mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-01-05 22:53:10 +00:00
541 lines
140 KiB
Plaintext
541 lines
140 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "3f485372-2531-4a49-8d15-5b26e9018a6a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from dataclasses import dataclass\n",
|
|
"from pyvis.network import Network\n",
|
|
"from pyvis.options import Layout\n",
|
|
"import networkx as nx"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "8ea18f7d-34a8-4de8-b18f-e93329825840",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@dataclass\n",
|
|
"class Block:\n",
|
|
" id: int\n",
|
|
" t: float\n",
|
|
" height: int\n",
|
|
" parent: int\n",
|
|
" leader: int"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "cabf7946-8382-4102-b730-d74ed42ceb38",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@dataclass\n",
|
|
"class NetworkParams:\n",
|
|
" mixnet_delay_mean: int # seconds\n",
|
|
" mixnet_delay_var: int\n",
|
|
" broadcast_delay_mean: int # second\n",
|
|
" pol_proof_time: int # seconds\n",
|
|
"\n",
|
|
" def sample_mixnet_delay(self):\n",
|
|
" scale = self.mixnet_delay_var / self.mixnet_delay_mean\n",
|
|
" shape = self.mixnet_delay_mean / scale\n",
|
|
" return np.random.gamma(shape=shape, scale=scale)\n",
|
|
" \n",
|
|
" def sample_broadcast_delay(self, blocks):\n",
|
|
" return np.random.exponential(self.broadcast_delay_mean, size=blocks.shape)\n",
|
|
"\n",
|
|
" def block_arrival_time(self, block_time):\n",
|
|
" return self.pol_proof_time + self.sample_mixnet_delay() + self.sample_broadcast_delay(block_time) + block_time"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "4e9df29f-fb4a-4dfb-a7b4-b8b4b0a6e6b7",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@dataclass\n",
|
|
"class Params:\n",
|
|
" CHAIN_HEIGHT: int\n",
|
|
" MEAN_BLOCK_TIME: int\n",
|
|
" honest_stake: np.array\n",
|
|
" adversary_control: float\n",
|
|
"\n",
|
|
" @property\n",
|
|
" def N(self):\n",
|
|
" return len(self.stake)\n",
|
|
"\n",
|
|
" @property\n",
|
|
" def stake(self):\n",
|
|
" if self.adversary_control:\n",
|
|
" adversary_stake = self.honest_stake.sum() / (1/self.adversary_control - 1)\n",
|
|
" return np.append(self.honest_stake, adversary_stake)\n",
|
|
" else:\n",
|
|
" return self.honest_stake\n",
|
|
" \n",
|
|
" @property\n",
|
|
" def relative_stake(self):\n",
|
|
" return self.stake / self.stake.sum()\n",
|
|
"\n",
|
|
" def block_delay_at_height(self):\n",
|
|
" return np.random.exponential(self.MEAN_BLOCK_TIME / self.relative_stake, size=(self.CHAIN_HEIGHT, self.N))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "ced60818-fab2-49c4-9247-9a31047d40d7",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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U93d3erq6jJ9HFaIBQAAQTwej3bt2qV77723v+3ChQt64okntH37dn322WeaMWOGfvKTn2jevHmSpMOHD2vWrFn6zW9+o5tvvnlI5+e2DgAAGNBDDz2kd999Vy+99JL+53/+R9/73vf053/+5/rggw8kSf/+7/+uG264Qa+99pomT56sSZMmqby8XJ9++qnpcxFOAADAFR09elQvvviidu7cqcLCQt1444167LHHdOedd+r555+XJH344Yf66KOPtHPnTr3wwguqqalRU1OTvvvd75o+H3NOAADAFf33f/+3DMPQlClTgtp7e3s1cuRISVJfX596e3v1wgsv9O/33HPPKS8vT++//76pWz2EEwAAcEV9fX1KSUlRU1OTUlJSgr77yle+IkkaM2aMUlNTgwLMtGnTJEnt7e2EEwAAYJ1bbrlFgUBAp06dUmFhYcR97rjjDn3++ec6evSobrzxRknS73//e0lSTk6OqfPxtA4AANDZs2d15MgRSX8KIxs3blRRUZGysrI0ceJE/eVf/qXeffddPfvss7rlllvU1dWlN998UzNnztSiRYvU19enOXPm6Ctf+Yo2bdqkvr4+eb1eZWRkaO/evaZqIZwAAAC9/fbbKioqCmsvKytTTU2NLl68qKeeekovvPCCPv74Y40cOVIFBQVav369Zs6cKUk6ceKE/uZv/kZ79+7Vtddeq5KSEj377LPKysoyVQvhBAAAOAqPEgMAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEchnAAAAEf5/3kbMqEG+rNjAAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"params = Params(\n",
|
|
" CHAIN_HEIGHT=1000,\n",
|
|
" MEAN_BLOCK_TIME=20,\n",
|
|
" honest_stake = np.random.pareto(10, size=100),\n",
|
|
" adversary_control=None,\n",
|
|
")\n",
|
|
"\n",
|
|
"_ = plt.hist(params.block_delay_at_height(), stacked=True, bins=100)\n",
|
|
"_ = plt.yscale(\"log\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "48c54c25-c7b4-47f9-a00a-5f10997cf185",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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4uLi1KJFC50+fVpPPPFEsQfBlVeTJk3k4+OjlJSUEtd7eXnd0H59fHx05coVnT171qawce0AoXHjxnJyclJcXFypV1w1b9681PdZtWqVhg8frsTERJv2H3/8UY0aNbJpu++++xQeHq6FCxeqQYMG2rdvn1atWlXBngEAAKAuy8rK0i233GJ9XdI577V8fHy0a9cuGYZhU9jIzs7WlStXrM+WaNq0qQoLC5WVlVVi0eDXIiMj9dBDD2n06NGSpMWLF6tevfJdM1vSj/ZX267tx7WFmKvrMzMzi+3jhx9+sPbFYrHogw8+0IwZMzRt2jRrzNVnQFy7z7Jyuqpp06aSpFOnTikoKKjEvh04cEBffvmlkpOTNWLECGv71Qec/1qTJk20YMECLViwQCdOnND69es1bdo0ZWdnlzo+Kq+rx6m0foWEhNjk4e7urr///e8l7uvqMS3JqlWr1Lx5c73zzjs2f6trH0AvSWaz2VrEmTJlipYvX67Y2Nhi4yYAKC9magAAyu3JJ5/UiRMn9P7772vZsmVav3695s+ff0P7io6O1tmzZ1VYWKiOHTsWW379ADs3N7disx9K07NnT0nS6tWrbdqvfdifh4eHevbsqS+++EJt27YtMYeyBogmk6nYA8s3btyo77//vsT4iRMnauPGjZo+fbr8/Pz00EMPlas/AAAAgFT8/PYf//iHrly5oh49epS6Ta9evXThwgX961//sml/6623rOslWW9Pu3jx4nLlMmLECK1du9b6QOjCwsJybXfw4EF9+eWXNm1r1qyRl5fXdWcxR0ZGyt3dvdjFQadOndKnn35q7YvJZJJhGMXO1d98881iefbs2VOffPKJTp8+bW0rLCzUO++8YxMXFRUlJyenMo/P1R/2r33fJUuWlNmvZs2a6emnn1afPn1sbsFVkTHQr3Xu3Fn169cv9nlJS0srdsvh6Ohofffdd/Lx8SlxPPTrAsi1TCaTXF1dbQoaWVlZpV70NnHiRP3444968MEHde7cOW7FC+CmMFMDAFAub775platWqXly5erTZs2atOmjZ5++mk9++yz6tq1q+65554K7e+RRx7R6tWrNWDAAE2aNEn33HOPXFxcdOrUKW3ZskX333+/hgwZIkmKiIjQ2rVr9c477+i2225T/fr1FRERUeJ+o6KidO+992rq1Km6ePGiOnbsqP/85z9auXJlsdi//OUv6tatm37zm9/od7/7nUJCQnT+/Hl9++232rBhgz799NNS84+OjlZycrJatmyptm3bKj09Xa+88kqpU9J/+9vfavr06frss8/0hz/8Qa6urhU6XgAAAKjb3n//fTk7O6tPnz46ePCgXnjhBbVr104xMTGlbjN8+HD97W9/04gRI3Ts2DFFRERo+/btSkxM1IABA9S7d29J0m9+8xvFxcVp9uzZOn36tKKjo+Xm5qYvvvhCHh4emjBhQrF9P/jgg/Lw8NCDDz6oS5cu6e23377uOW5gYKAGDx6smTNnKiAgQKtWrVJqaqpefvlleXh4lLlto0aN9MILL+i5557T8OHD9eijj+rs2bOaNWuW6tevrxkzZkiSGjZsqHvvvVevvPKKmjRpopCQEG3btk3Lli0rNjPgD3/4g9avX6/77rtPf/zjH+Xh4aG//e1vunjxok1cSEiInnvuOb344ou6dOmSHn30UZnNZn399df68ccfNWvWLLVs2VK33367pk2bJsMw5O3trQ0bNlhvQXuVxWJRz549FRsbq5YtW8rLy0t79uxRSkqKhg4dao2LiIjQ+++/r8WLF6tDhw6qV6+eOnbsWOYxkn6ZkT5lyhTNnj1bTzzxhB566CGdPHlSM2fOLHb7qfj4eL333nu699579cwzz6ht27YqKirSiRMntGnTJiUkJKhTp04lvk90dLTef/99jR8/Xg8++KBOnjypF198UQEBATpy5Eix+BYtWqhfv3766KOP1K1bt2LPVgGACrHrY8oBAFVixowZhiTjzJkzNu0jRowwPD09i8V3797daNOmjfX10aNHDUnG8uXLDcMwjK+++spwd3c3RowYYbPd5cuXjQ4dOhghISFGTk5Ome9xNadfKygoMP785z8b7dq1M+rXr280aNDAaNmypTFu3DjjyJEj1rhjx44ZUVFRhpeXlyHJCA4OLrP/586dM0aNGmU0atTI8PDwMPr06WP897//NSQZM2bMsIk9evSoMWrUKOOWW24xXFxcjKZNmxpdunQxZs+eXerxMAzDyMnJMUaPHm34+voaHh4eRrdu3YzPP//c6N69u9G9e/cS8xo5cqTh7OxsnDp1qsz8AQAAgKuunkenp6cbgwYNMho0aGB4eXkZjz76qHH69Gmb2JLORc+ePWs8+eSTRkBAgOHs7GwEBwcb06dPNy5fvmwTV1hYaMyfP98IDw83XF1dDbPZbERGRhobNmywxgQHBxsDBw602W7Lli1GgwYNjH79+hk///xzqf24uu0///lPo02bNoarq6sREhJizJs3r9j+JBnvvvtuift58803jbZt21pzvP/++42DBw/axJw6dcoYNmyY0bhxY8PLy8vo16+fceDAASM4OLjYmOY///mP0blzZ8PNzc3w9/c3fv/73xtvvPGGIck4evSoTexbb71l3H333daxS/v27W3GCF9//bXRp08fw8vLy2jcuLHx0EMPGSdOnLAZh1y+fNl48sknjbZt2xoNGzY03N3djbCwMGPGjBnGxYsXrfv66aefjAcffNBo1KiRYTKZio2lylJUVGQkJSUZQUFBhqurq9G2bVtjw4YNJX4+Lly4YPzhD38wwsLCrMc0IiLCeOaZZ4ysrCxrXEnHbs6cOUZISIjh5uZmtGrVyli6dGmJ476rkpOTDUnG2rVry90XACiJyTAMwy7VFAAA6pD8/HyFhISoW7du+sc//mHvdAAAAACgWg0bNkw7d+7UsWPH5OLiYu90ADgwbj8FAEAVOnPmjA4fPqzly5fr9OnTNg8rBAAAAIDaLC8vT/v27dPu3bu1bt06zZs3j4IGgJtGUQMAgCq0ceNGPf744woICNCiRYuu+wBEAAAAAChJYWGhyrrhislkkpOTUzVmdH2ZmZnq0qWLGjZsqHHjxpX4fBYAqChuPwUAAAAAAADUcD169NC2bdtKXR8cHKxjx45VX0IAYCcUNQAAAAAAAIAa7vDhwzp//nyp693c3BQREVGNGQGAfVDUAAAAAAAAAAAADqGevRMAAAAAgBvx2WefadCgQQoMDJTJZNK//vUv67qCggI9++yzioiIkKenpwIDAzV8+HD98MMPNvvIy8vThAkT1KRJE3l6emrw4ME6deqUTUxOTo7i4uJkNptlNpsVFxenc+fO2cScOHFCgwYNkqenp5o0aaKJEycqPz+/qroOAAAA1Fk8KLycioqK9MMPP8jLy0smk8ne6QAAAADVyjAMnT9/XoGBgapXr2ZcG3Xx4kW1a9dOjz/+uIYNG2az7ueff9a+ffv0wgsvqF27dsrJyVF8fLwGDx6svXv3WuPi4+O1YcMGrV27Vj4+PkpISFB0dLTS09OtD1uNjY3VqVOnlJKSIkkaO3as4uLitGHDBkm/PLh1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qms8sX79evXt21cPPfSQtm3bpltuuUXjx4/XmDFjJElHjx5VVlaWoqKirNu4ubmpe/fuSktL07hx45Senq6CggKbmMDAQIWHhystLU19+/bVjh07ZDabrQUNSercubPMZrPS0tJKLWrk5eUpLy/P+jo3N7eyDwEAAABQ61S4qPHWW2+VuX748OE3nAwAAACA2q06xxP/+9//tHjxYk2ePFnPPfecdu/erYkTJ8rNzU3Dhw9XVlaWJMnPz89mOz8/Px0/flySlJWVJVdXVzVu3LhYzNXts7KySrxtlq+vrzWmJElJSZo1a9ZN9REAAACoaypc1Jg0aZLN64KCAv38889ydXWVh4cHRQ0AAAAAparO8URRUZE6duyoxMRESVL79u118OBBLV682OZ9TCaTzXaGYRRru9a1MSXFX28/06dP1+TJk62vc3NzFRQUVHanAAAAgDquXkU3yMnJsVkuXLigw4cPq1u3bnr77berIkcAAAAAtUR1jicCAgLUunVrm7ZWrVrpxIkTkiR/f39JKjabIjs72zp7w9/fX/n5+crJySkz5vTp08Xe/8yZM8Vmgfyam5ubGjZsaLMAAAAAKFuFixolCQ0N1Zw5c4pddQUAAAAA11NV44muXbvq8OHDNm3ffPONgoODJUnNmzeXv7+/UlNTrevz8/O1bds2denSRZLUoUMHubi42MRkZmbqwIED1pjIyEhZLBbt3r3bGrNr1y5ZLBZrDAAAAIDKcUMPCi+Jk5OTfvjhh8raHQAAAIA6pCrGE88884y6dOmixMRExcTEaPfu3XrjjTf0xhtvSPrlllHx8fFKTExUaGioQkNDlZiYKA8PD8XGxkqSzGazRo8erYSEBPn4+Mjb21tTpkxRRESEevfuLemX2R/9+vXTmDFjtGTJEknS2LFjFR0dXepDwgEAAADcmAoXNdavX2/z2jAMZWZmauHCheratWulJQYAAACg9qnO8cTdd9+tdevWafr06frTn/6k5s2ba8GCBXrsscesMVOnTtWlS5c0fvx45eTkqFOnTtq0aZO8vLysMfPnz5ezs7NiYmJ06dIl9erVS8nJyXJycrLGrF69WhMnTlRUVJQkafDgwVq4cGGl9gcAAACAZDIMw6jIBvXq2d6xymQyqWnTprrvvvv06quvKiAgoFITrClyc3NlNptlsVi41y1qhZBpG+2dAuq4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zJhhtGvXrtzxU6dONVq2bGnTNm7cOKNz586VnFntNmnSJOP22283ioqKSly/ZcsWQ5KRk5NTvYk5OEnGunXrrK+LiooMf39/Y86cOda2y5cvG2az2Xj99ddL3U9MTIzRr18/m7a+ffsajzzySKXn7IiuPc4l2b17tyHJOH78eKkxy5cvN8xmc+UmV4uUdJxHjBhh3H///RXaD5/n6yvPZ/r+++837rvvvjJj+EyXLTs725BkbNu2zTAMvqOBG3XPPfcYTz75pE1by5YtjWnTptkpI5Tl2u8+1Bznz583QkNDjdTUVKN79+7GpEmT7J0S/s+zzz5rdOvWzd5poAwDBw40Ro0aZdM2dOhQ47e//a2dMsKvVdZvI6g6lfW7iqNgpgaqxJEjRxQYGKjmzZvrkUce0f/+979SY3fs2KGoqCibtr59+2rv3r0qKCio6lRrhfz8fK1atUqjRo2SyWQqM7Z9+/YKCAhQr169tGXLlmrKsPY4evSosrKybD6zbm5u6t69u9LS0krdrrTPeVnbwJbFYpHJZLru1VQXLlxQcHCwbr31VkVHR+uLL76ongQd2NatW+Xr66sWLVpozJgxys7OLjOez/PNO336tDZu3KjRo0dfN5bPdOksFoskydvbWxLf0cCNyM/PV3p6erF/A1FRUfwbqKGu/e5DzfHUU09p4MCB6t27t71TwTXWr1+vjh076qGHHpKvr6/at2+vpUuX2jst/Eq3bt30ySef6JtvvpEkffnll9q+fbsGDBhg58xQkhs974Z9lfd3FUdAUQOVrlOnTnrrrbf08ccfa+nSpcrKylKXLl109uzZEuOzsrLk5+dn0+bn56crV67oxx9/rI6UHd6//vUvnTt3TiNHjiw1JiAgQG+88Ybee+89vf/++woLC1OvXr302WefVV+itUBWVpYklfiZvbqutO0qug3+v8uXL2vatGmKjY1Vw4YNS41r2bKlkpOTtX79er399tuqX7++unbtqiNHjlRjto6lf//+Wr16tT799FO9+uqr2rNnj+677z7l5eWVug2f55u3YsUKeXl5aejQoWXG8ZkunWEYmjx5srp166bw8HBJfEcDN+LHH39UYWEh/wYcREnffagZ1q5dq3379ikpKcneqaAE//vf/7R48WKFhobq448/1pNPPqmJEyfqrbfesndq+D/PPvusHn30UbVs2VIuLi5q37694uPj9eijj9o7NZTgRs+7YT/l/V3FUTjbOwHUPv3797f+d0REhCIjI3X77bdrxYoVmjx5conbXDu7wDCMEttRsmXLlql///4KDAwsNSYsLExhYWHW15GRkTp58qT+/Oc/6957762ONGuVkj6z1/u83sg2+OXhVo888oiKioq0aNGiMmM7d+5s85Drrl276q677tJrr72mv/71r1WdqkN6+OGHrf8dHh6ujh07Kjg4WBs3bizzB3c+zzfn73//ux577LHrPhuDz3Tpnn76aX311Vfavn17sXV8RwMVx78Bx1DWdx/s5+TJk5o0aZI2bdpUZ597VdMVFRWpY8eOSkxMlPTLHQwOHjyoxYsXa/jw4XbODtIvz3datWqV1qxZozZt2igjI0Px8fEKDAzUiBEj7J0eSsH5g2OoyO8qjoKZGqhynp6eioiIKPWqUn9//2JV3OzsbDk7O8vHx6c6UnRox48f1+bNm/XEE09UeNvOnTtztW8F+fv7S1KJn9lrr1C4druKboNf/scbExOjo0ePKjU1tcJXE9SrV0933303n/MKCAgIUHBwcJnHjM/zzfn88891+PDhG/re5jP9iwkTJmj9+vXasmWLbr31Vms739FAxTVp0kROTk78G3AApX33wf7S09OVnZ2tDh06yNnZWc7Oztq2bZv++te/ytnZWYWFhfZOsc4LCAhQ69atbdpatWqlEydO2CkjXOv3v/+9pk2bpkceeUQRERGKi4vTM888w+ynGupGz7tR/W72d5WaiqIGqlxeXp4OHTqkgICAEtdHRkYqNTXVpm3Tpk3q2LGjXFxcqiNFh7Z8+XL5+vpq4MCBFd72iy++KPXvgpI1b95c/v7+Np/Z/Px8bdu2TV26dCl1u9I+52VtU9dd/R/vkSNHtHnz5hsqchqGoYyMDD7nFXD27FmdPHmyzGPG5/nmLFu2TB06dFC7du0qvG1d/0wbhqGnn35a77//vj799FM1b97cZj3f0UDFubq6qkOHDsX+DaSmpvJvoIa43ncf7K9Xr17av3+/MjIyrEvHjh312GOPKSMjQ05OTvZOsc7r2rWrDh8+bNP2zTffKDg42E4Z4Vo///yz6tWz/ZnSyclJRUVFdsoIZbnR825Ur8r4XaWm4vZTqHRTpkzRoEGD1KxZM2VnZ2v27NnKzc21ThecPn26vv/+e+u9K5988kktXLhQkydP1pgxY7Rjxw4tW7ZMb7/9tj274RCKioq0fPlyjRgxQs7Otv+crz3OCxYsUEhIiNq0aWN9sPh7772n9957zx6p12gXLlzQt99+a3199OhRZWRkyNvbW82aNVN8fLwSExMVGhqq0NBQJSYmysPDQ7GxsdZthg8frltuucV6VcmkSZN077336uWXX9b999+vf//739q8eXOdvnVAWcc5MDBQDz74oPbt26cPPvhAhYWF1itAvL295erqKqn4cZ41a5Y6d+6s0NBQ5ebm6q9//asyMjL0t7/9rfo7WEOUdZy9vb01c+ZMDRs2TAEBATp27Jiee+45NWnSREOGDLFuw+e5fK733SFJubm5evfdd/Xqq6+WuA8+02V76qmntGbNGv373/+Wl5eX9XvBbDbL3d1dJpOJ72jgBkyePFlxcXHq2LGjIiMj9cYbb+jEiRN68skn7Z0adP3vPtifl5dXsWeceHp6ysfHh2ef1BDPPPOMunTposTERMXExGj37t1644039MYbb9g7NfyfQYMG6aWXXlKzZs3Upk0bffHFF5o3b55GjRpl79TqrMr4bQRVqzJ+V3FYBlDJHn74YSMgIMBwcXExAgMDjaFDhxoHDx60rh8xYoTRvXt3m222bt1qtG/f3nB1dTVCQkKMxYsXV3PWjunjjz82JBmHDx8utu7a4/zyyy8bt99+u1G/fn2jcePGRrdu3YyNGzdWY7aOY8uWLYakYsuIESMMwzCMoqIiY8aMGYa/v7/h5uZm3Hvvvcb+/ftt9tG9e3dr/FXvvvuuERYWZri4uBgtW7Y03nvvvWrqUc1U1nE+evRoieskGVu2bLHu49rjHB8fbzRr1sxwdXU1mjZtakRFRRlpaWnV37kapKzj/PPPPxtRUVFG06ZNDRcXF6NZs2bGiBEjjBMnTtjsg89z+Vzvu8MwDGPJkiWGu7u7ce7cuRL3wWe6bKV9Lyxfvtwaw3c0cGP+9re/GcHBwYarq6tx1113Gdu2bbN3Svg/5fnuQ83TvXt3Y9KkSfZOA7+yYcMGIzw83HBzczNatmxpvPHGG/ZOCb+Sm5trTJo0yWjWrJlRv35947bbbjOef/55Iy8vz96p1VmV8dsIqlZl/K7iqEyG8X9PZAYAAAAAAAAAAKjBeKYGAAAAAAAAAABwCBQ1AAAAAAAAAACAQ6CoAQAAAAAAAAAAHAJFDQAAAAAAAAAA4BAoagAAAAAAAAAAAIdAUQMAAAAAAAAAADgEihoAAAAAAAAAAMAhUNQAgDqiR48eio+PL3d8cnKyGjVqVGX5/NoLL7ygsWPHVst7VZWtW7fKZDLp3Llz143dv3+/br31Vl28eLHqEwMAAACqCWOOqsWYAwB+QVEDAGBXp0+f1l/+8hc999xz9k6l2kREROiee+7R/Pnz7Z0KAAAAUOsx5gCA2oWiBgDArpYtW6bIyEiFhITYO5Vq9fjjj2vx4sUqLCy0dyoAAABArcaYgzEHgNqFogYA1EIXL17U8OHD1aBBAwUEBOjVV18tFpOfn6+pU6fqlltukaenpzp16qStW7eWus/vvvtO999/v/z8/NSgQQPdfffd2rx5s3X9n/70J0VERBTbrkOHDvrjH/9Y6n7Xrl2rwYMH27T985//VEREhNzd3eXj46PevXvbTJtevny5WrVqpfr166tly5ZatGiRzfanTp3SI488Im9vb3l6eqpjx47atWuXdf3ixYt1++23y9XVVWFhYVq5cqXN9iaTSW+++aaGDBkiDw8PhYaGav369TYxH374oVq0aCF3d3f17NlTx44ds1l//PhxDRo0SI0bN5anp6fatGmjDz/80Lq+b9++Onv2rLZt21bqsQEAAABqKsYcjDkAwF4oagBALfT73/9eW7Zs0bp167Rp0yZt3bpV6enpNjGPP/64/vOf/2jt2rX66quv9NBDD6lfv346cuRIifu8cOGCBgwYoM2bN+uLL75Q3759NWjQIJ04cUKSNGrUKH399dfas2ePdZuvvvpKX3zxhUaOHFniPnNycnTgwAF17NjR2paZmalHH31Uo0aN0qFDh7R161YNHTpUhmFIkpYuXarnn39eL730kg4dOqTExES98MILWrFihTXP7t2764cfftD69ev15ZdfaurUqSoqKpIkrVu3TpMmTVJCQoIOHDigcePG6fHHH9eWLVtscps1a5ZiYmL01VdfacCAAXrsscf0008/SZJOnjypoUOHasCAAcrIyNATTzyhadOm2Wz/1FNPKS8vT5999pn279+vl19+WQ0aNLCud3V1Vbt27fT555+X/EcEAAAAajDGHIw5AMBuDABArXL+/HnD1dXVWLt2rbXt7Nmzhru7uzFp0iTDMAzj22+/NUwmk/H999/bbNurVy9j+vTphmEYxvLlyw2z2Vzme7Vu3dp47bXXrK/79+9v/O53v7O+jo+PN3r06FHq9l988YUhyThx4oS1LT093ZBkHDt2rMRtgoKCjDVr1ti0vfjii0ZkZKRhGIaxZMkSw8vLyzh79myJ23fp0sUYM2aMTdtDDz1kDBgwwPpakvGHP/zB+vrChQuGyWQyPvroI8MwDGP69OlGq1atjKKiImvMs88+a0gycnJyDMMwjIiICGPmzJml9t0wDGPIkCHGyJEjy4wBAAAAahrGHIw5AMCemKkBALXMd999p/z8fEVGRlrbvL29FRYWZn29b98+GYahFi1aqEGDBtZl27Zt+u6770rc78WLFzV16lS1bt1ajRo1UoMGDfTf//7XetWUJI0ZM0Zvv/22Ll++rIKCAq1evVqjRo0qNddLly5JkurXr29ta9eunXr16qWIiAg99NBDWrp0qXJyciRJZ86c0cmTJzV69GibvGfPnm3NOyMjQ+3bt5e3t3eJ73no0CF17drVpq1r1646dOiQTVvbtm2t/+3p6SkvLy9lZ2db99G5c2eZTCZrzK+PtyRNnDhRs2fPVteuXTVjxgx99dVXxXJxd3fXzz//XOrxAQAAAGoixhyMOQDAnpztnQAAoHIZ/zdluixFRUVycnJSenq6nJycbNb9erryr/3+97/Xxx9/rD//+c+644475O7urgcffFD5+fnWmEGDBsnNzU3r1q2Tm5ub8vLyNGzYsFLzaNKkiaRfpoQ3bdpUkuTk5KTU1FSlpaVp06ZNeu211/T8889r165d8vDwkPTLdPBOnTrZ7OtqP9zd3a/b/18PDKRfjtm1bS4uLsW2uTqdvDzH+IknnlDfvn21ceNGbdq0SUlJSXr11Vc1YcIEa8xPP/2k22+//br7AgAAAGoSxhyMOQDAnpipAQC1zB133CEXFxft3LnT2paTk6NvvvnG+rp9+/YqLCxUdna27rjjDpvF39+/xP1+/vnnGjlypIYMGaKIiAj5+/sXe1Cds7OzRowYoeXLl2v58uV65JFHrIOCktx+++1q2LChvv76a5t2k8mkrl27atasWfriiy/k6uqqdevWyc/PT7fccov+97//Fcu7efPmkn652ikjI8N6L9prtWrVStu3b7dpS0tLU6tWrUrN81qtW7e2Ob6Sir2WpKCgID355JN6//33lZCQoKVLl9qsP3DggNq3b1/u9/1/7d15vJVVoT/+z5bhMAjIfEARKEEvQqZZDqmoIAqooZampmjUrRyK0AocruA1UEyycuybgmYOdUMbMBUE9ZppiLOWmYFiQjggiAPj8/vDH+d2ZD5yOGx4v1+v/Xq5n2c9azjnPG72/uy1FgAAbA685/CeA6AumakBsIXZdtttM2TIkHznO99J69at0759+5x77rnZZpv/y7G7d++eE088MSeffHIuu+yy7L777nn99dczderU9OrVKwMGDFil3p122ikTJ07MEUcckVKplPPPP7/qW0T/7itf+UrVP9b/+Mc/rrWv22yzTfr27ZsHH3wwgwYNSpI88sgjuffee9OvX7+0a9cujzzySF577bWqOkeOHJlvfvObad68efr375/Fixfn0Ucfzfz58zNs2LAcf/zxGT16dAYNGpQxY8akQ4cOefzxx9OxY8fss88++c53vpNjjz02e+yxR/r06ZPf/e53mThxYqZMmbLeP+Ovf/3rueyyyzJs2LB87Wtfy4wZMzJhwoRqZYYOHZr+/fune/fumT9/fqZOnVrtTcysWbPyz3/+M3379l3vdgEAYHPgPYf3HAB1qu628wCgtrz99tvFl770paJJkyZF+/bti7Fjxxa9e/eu2rSvKIpiyZIlxX/9138VXbp0KRo0aFBUVlYWRx11VPHUU08VRbHqpn0zZ84sDjrooKJx48ZFp06diiuuuGKVOlfaf//9ix49eqxXX++6665i++23L5YvX14URVE899xzxaGHHlq0bdu2qKioKLp3715tY8CiKIpf/OIXxSc/+cmiYcOGRcuWLYsDDjigmDhxYtX5WbNmFcccc0zRvHnzokmTJsWee+5ZPPLII1Xnr7rqquJjH/tY0aBBg6J79+7FjTfeWK3+JMXtt99e7ViLFi2K8ePHVz3/3e9+V+y0005FRUVFsf/++xfXX399tU37zjjjjOLjH/94UVFRUbRt27Y46aSTitdff73q+tGjRxeHHnroev2MAABgc+M9h/ccAHWlVBTrsUgfAKynoiiyyy675Gtf+1qGDRu2XuX33nvvDB06NMcff/wm6GHdW7x4cbp165ZbbrlllQ0EAQCAtfOeY9285wC2ZPbUAGCjmTdvXsaNG5d//vOfOfXUU9frmlKplJ/+9KdZtmxZLfdu8/HSSy/l3HPP9eYCAAA2kPcc68d7DmBLZqYGABtNqVRKmzZt8qMf/SgnnHBCXXcHAADYwnjPAYBQAwAAAAAAKAuWnwIAAAAAAMqCUAMAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAAAAAAAoC0INAAAAAACgLAg1AAAAAACAsiDUAAAAAAAAyoJQAwAAAAAAKAtCDQAAAAAAoCwINQAAAAAAgLIg1AAAAAAAAMqCUAMAAAAAACgLQg0AAOrcyJEjUyqV8vrrr6+z7IEHHpgDDzyw1vrSpUuXHH744bVW/0dRKpUycuTIWqt/1qxZKZVKmTBhwkeua8KECSmVSpk1a9YGX3vnnXfW6jiT/xvrD37wg1ptZ3P37rvvZuTIkbnvvvvWq/zG/BvZEF26dMkpp5yywddt6PhW+slPfpJddtklFRUV6dq1a0aNGpWlS5ducPsAAGx8Qg0AACgTf/rTn/KVr3ylrrtR6+68886MGjWqrruxVXj33XczatSo9f7Qv0OHDvnTn/6UgQMH1m7HNpINHV+SfP/738+3vvWtHH300bn77rtz2mmnZfTo0Tn99NNrr6MAAKy3+nXdAQAA4IMPX5s0abLK8aIo8v7776dx48bZe++966Bn8H8qKiq26L/DN954IxdddFG++tWvZvTo0Uk+mB22dOnSnHfeeRk6dGh69OhRx70EANi6makBAMBmY/bs2Tn66KPTvHnztGjRIl/60pfy2muvrfO6N998M6eddlq23377NGzYMB/72Mdy7rnnZvHixdXKrVixIj/5yU/yyU9+Mo0bN852222XvffeO7/97W/XWv9VV12V+vXr54ILLlhrudtuuy39+vVLhw4d0rhx4/zHf/xHhg8fnnfeeadauVNOOSXbbrttnn766fTr1y/NmjVLnz59knywxNQZZ5yRa665Jv/xH/+RioqK3HDDDVXnVi7L9OSTT6ZUKuW6665bpR9/+MMfUiqVqsb197//Paeeemq6deuWJk2aZPvtt88RRxyRp59+eq3jWZMVK1bkoosuys4771z1c/zEJz6RH/3oR+u89vrrr89uu+2WRo0apVWrVjnqqKPyl7/8pdrP5sorr6wa78rHmpaxuvLKK7PNNttk3rx5Vccuu+yylEqlat+sX7FiRVq2bJmzzjprlTrGjRuXrl27Ztttt80+++yThx9+eJUyjz76aI488si0atUqjRo1yu67755f/vKX1cqsXHJr2rRp+cY3vpE2bdqkdevWOfroo/Pqq6+u82fzj3/8I1/84hfTsWPHVFRUpH379unTp0+eeOKJauVuu+227LPPPmnatGm23XbbHHrooXn88cerlVn5N/b3v/89AwYMyLbbbptOnTrlrLPOqrovZs2albZt2yZJRo0aVfWzXtsyT6tbfmrl8nHPPvtsjj/++LRo0SLt27fPl7/85SxYsGCd43788cdz+OGHp127dqmoqEjHjh0zcODAvPLKK2u97uWXX86XvvSlquv+4z/+I5dddllWrFhR4/Hdddddef/993PqqadWO37qqaemKIrccccd6xwPAAC1y0wNAAA2G0cddVSOPfbYfP3rX8+zzz6b888/P88991weeeSRNGjQYLXXvP/++znooIPy4osvZtSoUfnEJz6R//3f/82YMWPyxBNPZNKkSVVlTznllNx0000ZMmRILrzwwjRs2DCPPfbYGj8wL4oi3/nOd/LjH/84P/vZz9a5pv8LL7yQAQMGZOjQoWnatGn++te/5pJLLsmf//znTJ06tVrZJUuW5Mgjj8zXvva1DB8+PMuWLas6d8cdd+R///d/81//9V+prKxMu3btVmlrt912y+67757x48dnyJAh1c5NmDAh7dq1y4ABA5Ikr776alq3bp2LL744bdu2zZtvvpkbbrghe+21Vx5//PHsvPPOax3Xh40dOzYjR47MeeedlwMOOCBLly7NX//617z11ltrvW7MmDE555xzcvzxx2fMmDF54403MnLkyOyzzz6ZPn16unXrlvPPPz/vvPNO/ud//id/+tOfqq7t0KHDauvs27dviqLIvffem+OPPz5JMmXKlDRu3DiTJ0+uKvfoo4/mrbfeSt++fatdf+WVV2aXXXbJ5ZdfniQ5//zzM2DAgMycOTMtWrRIkkybNi2HHXZY9tprr1xzzTVp0aJFbr311hx33HF59913V/m7+MpXvpKBAwfm5ptvzuzZs/Od73wnX/rSl1b5G/iwAQMGZPny5Rk7dmx23HHHvP7663nooYeq/VxHjx6d8847L6eeemrOO++8LFmyJJdeemn233///PnPf642i2Dp0qU58sgjM2TIkJx11ll54IEH8t///d9p0aJF/uu//isdOnTIXXfdlcMOOyxDhgypWtpsZRCwoY455pgcd9xxGTJkSJ5++umMGDEiyQdB1pq88847OeSQQ9K1a9dceeWVad++febOnZtp06bl7bffXuN1r732Wvbdd98sWbIk//3f/50uXbrk97//fc4+++y8+OKLueqqq2o0vmeeeSZJ0qtXr2rHO3TokDZt2lSdBwCgDhUAAFDHLrjggiJJ8e1vf7va8V/84hdFkuKmm26qOta7d++id+/eVc+vueaaIknxy1/+stq1l1xySZGkuOeee4qiKIoHHnigSFKce+65a+1L586di4EDBxbvvvtuccwxxxQtWrQopkyZssFjWrFiRbF06dLi/vvvL5IUTz75ZNW5wYMHF0mK66+/fpXrkhQtWrQo3nzzzdWeu+CCC6qe//jHPy6SFM8//3zVsTfffLOoqKgozjrrrDX2bdmyZcWSJUuKbt26VfuZz5w5s0hSjB8/fq1jO/zww4tPfvKTay0zfvz4Ikkxc+bMoiiKYv78+UXjxo2LAQMGVCv38ssvFxUVFcUJJ5xQdez0008vNuStyg477FB8+ctfLoqiKBYvXlw0bdq0+N73vlckKV566aWiKIri+9//ftGgQYNi0aJF1cbaq1evYtmyZVV1/fnPfy6SFLfcckvVsV122aXYfffdi6VLl67yc+jQoUOxfPnyamM+7bTTqpUbO3ZskaSYM2fOGsfw+uuvF0mKyy+/fI1lXn755aJ+/frFmWeeWe3422+/XVRWVhbHHnts1bGVf2Mfvi8GDBhQ7LzzzlXPX3vttVX+rtZmdX8jK+/fsWPHVit72mmnFY0aNSpWrFixxvoeffTRIklxxx13rLXdzp07F4MHD656Pnz48CJJ8cgjj1Qr941vfKMolUpV98SGju+rX/1qUVFRsdpz3bt3L/r167de9QAAUHssPwUAwGbjxBNPrPb82GOPTf369TNt2rQ1XjN16tQ0bdo0n//856sdX/nt+XvvvTfJB0syJVmvzX7feOONHHzwwfnzn/+cBx98sGppqHX5xz/+kRNOOCGVlZWpV69eGjRokN69eydJtSWWVjrmmGNWW8/BBx+cli1brrO9E088MRUVFdWWArrllluyePHiasvnLFu2LKNHj06PHj3SsGHD1K9fPw0bNswLL7yw2n6ty2c+85k8+eSTOe2003L33Xdn4cKF67zmT3/6U957771VZjV06tQpBx98cNXvqSb69OmTKVOmJEkeeuihvPvuuxk2bFjatGlTNVtjypQpVUs2/buBAwemXr16Vc8/8YlPJEleeumlJB8s3fXXv/616m9z2bJlVY8BAwZkzpw5ef7556vVeeSRR1Z7/uE6V6dVq1b5+Mc/nksvvTTjxo3L448/XrWM0kp33313li1blpNPPrlaPxo1apTevXuvshl2qVTKEUccsUpf1taPj2J1437//ferLQ32YTvttFNatmyZ733ve7nmmmvy3HPPrVdbU6dOTY8ePfKZz3ym2vFTTjklRVGsc1bM2pRKpRqdAwBg0xBqAACw2aisrKz2vH79+mndunXeeOONNV7zxhtvpLKycpUPG9u1a5f69etXXfvaa6+lXr16q7SxOn/729/yyCOPpH///unZs+d69X3RokXZf//988gjj+Siiy7Kfffdl+nTp2fixIlJkvfee69a+SZNmqR58+arrWtNSy19WKtWrXLkkUfmxhtvzPLly5N8sPTUZz7zmey6665V5YYNG5bzzz8/gwYNyu9+97s88sgjmT59enbbbbdV+rU+RowYkR/84Ad5+OGH079//7Ru3Tp9+vTJo48+usZrVv4eVje2jh07rvV3vC59+/bNyy+/nBdeeCFTpkzJ7rvvnnbt2uXggw/OlClT8t577+Whhx5aZempJGndunW15xUVFUn+7/f1r3/9K0ly9tlnp0GDBtUep512WpLk9ddf36A6V6dUKuXee+/NoYcemrFjx2aPPfZI27Zt881vfrNqGaaVffn0pz+9Sl9uu+22VfrRpEmTNGrUaJW+vP/++2vsx0dRk3G3aNEi999/fz75yU/mnHPOya677pqOHTvmggsuyNKlS9d43RtvvLHGv6WV52uidevWef/99/Puu++ucu7NN99Mq1atalQvAAAbjz01AADYbMydOzfbb7991fNly5bljTfeWOXD0n/XunXrPPLIIymKolqwMW/evCxbtixt2rRJ8sE6+suXL8/cuXPXGRrss88++cIXvlC1V8XVV1+dbbZZ+/eBpk6dmldffTX33Xdf1eyMJGvcZ2JjfRv81FNPza9+9atMnjw5O+64Y6ZPn56rr766WpmbbropJ598ckaPHl3t+Ouvv57ttttuvdtaqX79+hk2bFiGDRuWt956K1OmTMk555yTQw89NLNnz06TJk1WuWbl73DOnDmrnHv11Verfk81sXImzZQpUzJ58uQccsghVcfPO++8PPDAA1m8ePFqQ411WdmvESNG5Oijj15tmQ3dk2RNOnfuXLXx+9/+9rf88pe/zMiRI7NkyZJcc801VX35n//5n3Tu3HmjtLk56NWrV2699dYURZGnnnoqEyZMyIUXXpjGjRtn+PDhq72mdevWa/xbSlLjv6eVe2k8/fTT2WuvvaqOz507N6+//vp6h5wAANQeMzUAANhs/OIXv6j2/Je//GWWLVuWAw88cI3X9OnTJ4sWLcodd9xR7fiNN95YdT5J+vfvnySrfOC/JoMHD86tt96a8ePH5+STT66aCbEmK4OIld9OX+naa69dr/Zqql+/ftl+++0zfvz4jB8/Po0aNaraMPvf+/bhfk2aNCn//Oc/P3L72223XT7/+c/n9NNPz5tvvrnGTdf32WefNG7cODfddFO146+88kqmTp1abYmv9fmG/7/r0KFDevTokV//+teZMWNGVahxyCGH5LXXXsu4cePSvHnzfPrTn97g8e28887p1q1bnnzyyey5556rfTRr1myD612X7t2757zzzkuvXr3y2GOPJUkOPfTQ1K9fPy+++OIa+7KhNvRnXZtKpVJ22223/PCHP8x2221XNe7V6dOnT5577rlVytx4440plUo56KCDkmz4+A477LA0atSo2pJuyQczoEqlUgYNGrT+AwIAoFaYqQEAwGZj4sSJqV+/fg455JA8++yzOf/887Pbbrvl2GOPXeM1J598cq688soMHjw4s2bNSq9evfLggw9m9OjRGTBgQNW38/fff/+cdNJJueiii/Kvf/0rhx9+eCoqKvL444+nSZMmOfPMM1ep+/Of/3yaNGmSz3/+83nvvfdyyy23pGHDhqvtx7777puWLVvm61//ei644II0aNAgv/jFL/Lkk09unB/OGtSrVy8nn3xy1Qf3Rx99dFq0aFGtzOGHH54JEyZkl112ySc+8YnMmDEjl156aXbYYYcatXnEEUekZ8+e2XPPPdO2bdu89NJLufzyy9O5c+d069Zttddst912Of/883POOefk5JNPzvHHH5833ngjo0aNSqNGjXLBBRdUlV35bflLLrkk/fv3T7169fKJT3xijT/75IMPuX/yk5+kcePG+exnP5sk6dq1a7p27Zp77rknRx55ZOrXr9nbn2uvvTb9+/fPoYcemlNOOSXbb7993nzzzfzlL3/JY489ll/96lc1qvffPfXUUznjjDPyhS98Id26dUvDhg0zderUPPXUU1WzFbp06ZILL7ww5557bv7xj3/ksMMOS8uWLfOvf/0rf/7zn9O0adOMGjVqg9pt1qxZOnfunN/85jfp06dPWrVqlTZt2qRLly4feUzr4/e//32uuuqqDBo0KB/72MdSFEUmTpyYt956qyqcWp1vf/vbufHGGzNw4MBceOGF6dy5cyZNmpSrrroq3/jGN9K9e/caja9Vq1Y577zzcv7556dVq1bp169fpk+fnpEjR+YrX/lKevToURs/BgAANoBQAwCAzcbEiRMzcuTIXH311VWbHF9++eVr/TC7UaNGmTZtWs4999xceumlee2117L99tvn7LPPrvZBefLBt6332GOPXHfddZkwYUIaN26cHj165Jxzzllj/QMGDMidd96ZI444Ip/73OcyceLENG7ceJVyrVu3zqRJk3LWWWflS1/6Upo2bZrPfe5zue2227LHHnvU/IeyHk499dSMGTMmr732WrUNwlf60Y9+lAYNGmTMmDFZtGhR9thjj0ycODHnnXdejdo76KCD8utf/zo/+9nPsnDhwlRWVuaQQw7J+eefnwYNGqzxuhEjRqRdu3b58Y9/nNtuuy2NGzfOgQcemNGjR1cLQ0444YT88Y9/zFVXXZULL7wwRVFk5syZa/2gvW/fvvnJT36S/fbbr9o+En379s3/+3//r0ZLT/37eP/85z/n+9//foYOHZr58+endevW6dGjx1oDtw1RWVmZj3/847nqqqsye/bslEqlfOxjH8tll11WLXAbMWJEevTokR/96EdVm8JXVlbm05/+dL7+9a/XqO3rrrsu3/nOd3LkkUdm8eLFGTx48CozFWpLt27dst1222Xs2LF59dVX07Bhw+y8886ZMGFCBg8evMbr2rZtm4ceeigjRozIiBEjsnDhwnzsYx/L2LFjM2zYsGplN3R85557bpo1a5Yrr7wyP/jBD1JZWZnhw4fn3HPP3VjDBgDgIygVRVHUdScAAAAAAADWxZ4aAAAAAABAWRBqAAAAAAAAZUGoAQAAAAAAlAWhBgAAAAAAUBaEGgAAAAAAQFkQagAAAAAAAGVBqAEAAAAAAJSF+nXdgXKxYsWKvPrqq2nWrFlKpVJddwcAAAAAALYYRVHk7bffTseOHbPNNmuejyHUWE+vvvpqOnXqVNfdAAAAAACALdbs2bOzww47rPG8UGM9NWvWLMkHP9DmzZvXcW8AAAAAAGDLsXDhwnTq1Knqs/g1EWqsp5VLTjVv3lyoAQAAAAAAtWBd2z/YKBwAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAAAAAAAoC0INAAAAAACgLAg1AAAAAACAsiDUAAAAAAAAyoJQAwAAAAAAKAtCDQAAAAAAoCwINQAAAAAAgLIg1AAAAAAAAMpC/bruAADAmnQZPmmDr5l18cBa6AkAAACwOTBTAwAAAAAAKAtCDQAAAAAAoCwINQAAAAAAgLIg1AAAAAAAAMqCjcIBAMpETTZOT2yeDgAAwJbDTA0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAAAAAAAoC0INAAAAAACgLAg1AAAAAACAsiDUAAAAAAAAyoJQAwAAAAAAKAubdahx9dVX5xOf+ESaN2+e5s2bZ5999skf/vCHqvNFUWTkyJHp2LFjGjdunAMPPDDPPvtstToWL16cM888M23atEnTpk1z5JFH5pVXXtnUQwEAAAAAAD6i+nXdgbXZYYcdcvHFF2ennXZKktxwww353Oc+l8cffzy77rprxo4dm3HjxmXChAnp3r17LrroohxyyCF5/vnn06xZsyTJ0KFD87vf/S633nprWrdunbPOOiuHH354ZsyYkXr16tXl8AAANltdhk+q0XWzLh64kXsCAAAA/2eznqlxxBFHZMCAAenevXu6d++e73//+9l2223z8MMPpyiKXH755Tn33HNz9NFHp2fPnrnhhhvy7rvv5uabb06SLFiwINddd10uu+yy9O3bN7vvvntuuummPP3005kyZUodjw4AAAAAANgQm3Wo8e+WL1+eW2+9Ne+880722WefzJw5M3Pnzk2/fv2qylRUVKR379556KGHkiQzZszI0qVLq5Xp2LFjevbsWVVmTRYvXpyFCxdWewAAAAAAAHVnsw81nn766Wy77bapqKjI17/+9dx+++3p0aNH5s6dmyRp3759tfLt27evOjd37tw0bNgwLVu2XGOZNRkzZkxatGhR9ejUqdNGHBUAAAAAALChNvtQY+edd84TTzyRhx9+ON/4xjcyePDgPPfcc1XnS6VStfJFUaxy7MPWp8yIESOyYMGCqsfs2bNrPggAAAAAAOAj2+xDjYYNG2annXbKnnvumTFjxmS33XbLj370o1RWVibJKjMu5s2bVzV7o7KyMkuWLMn8+fPXWGZNKioq0rx582oPAAAAAACg7tSv6w5sqKIosnjx4nTt2jWVlZWZPHlydt999yTJkiVLcv/99+eSSy5JknzqU59KgwYNMnny5Bx77LFJkjlz5uSZZ57J2LFj62wMAMCWo8vwSRt8zayLB9ZCTwAAAGDLt1mHGuecc0769++fTp065e23386tt96a++67L3fddVdKpVKGDh2a0aNHp1u3bunWrVtGjx6dJk2a5IQTTkiStGjRIkOGDMlZZ52V1q1bp1WrVjn77LPTq1ev9O3bt45HBwAAAAAAbIjNOtT417/+lZNOOilz5sxJixYt8olPfCJ33XVXDjnkkCTJd7/73bz33ns57bTTMn/+/Oy1116555570qxZs6o6fvjDH6Z+/fo59thj895776VPnz6ZMGFC6tWrV1fDAgA2QzWZcQEAAABsWqWiKIq67kQ5WLhwYVq0aJEFCxbYXwMANpFNubTTpgw1yqGPNWVpLQAAAGpifT+D3+w3CgcAAAAAAEiEGgAAAAAAQJkQagAAAAAAAGVBqAEAAAAAAJSF+nXdAQAAqOkm6DYmBwAA2LqYqQEAAAAAAJQFoQYAAAAAAFAWLD8FAGxRarqM0aZUDn0EAACAzZGZGgAAAAAAQFkQagAAAAAAAGVBqAEAAAAAAJQFoQYAAAAAAFAWhBoAAAAAAEBZqF/XHQAAtnxdhk+q6y4AAAAAWwAzNQAAAAAAgLIg1AAAAAAAAMqCUAMAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyUL+uOwAA1I0uwydt8DWzLh5YCz1hS1KTvysAAABYX2ZqAAAAAAAAZcFMDQAAtiqbejaJGU4AAAAbj5kaAAAAAABAWTBTAwBYb/ZLAAAAAOqSmRoAAAAAAEBZEGoAAAAAAABlQagBAAAAAACUBaEGAAAAAABQFoQaAAAAAABAWRBqAAAAAAAAZUGoAQAAAAAAlAWhBgAAAAAAUBaEGgAAAAAAQFkQagAAAAAAAGVBqAEAAAAAAJQFoQYAAAAAAFAWNutQY8yYMfn0pz+dZs2apV27dhk0aFCef/75amVOOeWUlEqlao+99967WpnFixfnzDPPTJs2bdK0adMceeSReeWVVzblUAAAAAAAgI9osw417r///px++ul5+OGHM3ny5Cxbtiz9+vXLO++8U63cYYcdljlz5lQ97rzzzmrnhw4dmttvvz233nprHnzwwSxatCiHH354li9fvimHAwAAAAAAfAT167oDa3PXXXdVez5+/Pi0a9cuM2bMyAEHHFB1vKKiIpWVlautY8GCBbnuuuvy85//PH379k2S3HTTTenUqVOmTJmSQw89tPYGAACbQJfhk+q6CwAAAACbxGY9U+PDFixYkCRp1apVteP33Xdf2rVrl+7du+erX/1q5s2bV3VuxowZWbp0afr161d1rGPHjunZs2ceeuihNba1ePHiLFy4sNoDAAAAAACoO5v1TI1/VxRFhg0blv322y89e/asOt6/f/984QtfSOfOnTNz5sycf/75OfjggzNjxoxUVFRk7ty5adiwYVq2bFmtvvbt22fu3LlrbG/MmDEZNWpUrY0HAICPzkwlAACArUvZhBpnnHFGnnrqqTz44IPVjh933HFV/92zZ8/sueee6dy5cyZNmpSjjz56jfUVRZFSqbTG8yNGjMiwYcOqni9cuDCdOnX6CCMAAAAAAAA+irJYfurMM8/Mb3/720ybNi077LDDWst26NAhnTt3zgsvvJAkqayszJIlSzJ//vxq5ebNm5f27duvsZ6Kioo0b9682gMAAAAAAKg7m3WoURRFzjjjjEycODFTp05N165d13nNG2+8kdmzZ6dDhw5Jkk996lNp0KBBJk+eXFVmzpw5eeaZZ7LvvvvWWt8BAAAAAICNa7Nefur000/PzTffnN/85jdp1qxZ1R4YLVq0SOPGjbNo0aKMHDkyxxxzTDp06JBZs2blnHPOSZs2bXLUUUdVlR0yZEjOOuustG7dOq1atcrZZ5+dXr16pW/fvnU5PAAAAAAAYANs1qHG1VdfnSQ58MADqx0fP358TjnllNSrVy9PP/10brzxxrz11lvp0KFDDjrooNx2221p1qxZVfkf/vCHqV+/fo499ti899576dOnTyZMmJB69eptyuEAAAAAAAAfQakoiqKuO1EOFi5cmBYtWmTBggX21wBgs9Jl+KS67gKwFrMuHljXXQAAANjsre9n8Jv1nhoAAAAAAAArCTUAAAAAAICyINQAAAAAAADKwma9UTgAbE3sjQFbpprc2/bhAAAAWD0zNQAAAAAAgLIg1AAAAAAAAMqCUAMAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAAAAAAAoC0INAAAAAACgLAg1AAAAAACAslC/rjsAAFuiLsMn1XUXAAAAALY4ZmoAAAAAAABlQagBAAAAAACUBaEGAAAAAABQFoQaAAAAAABAWRBqAAAAAAAAZUGoAQAAAAAAlAWhBgAAAAAAUBaEGgAAAAAAQFkQagAAAAAAAGVBqAEAAAAAAJQFoQYAAAAAAFAWhBoAAAAAAEBZEGoAAAAAAABlQagBAAAAAACUhfp13QEA2Jx1GT6prrsAAAAAwP/PTA0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAAAAAAAoC0INAAAAAACgLAg1AAAAAACAsrBZhxpjxozJpz/96TRr1izt2rXLoEGD8vzzz1crUxRFRo4cmY4dO6Zx48Y58MAD8+yzz1Yrs3jx4px55plp06ZNmjZtmiOPPDKvvPLKphwKAAAAAADwEW3Wocb999+f008/PQ8//HAmT56cZcuWpV+/fnnnnXeqyowdOzbjxo3LFVdckenTp6eysjKHHHJI3n777aoyQ4cOze23355bb701Dz74YBYtWpTDDz88y5cvr4thAQAAAAAANVAqiqLY2JXOnDkzXbt23djV5rXXXku7du1y//3354ADDkhRFOnYsWOGDh2a733ve0k+mJXRvn37XHLJJfna176WBQsWpG3btvn5z3+e4447Lkny6quvplOnTrnzzjtz6KGHrlfbCxcuTIsWLbJgwYI0b958o48NgM1Tl+GT6roLwFZo1sUD67oLAAAAm9T6fgZfKzM1dtpppxx00EG56aab8v7772+0ehcsWJAkadWqVZIPwpO5c+emX79+VWUqKirSu3fvPPTQQ0mSGTNmZOnSpdXKdOzYMT179qwqAwAAAAAAbP7q10alTz75ZK6//vqcddZZOeOMM3LcccdlyJAh+cxnPlPjOouiyLBhw7LffvulZ8+eSZK5c+cmSdq3b1+tbPv27fPSSy9VlWnYsGFatmy5SpmV16/O4sWLs3jx4qrnCxcurHHfAQBgU6jp7DIzQwAAgHJRK6FGz549M27cuIwdOza/+93vMmHChOy3337p1q1bhgwZkpNOOilt27bdoDrPOOOMPPXUU3nwwQdXOVcqlao9L4pilWMftq4yY8aMyahRozaojwBsviwjBQAAAFD+aiXUqKq8fv0cddRRGTBgQK666qqMGDEiZ599dkaMGJHjjjsul1xySTp06LDOes4888z89re/zQMPPJAddtih6nhlZWWSD2Zj/Hs98+bNq5q9UVlZmSVLlmT+/PnVZmvMmzcv++677xrbHDFiRIYNG1b1fOHChenUqdP6Dx4AAMpETYJfszsAAIC6UCt7aqz06KOP5rTTTkuHDh0ybty4nH322XnxxRczderU/POf/8znPve5tV5fFEXOOOOMTJw4MVOnTl1l8/GuXbumsrIykydPrjq2ZMmS3H///VWBxac+9ak0aNCgWpk5c+bkmWeeWWuoUVFRkebNm1d7AAAAAAAAdadWZmqMGzcu48ePz/PPP58BAwbkxhtvzIABA7LNNh9kKF27ds21116bXXbZZa31nH766bn55pvzm9/8Js2aNavaA6NFixZp3LhxSqVShg4dmtGjR6dbt27p1q1bRo8enSZNmuSEE06oKjtkyJCcddZZad26dVq1apWzzz47vXr1St++fWtj+ADUMktJAQAAAGydaiXUuPrqq/PlL385p556atUSUR+244475rrrrltnPUly4IEHVjs+fvz4nHLKKUmS7373u3nvvfdy2mmnZf78+dlrr71yzz33pFmzZlXlf/jDH6Z+/fo59thj895776VPnz6ZMGFC6tWrV/NBAgAAAAAAm1SpKIqirjtRDhYuXJgWLVpkwYIFlqICqGNmagBbupruV7Ep//9oTw0AAGBjWt/P4GtlT43x48fnV7/61SrHf/WrX+WGG26ojSYBAAAAAIAtXK0sP3XxxRfnmmuuWeV4u3bt8p//+Z8ZPHhwbTQLAABs5mo6m8TMEAAAIKmlmRovvfRSunbtusrxzp075+WXX66NJgEAAAAAgC1crYQa7dq1y1NPPbXK8SeffDKtW7eujSYBAAAAAIAtXK2EGl/84hfzzW9+M9OmTcvy5cuzfPnyTJ06Nd/61rfyxS9+sTaaBAAAAAAAtnC1sqfGRRddlJdeeil9+vRJ/fofNLFixYqcfPLJGT16dG00CQAAW4ya7jsBAACwpauVUKNhw4a57bbb8t///d958skn07hx4/Tq1SudO3eujeYAAAAAAICtQK2EGit179493bt3r80mAACAOmA2CQAAUBdqJdRYvnx5JkyYkHvvvTfz5s3LihUrqp2fOnVqbTQLAAAAAABswWol1PjWt76VCRMmZODAgenZs2dKpVJtNAMAAAAAAGxFaiXUuPXWW/PLX/4yAwYMqI3qAQAAAACArdA2tVFpw4YNs9NOO9VG1QAAAAAAwFaqVkKNs846Kz/60Y9SFEVtVA8AAAAAAGyFamX5qQcffDDTpk3LH/7wh+y6665p0KBBtfMTJ06sjWYBAAAAAIAtWK2EGtttt12OOuqo2qgaAAAAAADYStVKqDF+/PjaqBaALUyX4ZPqugsAAAAAlJFa2VMjSZYtW5YpU6bk2muvzdtvv50kefXVV7No0aLaahIAAAAAANiC1cpMjZdeeimHHXZYXn755SxevDiHHHJImjVrlrFjx+b999/PNddcUxvNAgAAAAAAW7BamanxrW99K3vuuWfmz5+fxo0bVx0/6qijcu+999ZGkwAAAAAAwBauVmZqPPjgg/njH/+Yhg0bVjveuXPn/POf/6yNJgEAAAAAgC1crczUWLFiRZYvX77K8VdeeSXNmjWrjSYBAAAAAIAtXK2EGoccckguv/zyquelUimLFi3KBRdckAEDBtRGkwAAAAAAwBauVpaf+uEPf5iDDjooPXr0yPvvv58TTjghL7zwQtq0aZNbbrmlNpoEAAAAAAC2cLUSanTs2DFPPPFEbrnlljz22GNZsWJFhgwZkhNPPLHaxuEAAAAAAADrq1ZCjSRp3LhxvvzlL+fLX/5ybTUBAAAAAABsRWol1LjxxhvXev7kk0+ujWYBAAAAAIAtWK2EGt/61reqPV+6dGnefffdNGzYME2aNBFqAAAAAAAAG2yb2qh0/vz51R6LFi3K888/n/32289G4QAAAAAAQI3USqixOt26dcvFF1+8yiwOAAAAAACA9bHJQo0kqVevXl599dVN2SQAAAAAALCFqJU9NX77299We14URebMmZMrrrgin/3sZ2ujSQAAAAAAYAtXK6HGoEGDqj0vlUpp27ZtDj744Fx22WW10SQAAAAAALCFq5VQY8WKFbVRLQAAAAAAsBXbpHtqAAAAAAAA1FStzNQYNmzYepcdN25cbXQBAAAAAADYwtRKqPH444/nsccey7Jly7LzzjsnSf72t7+lXr162WOPParKlUql2mgeAAAAAADYAtXK8lNHHHFEevfunVdeeSWPPfZYHnvsscyePTsHHXRQDj/88EybNi3Tpk3L1KlT11nXAw88kCOOOCIdO3ZMqVTKHXfcUe38KaecklKpVO2x9957VyuzePHinHnmmWnTpk2aNm2aI488Mq+88srGHDIAAAAAAFDLaiXUuOyyyzJmzJi0bNmy6ljLli1z0UUX5bLLLtugut55553stttuueKKK9ZY5rDDDsucOXOqHnfeeWe180OHDs3tt9+eW2+9NQ8++GAWLVqUww8/PMuXL9+wgQEAAAAAAHWmVpafWrhwYf71r39l1113rXZ83rx5efvttzeorv79+6d///5rLVNRUZHKysrVnluwYEGuu+66/PznP0/fvn2TJDfddFM6deqUKVOm5NBDD92g/gCwqi7DJ9V1FwAAAADYCtRKqHHUUUfl1FNPzWWXXVa1FNTDDz+c73znOzn66KM3env33Xdf2rVrl+222y69e/fO97///bRr1y5JMmPGjCxdujT9+vWrKt+xY8f07NkzDz30kFADAADKQE0C9FkXD6yFngAAAHWpVkKNa665JmeffXa+9KUvZenSpR80VL9+hgwZkksvvXSjttW/f/984QtfSOfOnTNz5sycf/75OfjggzNjxoxUVFRk7ty5adiwYbWlsJKkffv2mTt37hrrXbx4cRYvXlz1fOHChRu13wAAAAAAwIaplVCjSZMmueqqq3LppZfmxRdfTFEU2WmnndK0adON3tZxxx1X9d89e/bMnnvumc6dO2fSpElrnRVSFEVKpdIaz48ZMyajRo3aqH0FAAAAAABqrlY2Cl9p5cbd3bt3T9OmTVMURW02lyTp0KFDOnfunBdeeCFJUllZmSVLlmT+/PnVys2bNy/t27dfYz0jRozIggULqh6zZ8+u1X4DAAAAAABrVyuhxhtvvJE+ffqke/fuGTBgQObMmZMk+cpXvpKzzjqrNpqs1vbs2bPToUOHJMmnPvWpNGjQIJMnT64qM2fOnDzzzDPZd99911hPRUVFmjdvXu0BAAAAAADUnVoJNb797W+nQYMGefnll9OkSZOq48cdd1zuuuuuDapr0aJFeeKJJ/LEE08kSWbOnJknnngiL7/8chYtWpSzzz47f/rTnzJr1qzcd999OeKII9KmTZscddRRSZIWLVpkyJAhOeuss3Lvvffm8ccfz5e+9KX06tUrffv23WhjBgAAAAAAalet7Klxzz335O67784OO+xQ7Xi3bt3y0ksvbVBdjz76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i6JY5dhKY8aMyahRo1Y53qlTp1rpGwAAAACwZWlx+ZbZVk1t6j76mZSnt99+Oy1atFjj+a0i1GjTpk3q1au3yqyMefPmrTJ7Y6URI0Zk2LBhVc9XrFiRN998M61bt15jEEJ5WbhwYTp16pTZs2enefPmdd0dKBvuHagZ9w7UjHsHasa9AzXn/oGace/wURVFkbfffjsdO3Zca7mtItRo2LBhPvWpT2Xy5Mk56qijqo5Pnjw5n/vc51Z7TUVFRSoqKqod22677Wqzm9SR5s2b+x8t1IB7B2rGvQM1496BmnHvQM25f6Bm3Dt8FGubobHSVhFqJMmwYcNy0kknZc8998w+++yTn/70p3n55Zfz9a9/va67BgAAAAAArIetJtQ47rjj8sYbb+TCCy/MnDlz0rNnz9x5553p3LlzXXcNAAAAAABYD1tNqJEkp512Wk477bS67gabiYqKilxwwQWrLDMGrJ17B2rGvQM1496BmnHvQM25f6Bm3DtsKqWiKIq67gQAAAAAAMC6bFPXHQAAAAAAAFgfQg0AAAAAAKAsCDUAAAAAAICyINRgi9SlS5eUSqVVHqeffvpqy993332rLf/Xv/51E/ccNq0HHnggRxxxRDp27JhSqZQ77rij2vmiKDJy5Mh07NgxjRs3zoEHHphnn312nfX++te/To8ePVJRUZEePXrk9ttvr6URQN1Y272zdOnSfO9730uvXr3StGnTdOzYMSeffHJeffXVtdY5YcKE1b4Wvf/++7U8Gth01vW6c8opp6xyD+y9997rrNfrDluDdd0/q3sNKZVKufTSS9dYp9cetnRjxozJpz/96TRr1izt2rXLoEGD8vzzz1cr4z0PrGpd9473PNQ1oQZbpOnTp2fOnDlVj8mTJydJvvCFL6z1uueff77add26ddsU3YU6884772S33XbLFVdcsdrzY8eOzbhx43LFFVdk+vTpqayszCGHHJK33357jXX+6U9/ynHHHZeTTjopTz75ZE466aQce+yxeeSRR2prGLDJre3eeffdd/PYY4/l/PPPz2OPPZaJEyfmb3/7W4488sh11tu8efNqr0Nz5sxJo0aNamMIUCfW9bqTJIcddli1e+DOO+9ca51ed9harOv++fDrx/XXX59SqZRjjjlmrfV67WFLdv/99+f000/Pww8/nMmTJ2fZsmXp169f3nnnnaoy3vPAqtZ173jPQ10rFUVR1HUnoLYNHTo0v//97/PCCy+kVCqtcv6+++7LQQcdlPnz52e77bbb9B2EzUCpVMrtt9+eQYMGJfngG0sdO3bM0KFD873vfS9Jsnjx4rRv3z6XXHJJvva1r622nuOOOy4LFy7MH/7wh6pjhx12WFq2bJlbbrml1scBm9qH753VmT59ej7zmc/kpZdeyo477rjaMhMmTMjQoUPz1ltv1U5HYTOzunvnlFNOyVtvvbXKN9DXxusOW6P1ee0ZNGhQ3n777dx7771rLOO1h63Na6+9lnbt2uX+++/PAQcc4D0PrKcP3zur4z0Pm5KZGmzxlixZkptuuilf/vKXVxto/Lvdd989HTp0SJ8+fTJt2rRN1EPYPM2cOTNz585Nv379qo5VVFSkd+/eeeihh9Z43Z/+9Kdq1yTJoYceutZrYEu3YMGClEqldQbnixYtSufOnbPDDjvk8MMPz+OPP75pOgibkfvuuy/t2rVL9+7d89WvfjXz5s1ba3mvO7Cqf/3rX5k0aVKGDBmyzrJee9iaLFiwIEnSqlWrJN7zwPr68L2zpjLe87CpCDXY4t1xxx156623csopp6yxTIcOHfLTn/40v/71rzNx4sTsvPPO6dOnTx544IFN11HYzMydOzdJ0r59+2rH27dvX3VuTddt6DWwJXv//fczfPjwnHDCCWnevPkay+2yyy6ZMGFCfvvb3+aWW25Jo0aN8tnPfjYvvPDCJuwt1K3+/fvnF7/4RaZOnZrLLrss06dPz8EHH5zFixev8RqvO7CqG264Ic2aNcvRRx+91nJee9iaFEWRYcOGZb/99kvPnj2TeM8D62N1986Hec/Dpla/rjsAte26665L//7907FjxzWW2XnnnbPzzjtXPd9nn30ye/bs/OAHP1jjtDrYWnx4hlNRFOuc9VSTa2BLtHTp0nzxi1/MihUrctVVV6217N57711tQ+TPfvaz2WOPPfKTn/wkP/7xj2u7q7BZOO6446r+u2fPntlzzz3TuXPnTJo0aa0fznrdgequv/76nHjiietco9xrD1uTM844I0899VQefPDBVc55zwNrtrZ7J/Geh7phpgZbtJdeeilTpkzJV77ylQ2+du+995YUs1WrrKxMklW+bTRv3rxVvpX04es29BrYEi1dujTHHntsZs6cmcmTJ6/1G0urs8022+TTn/601yK2ah06dEjnzp3Xeh943YHq/vd//zfPP/98jd4Dee1hS3XmmWfmt7/9baZNm5Yddtih6rj3PLB2a7p3VvKeh7oi1GCLNn78+LRr1y4DBw7c4Gsff/zxdOjQoRZ6BeWha9euqayszOTJk6uOLVmyJPfff3/23XffNV63zz77VLsmSe655561XgNbmpX/uH/hhRcyZcqUtG7deoPrKIoiTzzxhNcitmpvvPFGZs+evdb7wOsOVHfdddflU5/6VHbbbbcNvtZrD1uaoihyxhlnZOLEiZk6dWq6du1a7bz3PLB667p3Eu95qFuWn2KLtWLFiowfPz6DBw9O/frV/9RHjBiRf/7zn7nxxhuTJJdffnm6dOmSXXfdtWpj8V//+tf59a9/XRddh01m0aJF+fvf/171fObMmXniiSfSqlWr7Ljjjhk6dGhGjx6dbt26pVu3bhk9enSaNGmSE044oeqak08+Odtvv33GjBmTJPnWt76VAw44IJdcckk+97nP5Te/+U2mTJmyxqmqUI7Wdu907Ngxn//85/PYY4/l97//fZYvX171Tb5WrVqlYcOGSVa9d0aNGpW999473bp1y8KFC/PjH/84TzzxRK688spNP0CoJWu7d1q1apWRI0fmmGOOSYcOHTJr1qycc845adOmTY466qiqa7zusLVa17/bkmThwoX51a9+lcsuu2y1dXjtYWtz+umn5+abb85vfvObNGvWrOrfZC1atEjjxo1TKpW854HVWNe9s2zZMu95qFsFbKHuvvvuIknx/PPPr3Ju8ODBRe/evaueX3LJJcXHP/7xolGjRkXLli2L/fbbr5g0adIm7C3UjWnTphVJVnkMHjy4KIqiWLFiRXHBBRcUlZWVRUVFRXHAAQcUTz/9dLU6evfuXVV+pV/96lfFzjvvXDRo0KDYZZddil//+tebaESwaazt3pk5c+ZqzyUppk2bVlXHh++doUOHFjvuuGPRsGHDom3btkW/fv2Khx56aNMPDmrR2u6dd999t+jXr1/Rtm3bokGDBsWOO+5YDB48uHj55Zer1eF1h63Vuv7dVhRFce211xaNGzcu3nrrrdXW4bWHrc2a/k02fvz4qjLe88Cq1nXveM9DXSsVRVHUSloCAAAAAACwEdlTAwAAAAAAKAtCDQAAAAAAoCwINQAAAAAAgLIg1AAAAAAAAMqCUAMAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKglADAADYbHTp0iWXX375Rqtv1qxZKZVKeeKJJzbougkTJmS77bbbaP0AAAA2DqEGAACw2Zg+fXr+8z//c5O2ubog5bjjjsvf/va3TdoPAABg3erXdQcAAICty9KlS9OgQYNqx5YsWZKGDRumbdu2ddSr6ho3bpzGjRvXdTcAAIAPMVMDAACosbvuuiv77bdftttuu7Ru3TqHH354XnzxxarzK5d/+uUvf5kDDzwwjRo1yk033ZRTTjklgwYNypgxY9KxY8d07949SfVZE8cff3y++MUvVmtv6dKladOmTcaPH79e7a/LgQcemJdeeinf/va3UyqVUiqVkqy6/NTIkSPzyU9+Mtdff3123HHHbLvttvnGN76R5cuXZ+zYsamsrEy7du3y/e9/v1r9CxYsyH/+53+mXbt2ad68eQ4++OA8+eST690/AACgOqEGAABQY++8806GDRuW6dOn5957780222yTo446KitWrKhW7nvf+16++c1v5i9/+UsOPfTQJMm9996bv/zlL5k8eXJ+//vfr1L3iSeemN/+9rdZtGhR1bG7774777zzTo455pgNan9NJk6cmB122CEXXnhh5syZkzlz5qyx7Isvvpg//OEPueuuu3LLLbfk+uuvz8CBA/PKK6/k/vvvzyWXXJLzzjsvDz/8cJKkKIoMHDgwc+fOzZ133pkZM2Zkjz32SJ8+ffLmm2+uV/8AAIDqLD8FAADU2MpwYaXrrrsu7dq1y3PPPZeePXtWHR86dGiOPvroamWbNm2an/3sZ2nYsOFq6z700EPTtGnT3H777TnppJOSJDfffHOOOOKING/efIPaX5NWrVqlXr16adasWSorK9dadsWKFbn++uvTrFmz9OjRIwcddFCef/753Hnnndlmm22y884755JLLsl9992XvffeO9OmTcvTTz+defPmpaKiIknygx/8IHfccUf+53/+Z5PvHQIAAFsCMzUAAIAae/HFF3PCCSfkYx/7WJo3b56uXbsmSV5++eVq5fbcc89Vru3Vq9caA40kadCgQb7whS/kF7/4RZIPZmX85je/yYknnrjB7W8MXbp0SbNmzaqet2/fPj169Mg222xT7di8efOSJDNmzMiiRYvSunXrbLvttlWPmTNnbtASWQAAwP8xUwMAAKixI444Ip06dcr/+3//Lx07dsyKFSvSs2fPLFmypFq5pk2brnLt6o592IknnpjevXtn3rx5mTx5cho1apT+/ftvcPsbw4c3Ny+VSqs9tnLpqxUrVqRDhw657777Vqnr3/frAAAA1p9QAwAAqJE33ngjf/nLX3Lttddm//33T5I8+OCDG7WNfffdN506dcptt92WP/zhD/nCF75QNbtjY7XfsGHDLF++fKP2O0n22GOPzJ07N/Xr10+XLl02ev0AALA1EmoAAAA10rJly7Ru3To//elP06FDh7z88ssZPnz4Rm2jVCrlhBNOyDXXXJO//e1vmTZt2kZvv0uXLnnggQfyxS9+MRUVFWnTps1G6Xvfvn2zzz77ZNCgQbnkkkuy884759VXX82dd96ZQYMGrXZJLgAAYO3sqQEAANTINttsk1tvvTUzZsxIz5498+1vfzuXXnrpRm/nxBNPzHPPPZftt98+n/3sZzd6+xdeeGFmzZqVj3/842nbtu1G63epVMqdd96ZAw44IF/+8pfTvXv3fPGLX8ysWbPSvn37jdYOAABsTUpFURR13QkAAAAAAIB1MVMDAAAAAAAoC0INAAAAAACgLAg1AAAAAACAsiDUAAAAAAAAyoJQAwAAAAAAKAtCDQAAAAAAoCwINQAAAAAAgLIg1AAAAAAAAMqCUAMAAAAAACgLQg0AAAAAAKAsCDUAAAAAAICyINQAAAAAAADKwv8HcIV5PuDuPwEAAAAASUVORK5CYII=",
|
|
"text/plain": [
|
|
"<Figure size 1600x800 with 3 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"network = NetworkParams(\n",
|
|
" mixnet_delay_mean=10, # seconds\n",
|
|
" mixnet_delay_var=4,\n",
|
|
" broadcast_delay_mean=1, # second\n",
|
|
" pol_proof_time=2, # seconds\n",
|
|
")\n",
|
|
"\n",
|
|
"\n",
|
|
"mixnet_delay_data = np.array([network.sample_mixnet_delay() for _ in range(100000)])\n",
|
|
"\n",
|
|
"plt.figure(figsize=(16,8))\n",
|
|
"ax = plt.subplot(221)\n",
|
|
"_ = ax.hist(mixnet_delay_data, bins=100)\n",
|
|
"ax.set_title(f\"mixnet delay\")\n",
|
|
"_ = ax.set_ylabel(\"frequency\")\n",
|
|
"_ = ax.set_xlabel(\"delay (seconds)\")\n",
|
|
"\n",
|
|
"broadcast_delay_data = network.sample_broadcast_delay(np.zeros(100000))\n",
|
|
"ax = plt.subplot(222)\n",
|
|
"_ = ax.hist(broadcast_delay_data, bins=100)\n",
|
|
"ax.set_title(f\"block broadcast_delay\")\n",
|
|
"ax.set_ylabel(\"frequency\")\n",
|
|
"ax.set_xlabel(\"delay (seconds)\")\n",
|
|
"\n",
|
|
"BLOCK_TIME = 0\n",
|
|
"block_arrival_slots = np.array([network.block_arrival_time(np.array([BLOCK_TIME])) for _ in range(10000)])\n",
|
|
"\n",
|
|
"ax = plt.subplot(212)\n",
|
|
"_ = ax.hist(block_arrival_slots, bins=100)\n",
|
|
"ax.set_title(f\"block arrival slot when sent in slot {BLOCK_TIME}\")\n",
|
|
"ax.set_ylabel(\"frequency\")\n",
|
|
"ax.set_xlabel(\"arrival time\")\n",
|
|
"\n",
|
|
"plt.tight_layout()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"id": "94cc80de-2c60-495f-a73a-d126717f1007",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class Sim:\n",
|
|
" def __init__(self, params: Params, network: NetworkParams):\n",
|
|
" self.params = params\n",
|
|
" self.network = network\n",
|
|
" self.events = {}\n",
|
|
" self.blocks = []\n",
|
|
" self.block_heights = np.array([], dtype=np.int64)\n",
|
|
" self.block_arrivals = np.zeros(shape=(params.N, 0), dtype=np.int64) # arrival time to each leader for each block\n",
|
|
"\n",
|
|
" def emit_block(self, t, leader, height, parent):\n",
|
|
" assert type(t) in [float, np.float64], type(t)\n",
|
|
" assert type(leader) in [int, np.int64]\n",
|
|
" assert type(height) in [int, np.int64]\n",
|
|
" assert type(parent) in [int, np.int64]\n",
|
|
" \n",
|
|
" block = Block(\n",
|
|
" id=len(self.blocks),\n",
|
|
" t=t,\n",
|
|
" height=height,\n",
|
|
" parent=parent,\n",
|
|
" leader=leader\n",
|
|
" )\n",
|
|
" self.blocks.append(block)\n",
|
|
" self.block_heights = np.append(self.block_heights, block.height)\n",
|
|
" \n",
|
|
" # decide when this block will arrive at each node\n",
|
|
" self.block_arrivals = np.append(self.block_arrivals, self.network.block_arrival_time(np.repeat(t, self.params.N).reshape((self.params.N, 1))), axis=1)\n",
|
|
" return block.id\n",
|
|
"\n",
|
|
" def plot_spacetime_diagram(self, MAX_T=1 * 60 * 60):\n",
|
|
" alpha_index = sorted(range(self.params.N), key=lambda n: self.params.relative_stake[n])\n",
|
|
" nodes = [f\"$N_{n}$($\\\\alpha$={self.params.relative_stake[n]:.2f})\" for n in alpha_index]\n",
|
|
" messages = [(nodes[alpha_index.index(self.blocks[b].leader)], nodes[alpha_index.index(node)], self.blocks[b].t, arrival_t, f\"$B_{{{b}}}$\") for b, arrival_ts in enumerate(self.block_arrivals.T) for node, arrival_t in enumerate(arrival_ts) if arrival_t < MAX_T]\n",
|
|
" \n",
|
|
" fig, ax = plt.subplots(figsize=(8,8))\n",
|
|
" \n",
|
|
" # Plot vertical lines for each node\n",
|
|
" max_slot = max(s for _,_,start_t, end_t,_ in messages for s in [start_t, end_t])\n",
|
|
" for i, node in enumerate(nodes):\n",
|
|
" ax.plot([i, i], [0, max_slot], 'k-', linewidth=0.1)\n",
|
|
" ax.text(i, max_slot + 30 * (0 if i % 2 == 0 else 1), node, ha='center', va='bottom')\n",
|
|
" \n",
|
|
" # Plot messages\n",
|
|
" colors = plt.cm.rainbow(np.linspace(0, 1, len(messages)))\n",
|
|
" for (start, end, start_time, end_time, label), color in zip(messages, colors):\n",
|
|
" start_idx = nodes.index(start)\n",
|
|
" end_idx = nodes.index(end)\n",
|
|
" ax.annotate('', xy=(end_idx, end_time), xytext=(start_idx, start_time),\n",
|
|
" arrowprops=dict(arrowstyle='->', color=\"black\", lw=0.5))\n",
|
|
" placement = 0\n",
|
|
" mid_x = start_idx * (1 - placement) + end_idx * placement\n",
|
|
" mid_y = start_time * (1 - placement) + end_time * placement\n",
|
|
" ax.text(mid_x, mid_y, label, ha='center', va='center', \n",
|
|
" bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))\n",
|
|
" \n",
|
|
" ax.set_xlim(-1, len(nodes))\n",
|
|
" ax.set_ylim(0, max_slot + 70)\n",
|
|
" ax.set_xticks(range(len(nodes)))\n",
|
|
" ax.set_xticklabels([])\n",
|
|
" # ax.set_yticks([])\n",
|
|
" ax.set_title('Space-Time Diagram')\n",
|
|
" ax.set_ylabel('Time')\n",
|
|
" \n",
|
|
" plt.tight_layout()\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
" def honest_chain(self):\n",
|
|
" chain_head = max(self.blocks, key=lambda b: b.height)\n",
|
|
" honest_chain = {chain_head.id}\n",
|
|
" \n",
|
|
" curr_block = chain_head\n",
|
|
" while curr_block.parent >= 0:\n",
|
|
" honest_chain.add(curr_block.parent)\n",
|
|
" curr_block = self.blocks[curr_block.parent]\n",
|
|
" return sorted(honest_chain, key=lambda b: self.blocks[b].height)\n",
|
|
"\n",
|
|
" def visualize_chain(self):\n",
|
|
" honest_chain = self.honest_chain()\n",
|
|
" print(\"Honest chain length\", len(honest_chain))\n",
|
|
" honest_chain_set = set(honest_chain)\n",
|
|
" \n",
|
|
" layout = Layout()\n",
|
|
" layout.hierachical = True\n",
|
|
" \n",
|
|
" G = Network(width=1600, height=800, notebook=True, directed=True, layout=layout, cdn_resources='in_line')\n",
|
|
"\n",
|
|
" for block in self.blocks:\n",
|
|
" # level = slot\n",
|
|
" level = block.height\n",
|
|
" color = \"lightgrey\"\n",
|
|
" if block.id in honest_chain_set:\n",
|
|
" color = \"orange\"\n",
|
|
"\n",
|
|
" G.add_node(int(block.id), level=block.height, color=color, label=f\"{block.t:.2f}\")\n",
|
|
" # G.add_node(int(block.id), level=block.t * 0.1, color=color, label=f\"{block.height}\")\n",
|
|
"\n",
|
|
" if block.parent >= 0:\n",
|
|
" G.add_edge(int(block.id), int(block.parent), width=2, color=color)\n",
|
|
" \n",
|
|
" return G.show(\"chain.html\")\n",
|
|
"\n",
|
|
" def adverserial_analysis(self):\n",
|
|
" np.random.seed(0)\n",
|
|
" adversary = self.params.N - 1\n",
|
|
" \n",
|
|
" reorg_depths = []\n",
|
|
" honest_chain = self.honest_chain()\n",
|
|
" print(\"honest_chain length\", len(honest_chain))\n",
|
|
"\n",
|
|
" adversary_delays = self.delays.T[adversary]\n",
|
|
"\n",
|
|
" for block in self.blocks:\n",
|
|
" if block.id % 100 == 0:\n",
|
|
" print(\"processing\", block)\n",
|
|
" nearest_honest_block = block\n",
|
|
" while nearest_honest_block.height >= len(honest_chain) or honest_chain[nearest_honest_block.height-1] != nearest_honest_block.id:\n",
|
|
" nearest_honest_block = self.blocks[nearest_honest_block.parent]\n",
|
|
" \n",
|
|
" \n",
|
|
" adversary_blocks = []\n",
|
|
" t = block.t\n",
|
|
" for h in range(block.height + 1, self.params.CHAIN_HEIGHT):\n",
|
|
" t += adversary_delays[h-1]\n",
|
|
" adversary_blocks.append(t)\n",
|
|
" adverserial_height = block.height + len(adversary_blocks)\n",
|
|
" \n",
|
|
" honest_chain_up_to_t = [\n",
|
|
" b for b in honest_chain\n",
|
|
" if self.blocks[b].t <= t\n",
|
|
" ]\n",
|
|
" last_honest_block = self.blocks[honest_chain_up_to_t[-1]]\n",
|
|
" assert last_honest_block.height >= nearest_honest_block.height, (t, last_honest_block, nearest_honest_block)\n",
|
|
" if last_honest_block.height < adverserial_height:\n",
|
|
" reorg_depths += [last_honest_block.height - nearest_honest_block.height]\n",
|
|
" \n",
|
|
" plt.hist(reorg_depths, bins=60)\n",
|
|
" plt.grid(True)\n",
|
|
" plt.title(f\"reorg depths with {self.params.adversary_control * 100:.0f}% adversary\")\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
" def run(self, seed=None):\n",
|
|
" if seed is not None:\n",
|
|
" np.random.seed(seed)\n",
|
|
"\n",
|
|
" \n",
|
|
" # emit the genesis block\n",
|
|
" \n",
|
|
" \n",
|
|
" t = 0.0\n",
|
|
" self.emit_block(\n",
|
|
" t=t,\n",
|
|
" leader=0,\n",
|
|
" height=1,\n",
|
|
" parent=-1,\n",
|
|
" )\n",
|
|
" self.block_arrivals[:,:] = 0 # all nodes see the genesis block immediately\n",
|
|
" \n",
|
|
" self.delays = self.params.block_delay_at_height()\n",
|
|
"\n",
|
|
" for h in range(1, self.params.CHAIN_HEIGHT):\n",
|
|
" for leader, block_delay in enumerate(self.delays[h-1]):\n",
|
|
" if self.params.adversary_control and leader == self.params.N-1:\n",
|
|
" continue\n",
|
|
" leader_arrivals = self.block_arrivals[leader]\n",
|
|
" \n",
|
|
" parent = (leader_arrivals == leader_arrivals[self.block_heights == h].min()).argmax()\n",
|
|
" assert parent is not None\n",
|
|
" assert self.blocks[parent].height == h, (self.blocks[parent], h)\n",
|
|
" self.emit_block(\n",
|
|
" t=self.blocks[parent].t + block_delay,\n",
|
|
" leader=leader,\n",
|
|
" height=self.blocks[parent].height + 1,\n",
|
|
" parent=parent,\n",
|
|
" )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"id": "617a5279-43cb-4fb2-ae65-33fa3a5355fc",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"avg blocks per sec 0.21317693308797184\n",
|
|
"Number of blocks 2441\n",
|
|
"longest chain 245\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"np.random.seed(0)\n",
|
|
"\n",
|
|
"sim = Sim(\n",
|
|
" params=Params(\n",
|
|
" CHAIN_HEIGHT=245,\n",
|
|
" MEAN_BLOCK_TIME=20,\n",
|
|
" honest_stake = np.random.pareto(10, size=10),\n",
|
|
" adversary_control=0.3,\n",
|
|
" ),\n",
|
|
" network=NetworkParams(\n",
|
|
" mixnet_delay_mean=10, # seconds\n",
|
|
" mixnet_delay_var=4,\n",
|
|
" broadcast_delay_mean=2, # second\n",
|
|
" pol_proof_time=2, # seconds\n",
|
|
" )\n",
|
|
")\n",
|
|
"sim.run(seed=5)\n",
|
|
"# sim.visualize_chain()\n",
|
|
"# sim.plot_spacetime_diagram()\n",
|
|
"\n",
|
|
"n_blocks_per_s = len(sim.blocks) / max(b.t for b in sim.blocks)\n",
|
|
"print(\"avg blocks per sec\", n_blocks_per_s)\n",
|
|
"print(\"Number of blocks\", len(sim.blocks))\n",
|
|
"print(\"longest chain\", max(b.height for b in sim.blocks))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"id": "d6ecc3ce-9206-4e0b-9118-55cc01aea8fb",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"honest_chain length 245\n",
|
|
"processing Block(id=0, t=0.0, height=1, parent=-1, leader=0)\n",
|
|
"processing Block(id=100, t=1231.1825397618154, height=11, parent=81, leader=9)\n",
|
|
"processing Block(id=200, t=643.888657267845, height=21, parent=189, leader=9)\n",
|
|
"processing Block(id=300, t=2018.0763488312223, height=31, parent=286, leader=9)\n",
|
|
"processing Block(id=400, t=1652.7268466796731, height=41, parent=390, leader=9)\n",
|
|
"processing Block(id=500, t=2166.111823344706, height=51, parent=483, leader=9)\n",
|
|
"processing Block(id=600, t=2309.4070586513462, height=61, parent=588, leader=9)\n",
|
|
"processing Block(id=700, t=1975.9198897321473, height=71, parent=689, leader=9)\n",
|
|
"processing Block(id=800, t=2166.04768532737, height=81, parent=787, leader=9)\n",
|
|
"processing Block(id=900, t=2480.0230869739353, height=91, parent=882, leader=9)\n",
|
|
"processing Block(id=1000, t=4488.3970031230565, height=101, parent=986, leader=9)\n",
|
|
"processing Block(id=1100, t=3511.4998241967496, height=111, parent=1083, leader=9)\n",
|
|
"processing Block(id=1200, t=5101.30605009875, height=121, parent=1189, leader=9)\n",
|
|
"processing Block(id=1300, t=4461.73775749359, height=131, parent=1288, leader=9)\n",
|
|
"processing Block(id=1400, t=4971.418138581639, height=141, parent=1388, leader=9)\n",
|
|
"processing Block(id=1500, t=5558.756693373566, height=151, parent=1488, leader=9)\n",
|
|
"processing Block(id=1600, t=5666.4009766452255, height=161, parent=1582, leader=9)\n",
|
|
"processing Block(id=1700, t=5619.044916466169, height=171, parent=1689, leader=9)\n",
|
|
"processing Block(id=1800, t=5806.723632336016, height=181, parent=1788, leader=9)\n",
|
|
"processing Block(id=1900, t=8114.93522758204, height=191, parent=1889, leader=9)\n",
|
|
"processing Block(id=2000, t=6222.034399400075, height=201, parent=1987, leader=9)\n",
|
|
"processing Block(id=2100, t=6611.0363127282435, height=211, parent=2089, leader=9)\n",
|
|
"processing Block(id=2200, t=6841.239918856918, height=221, parent=2189, leader=9)\n",
|
|
"processing Block(id=2300, t=7713.936866630708, height=231, parent=2288, leader=9)\n",
|
|
"processing Block(id=2400, t=8046.790543317015, height=241, parent=2385, leader=9)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAGxCAYAAABIjE2TAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8VUlEQVR4nO3de1yUZf7/8feIw3AQUEQEFBHN1k2NTMvSSq1AycxDdpAOaG7mZj1y1e24fhl2Te1cX81OW2opaf1WrU03w1SsVXcVa/NQLW6ahyQTD4jYOOL1+6Mv007DUZjhRl/Px2MeD+/rvu7rvu4Pt/DmvudmbMYYIwAAAAtp0tATAAAA+CUCCgAAsBwCCgAAsBwCCgAAsBwCCgAAsBwCCgAAsBwCCgAAsBwCCgAAsBwCCgAAsBwCClBP1qxZI5vNpjVr1vh1P7Nnz9bcuXMr3f//+3//z6/7PxM2m01Op9OzvH37djmdTu3atcunb79+/dS1a9cz3tdjjz2m7t27Kzo6WiEhIerQoYPGjh2rb7/91qev2+1Wdna22rdvL4fDoc6dO2vmzJk+/dauXavu3bsrIiJCV111lbZv3+7TZ/z48erbt68C9ce5nU6nbDZbQPYFNAQCCtDIVBZQrGz9+vX6zW9+41nevn27srOzKwwodXXkyBGNHDlS8+bN04cffqjJkyfrgw8+UK9evVRUVOTV995779X06dM1fvx4rVixQsOGDdMDDzygadOmeY03bNgwXXLJJVq8eLGioqI0fPhwlZWVefps2LBBb7zxhl555RVCA1BPmjb0BIDS0lKFhYWddfvCzy677LKA7evFF1/0Wu7Xr5+Sk5N13XXX6b333tNdd90lSdq2bZtef/11Pf744/r973/v6VtUVKSpU6dq3Lhxio6O1vr16+VyufTiiy/KbrerS5cuatOmjQoKCtS5c2e53W6NHTtWDz30kDp37hyw42woJ06cUGhoqF/3YYzRjz/+6Pf9wNq4goKAKr8svXnzZo0YMUItWrRQx44dJf30TWn27Nm66KKLFBoaqhYtWmjEiBH65ptvfMZ54403lJKSopCQEEVHR2vYsGH68ssvvfqMGjVKzZo105YtW5SWlqaIiAhdc801kn76rXjMmDGKjo5Ws2bNNGjQIH3zzTc+tyIq89VXX2ngwIEKCwtTTEyMxo0bp2PHjlXYd+XKlbrmmmsUGRmpsLAw9enTRx9//HGFdfnss880fPhwRUZGKioqSrfffrt++OEHT7/27dtr27ZtysvLk81mk81mU/v27b3Gcrvdeuyxx5SQkKDIyEhde+21+vrrr736fPbZZ7r++usVGxsrh8OhhIQEDRo0SHv37q30mF988UU1adJEBw4c8LQ988wzstlsGj9+vKft9OnTatGihSZNmuRp+++6zp07VzfddJMkqX///p7j+OVVoY0bN+rKK69UWFiYOnTooBkzZuj06dOVzq8qrVq1kiQ1bfrz72RLly6VMUajR4/26jt69GidOHFCH374oSTpxx9/lMPhkN1ulyQ1a9bM0y5JTz/9tE6ePKlHHnmkVnPKzc3VkCFD1LZtW4WEhOi8887TPffco4MHD/r0XbZsmS666CI5HA4lJyfr6aef9unTvXt3XXnllT7tZWVlatOmjYYPH+5pO3nypKZOnarOnTvL4XCoVatWGj16tNe5Jv10vl1//fVavHixunfvrpCQEGVnZ0uS3n33XfXq1UtRUVGer1F5+Cuvz6RJk3TRRRcpKipK0dHRuvzyy/Xee+/5zNFms+m+++7Tyy+/rF//+tdyOByaO3euOnXqpAEDBvj0LykpUVRUlNd5h7OQAQIoKyvLSDJJSUnmoYceMrm5uWbp0qXGGGPuvvtuY7fbzaRJk8yHH35ocnJyTOfOnU3r1q1NYWGhZ4xp06YZSWbkyJFm2bJl5s033zQdOnQwUVFR5t///renX2ZmprHb7aZ9+/Zm+vTp5uOPPzYrVqwwZWVl5oorrjAhISFmxowZ5qOPPjLZ2dmmU6dORpLJysqq8hgKCwtNbGysadOmjZkzZ45Zvny5ue2220y7du2MJLN69WpP37feesvYbDYzdOhQs3jxYvPXv/7VXH/99SYoKMisXLmywrr8/ve/NytWrDDPPvusCQ8PN927dzcnT540xhizefNm06FDB9O9e3ezfv16s379erN582ZjjDGrV682kkz79u3NbbfdZpYtW2befvtt065dO9OpUydz6tQpY4wxJSUlpmXLlqZnz57mnXfeMXl5eWbRokVm3LhxZvv27ZUe91dffWUkmZycHE/bwIEDTWhoqOnUqZOn7R//+IeRZJYvX+5p+++6HjhwwPM1fPHFFz3HceDAAWOMMX379jUtW7Y0nTp1Mi+//LLJzc019957r5Fk5s2bV+XX5r+53W5TWlpqNm/ebPr06WPOP/98c+zYMc/6W2+91bRq1cpnu5KSEiPJPPLII8YYY3bv3m3sdruZPXu2OXz4sHnooYdMy5YtTWlpqdmxY4cJCwszeXl5NZ5XuZdeeslMnz7dvP/++yYvL8/MmzfPpKSkmF/96leer7cxxqxcudIEBQWZK664wixevNi8++675pJLLvGcb+VeeOEFI8nr/4AxxixfvtxIMu+//74xxpiysjIzcOBAEx4ebrKzs01ubq7585//bNq0aWMuuOACU1pa6tk2KSnJxMfHmw4dOpg33njDrF692vzzn/8069atMzabzdx6661m+fLlZtWqVWbOnDnmjjvu8Gx75MgRM2rUKPPWW2+ZVatWmQ8//NBMnjzZNGnSxOfrKMm0adPGXHjhhSYnJ8esWrXKbN261bzwwgvGZrP5HNOLL75oJJlt27bVuu5oPAgoCKjyH8T/8z//49W+fv16I8k888wzXu179uwxoaGh5sEHHzTGGHP48GETGhpqrrvuOq9+u3fvNg6Hw2RkZHjaMjMzjSTzxhtvePVdtmyZkWReeuklr/bp06fXKKA89NBDxmazmc8//9yrPTU11SugHD9+3ERHR5vBgwd79SsrKzMpKSnm0ksv9anL7373O6++CxYsMJLM/PnzPW1dunQxffv29ZlXeUD5ZW3eeecdI8msX7/eGGPMpk2bjCRPMKyNtm3bmrvuussYY4zL5TLh4eHmoYceMpLMt99+a4wx5vHHHzd2u92UlJR4tvtlXd99912fMFeub9++RpL5xz/+4dV+wQUXmAEDBtRonvv37zeSPK9evXqZffv2efVJTU01v/rVryrcPjg42IwdO9azPHv2bBMcHGwkmaioKPPee+8ZY4y59tprzZgxY2o0p6qcPn3auN1u8+233xpJnvGNMaZXr14mISHBnDhxwtNWXFxsoqOjvQLKwYMHTXBwsHn00Ue9xr755ptN69atjdvtNsYY8/bbbxtJ5i9/+YtXv40bNxpJZvbs2Z62pKQkExQUZL7++muvvk8//bSRZI4cOVLjYzx16pRxu91mzJgxpnv37l7ryut66NAhr/bi4mITERFhHnjgAa/2Cy64wPTv37/G+0bjxC0eNIgbb7zRa/mDDz6QzWbT7bffrlOnTnlecXFxSklJ8TwZs379ep04cUKjRo3y2j4xMVFXX321z62TivaVl5cnSbr55pu92keOHFmjua9evVpdunRRSkqKV3tGRobX8rp163To0CFlZmZ6HdPp06c1cOBAbdy4UcePH/fa5rbbbvNavvnmm9W0aVOtXr26RnOTpBtuuMFr+cILL5Qkz1Ms5513nlq0aKGHHnpIL7/8coVPpFTmmmuu0cqVKz3HV1paqokTJyomJka5ubmSfrqldfnllys8PLzG4/5SXFycLr30Up/jqOhJnIrExMRo48aN+vTTT/Xaa6/p0KFD6t+/v/bv3+/Vr6o3tP73ut/+9rc6dOiQvvzyS33//fe64YYb9NZbb+mLL77QU089pUOHDum2225Tq1at1LFjR7388svVzvHAgQMaN26cEhMT1bRpU9ntdiUlJUmS53bl8ePHtXHjRg0fPlwhISGebSMiIjR48GCv8Vq2bKnBgwdr3rx5nlthhw8f1nvvvac777zTc3vrgw8+UPPmzTV48GCv8/Kiiy5SXFycz1NoF154oc4//3yvtksuuUTST+fnO++8o3379lV4jO+++6769OmjZs2aeY7x9ddf97kdK0lXX321WrRo4dUWERGh0aNHa+7cuZ7/K6tWrdL27dt13333VV5cnBUIKGgQ8fHxXsvff/+9jDFq3bq17Ha712vDhg2e+/LlT2H8cntJSkhI8HlKIywsTJGRkV5tRUVFatq0qaKjo73aW7duXaO5FxUVKS4uzqf9l23ff/+9JGnEiBE+x/TEE0/IGKNDhw5VOUbTpk3VsmVLn+OqSsuWLb2WHQ6HpJ/e3ChJUVFRysvL00UXXaRHH31UXbp0UUJCgrKysuR2u6sc+9prr9Xu3btVUFCglStXqnv37oqNjdXVV1+tlStX6sSJE1q3bp2uvfbaGs+3JsdQfhzlx1Cdpk2bqmfPnurTp49+85vfaNWqVfrmm280Y8YMr31UVNfjx4/r5MmTPudHeHi45z0bRUVFmjRpkp5//nm1aNFCDzzwgA4dOqQdO3Zo4cKFmjx5cpWh8vTp00pLS9PixYv14IMP6uOPP9Y///lPbdiwQdLPX6vDhw/r9OnTNTrfJOmuu+7Svn37PGHx7bfflsvl8gr033//vY4cOaLg4GCf87KwsNDnPTAV/V+76qqrtHTpUp06dUp33nmn2rZtq65du+rtt9/29Fm8eLFuvvlmtWnTRvPnz9f69eu1ceNG3XXXXZ7371S3H0m6//77dezYMS1YsECSNGvWLLVt21ZDhgypsD/OHjzFgwbxy99cY2JiZLPZ9Mknn3h+oP638rbyH1y//E1Ykr777jvFxMRUuZ/yMU6dOqVDhw55/RAqLCys0dxbtmxZYd9ftpXPZebMmZU+xfLLUFRYWKg2bdp4lk+dOqWioqIKf2DXRbdu3bRw4UIZY/TFF19o7ty5+uMf/6jQ0FA9/PDDlW5X/ibjlStXKjc3V6mpqZ72P/zhD1q7dq1cLledA0p9a9u2rRISEvTvf//b01Zeg8LCQq8f9lu2bJGkKv8Wy6RJk9SjRw/PVbe//e1vmjNnjqKionTJJZcoLS1Ny5cvV//+/SvcfuvWrfrXv/6luXPnKjMz09O+Y8cOr34tWrSQzWar0fkmSQMGDFBCQoLmzJmjAQMGaM6cOerVq5cuuOACT5+YmBi1bNnS8ybgX4qIiPBaruwq05AhQzRkyBC5XC5t2LBB06dPV0ZGhtq3b6/LL79c8+fPV3JyshYtWuQ1hsvlqnC8yvZz3nnnKT09XS+++KLS09P1/vvvKzs7W0FBQRX2x9mDKyiwhOuvv17GGO3bt089e/b0eXXr1k2SdPnllys0NFTz58/32n7v3r1atWqV5wdoVfr27StJWrRokVf7woULazTX/v37a9u2bfrXv/7l1Z6Tk+O13KdPHzVv3lzbt2+v8Jh69uyp4OBgr23Kf0ss98477+jUqVPq16+fp602VxKqY7PZlJKSoueee07NmzfX5s2bq+wfHx+vCy64QH/5y1+Un5/vCSipqan64Ycf9OyzzyoyMtJzC6Ayv7yq4287duzQ3r17dd5553nahgwZIpvNpnnz5nn1nTt3rkJDQzVw4MAKx1q9erXeffddzZ4929NmjPG6XVdSUlLlH2wr/2H8yzD+yiuveC2Hh4fr0ksv1eLFi72uOhw7dkx//etffcYNCgrSHXfcoaVLl+qTTz7Rpk2bvJ6skX76v1ZUVKSysrIKz8lf/epXlc67Ig6HQ3379tUTTzwh6acnxMqPMTg42Ct4FBYWVvgUT3UeeOABffHFF8rMzFRQUJDuvvvuWo+BxocrKLCEPn36aOzYsRo9erQ2bdqkq666SuHh4dq/f78+/fRTdevWTb/97W/VvHlzTZkyRY8++qjuvPNOjRw5UkVFRcrOzlZISIiysrKq3dfAgQPVp08fTZo0ScXFxerRo4fWr1+vN998U5LUpEnVuX3ChAl64403NGjQIE2dOlWtW7fWggUL9NVXX3n1a9asmWbOnKnMzEwdOnRII0aMUGxsrH744Qf961//0g8//KCXXnrJa5vFixeradOmSk1N1bZt2zRlyhSlpKR4vV+m/Df/RYsWqUOHDgoJCfEEuJr44IMPNHv2bA0dOlQdOnSQMUaLFy/WkSNHPIGjKtdcc41mzpyp0NBQ9enTR5KUnJys5ORkffTRR7rhhhu8HuetSPnViVdffVUREREKCQlRcnJyna8UffHFF/rd736nESNGqEOHDmrSpIm2bNmi5557Ti1bttTkyZM9fbt06aIxY8YoKytLQUFBuuSSS/TRRx/p1Vdf1dSpU31u8Ug//fZ/zz33yOl0Kjk52dM+YMAA/fGPf1RkZKQKCgr08ccf68EHH6x0np07d1bHjh318MMPyxij6Oho/fWvf/Xcmvlvf/rTnzRw4EClpqZq0qRJKisr0xNPPKHw8HCfW4TST7d5nnjiCWVkZCg0NFS33HKL1/pbb71VCxYs0HXXXacHHnhAl156qex2u/bu3avVq1dryJAhGjZsWJV1/p//+R/t3btX11xzjdq2basjR47ohRdekN1u9/wCUP548r333qsRI0Zoz549+tOf/qT4+HgVFBRUOf4vpaam6oILLtDq1at1++23KzY2tlbbo5FquPfn4lxU/rTKDz/8UOH6N954w/Tq1cuEh4eb0NBQ07FjR3PnnXeaTZs2efX785//bC688EITHBxsoqKizJAhQ3weOczMzDTh4eEV7ufQoUNm9OjRpnnz5iYsLMykpqaaDRs2GEnmhRdeqPY4tm/fblJTU01ISIiJjo42Y8aMMe+9916FT6bk5eWZQYMGmejoaGO3202bNm3MoEGDzLvvvutTl/z8fDN48GDTrFkzExERYUaOHGm+//57r/F27dpl0tLSTEREhOfRZGN+fornv8c1xpidO3caSWbOnDnGmJ8eFx45cqTp2LGjCQ0NNVFRUebSSy81c+fOrfa4jTGe40xNTfVqv/vuu40k87//+78+26iCp6Oef/55k5ycbIKCgrzm17dvX9OlSxefMTIzMz3HWpnCwkJz++23m44dO5qwsDATHBxsOnToYMaNG2d2797t0//kyZMm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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"sim.adverserial_analysis()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "89bf9a0f-7f47-4216-80e8-5e6e24998f3b",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Text(0.5, 0, 'PoL time as fraction of mean block time')"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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3l2TJ0+Wj4+PwsPDtX37dn3wwQd66623XFk6AACoJlx6mCkvL08zZszQ+vXrdfbsWYWEhGjIkCH685//LC8vL0nSmTNnNH36dCUkJOjcuXMKDw/X2LFj9fzzz8tisdx0HhxmAgDAfOzZfrs0zFQFwgwAAOZjmnNmAAAAbhVhBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmBphBgAAmJpLw0xhYaFefvllNWrUSD4+Prr77rv12muvqbi4uES7jIwMPfzwwwoICJCfn586duyoEydOuKhqAABQnXi4cubz5s3T0qVLtWLFCjVv3lzJycmKiYlRQECAJk2aJEk6cuSIunbtqtGjR2vmzJkKCAhQRkaGatSo4crSAQBANWExDMNw1cwHDBigwMBAvf/++9ZpjzzyiGrWrKmVK1dKkp544gl5enpa39srNzdXAQEBysnJkb+/v0PqBgAAzmXP9tulh5m6du2qLVu2KDMzU5J04MABJSYmql+/fpKk4uJi/fOf/1STJk0UFRWlevXqqUOHDvr000/L7TM/P1+5ubklXgAA4Pbl0jAzdepUDRkyRE2bNpWnp6ciIyMVGxurIUOGSJLOnj2rCxcuaO7cuerbt68SEhL0hz/8QYMGDdL27dvL7HPOnDkKCAiwvsLCwqpykQAAQBVz6WGmNWvWaPLkyfrLX/6i5s2bKy0tTbGxsXrrrbc0YsQIZWVlKTQ0VEOGDNFHH31k/d7DDz8sX19frV69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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"N = 100\n",
|
|
"net_params = [NetworkParams(\n",
|
|
" mixnet_delay_mean=0.1, # seconds\n",
|
|
" mixnet_delay_var=0.1,\n",
|
|
" broadcast_delay_mean=0.1, # second\n",
|
|
" pol_proof_time=i/N * 5, # seconds\n",
|
|
" ) for i in range(N)]\n",
|
|
"\n",
|
|
"sims = [Sim(\n",
|
|
" params=Params(\n",
|
|
" CHAIN_HEIGHT=1000, # seconds\n",
|
|
" MEAN_BLOCK_TIME=20,\n",
|
|
" honest_stake = np.random.pareto(10, size=10),\n",
|
|
" adversary_control=0.1,\n",
|
|
" ),\n",
|
|
" network=net\n",
|
|
") for net in net_params]\n",
|
|
"\n",
|
|
"[sim.run() for sim in sims]\n",
|
|
"\n",
|
|
"\n",
|
|
"plt.scatter([sim.network.pol_proof_time / sim.params.MEAN_BLOCK_TIME for sim in sims], [100 - 100 * len(sim.honest_chain()) / len(sim.blocks) for sim in sims])\n",
|
|
"plt.ylabel(\"wasted blocks %\")\n",
|
|
"plt.xlabel(\"PoL time as fraction of mean block time\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1c21cfba-68b3-487b-a273-76776defddca",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.9"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|