diff --git a/analysis/DAS_Codex.ipynb b/analysis/DAS_Codex.ipynb new file mode 100644 index 0000000..187f93c --- /dev/null +++ b/analysis/DAS_Codex.ipynb @@ -0,0 +1,122 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 367 + }, + "id": "dhSrVOikPwMX", + "outputId": "b417211e-d765-47d1-fae3-4b7151008fdd" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "675\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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L8rNzS2ytsWLF6tVq1b29ezdu9fhEbXCtUtSVlaW/S4oX19fh/qL8+KLL2rw4MGqV69ekdMrV66sxx9/XI0bN1bVqlX13HPP2Y/522+/rRYtWqh9+/ZFLjtmzBhdvnxZGRkZys7OVq9eva67I0mSvLy8dM899yg9PV3vvPPOddN9fX01atQoDRkyRP/5z3+K3NaAAQO0bNkySVfvRvrjH/9oPy5bt25V586dVbNmTfn7+2vBggWmHvcrfK4LH8ekpCS1b99e1atXV0BAgD799NMS11vUdVXweKgk1axZUz4+PvbhiRMnKjw8XA8++KAaNGigWbNm3bBmAED5QJAEALgtlPaRi9DQUMXExDiEUllZWQ5/SF67ztDQUNWvX99h/vPnz9v/qPX19dWFCxfs818bSDlTjRo1VLlyZf3www/2umw2mz2UKOq43H333dq/f78+/vhjxcTEqGnTpvrll1/06aef2h8pq1GjhipUqKAjR47Yl/vll18UHBxsHy5q3REREVq0aJG6detWZGfUpamhMGc8VlPQB06B5ORkjRw5UlarVc2bNze97Lp16zRx4kTdcccd9pClQ4cOWrp0aalrqlu37nXH3dvbW7Vr11adOnV09OhR+7QLFy4oIyPDPhwaGqqkpCSH6/TSpUsKDg5WhQoVNHXqVKWmpmrz5s1au3atFi9efN32jxw5opEjR2revHnKyMhQZmammjVr5nCcilOnTh2dPXtW2dnZDvUXZ926dXrrrbfsx+3o0aPq06ePXnnlFUlSixYtHM77tT+vW7dOH3/8sX3ZzZs3689//rP9McDdu3dr2LBhql69uipVqqSxY8dq27ZtxYYteXl5xXaUfuXKFV24cMEhSL1Wly5ddOrUKe3evVvLli2zP9YmXQ2ZevbsqaNHj8pms2nUqFGmj+W15/ra43j58mU9+uijmjBhgk6ePKnMzEx1797dvt6i2kpR11XB46FFLePn56fXX39dP//8s9asWaM33nhD69atu2HdAIDbH0ESAOC2ULt2baWnpysnJ8fU/D169NCBAwf0/vvvKzc3V7m5udq+fbv27dtX5Pxt27aVn5+fXnnlFV28eFH5+fnau3evtm/fLklq1aqVPv30U505c0a//vqr5syZc8v2rSS/+93vNHLkSD3zzDP2uyWOHTtm72+ndu3aysjIcOisuUqVKoqK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VKlSJZ0+fVpnzpwp9aZWrVqlHj16qGnTpjdTqT1IGjBggCQpOjpa0dHRN7UuM7gjCQAAAAAAD/TVV1/Jx8dHjz/+uCTJy8tLs2fP1v/93//pwoULOnr0qGJjY9WoUSNNmzZNkpSdna2HH35YLVu2VLNmzfTBBx9Iknbu3KmYmBhFRUWpa9euOnHihKSrd8eMHz9e0dHRmjFjhsLCwnTlyhX7ukJDQ5Wbm6uffvpJDz30kKKionTvvffqxx9/lCSlpaWpQ4cOat68uaZMmeLqQ+RUJ06cUI0aNVSpUiVJUo0aNXTgwAH98Y9/tM/zxRdf6JFHHpF09W6syZMnq2XLlmrfvr1OnjypzZs3a82aNZo4caJatWqln376SZK0YsUKtW3bVo0bN9bGjRslSfn5+Zo4caLatGmjFi1a6O9//7sk6a9//as2btyoVq1aafbs2UpJSVGPHj0kSVlZWXr88cfVvHlztWjRQh999NFv3m+CpDKEx2sBAAAAAGb98MMPioqKchhXrVo1/f73v1deXp62bdumjz76SN99951WrFihHTt2KDk5WXXr1tWePXu0d+9ePfTQQ8rNzdXYsWO1cuVK7dy5U8OHD9fkyZPt68zJydGOHTs0depUtWrVShs2bJAkrV27Vl27dlWFChUUHx+vuXPnaufOnXrttdf05JNPSpLGjRun0aNH6/vvv1edOnVcd3Bc4MEHH9TRo0fVuHFjPfnkk9qwYYM6deqkH3/8UadOnZIkLVq0SMOHD5d0NXhr37699uzZo06dOmnhwoW6++671bNnT7366qvavXu3GjZsKEn28zdnzhx7CJiYmCh/f39t375d27dv18KFC5WWlqZZs2bp3nvv1e7du/XMM8841Pjyyy/L399f33//vb777jvdd999v3m/CZIAAAAAALgNdenSRUFBQapcubJ69eqlr7/+Ws2bN9cXX3yhSZMmaePGjfL399f+/fu1d+9edenSRa1atdL06dOVnp5uX0/fvn0dfi64i2n58uXq27evsrKytHnzZj322GNq1aqV/vSnP9nvaNq0aZP69+8vSRo8eLAL9975qlatqp07dyohIUE1a9ZU3759tXTpUg0ePFj//Oc/lZmZqS1btqhbt26SpIoVK9rvFIqKitLhw4eLXXevXr2um+/zzz/X4sWL1apVK7Vr104ZGRk6ePBgiTV+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\n" + }, + "metadata": {} + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "\n", + "# Prepare data observed in the network\n", + "\n", + "rawData = [6691, 2199, 606, 358, 202, 154, 111, 72, 81, 53, 78, 21, 38, 11, 31, 22, 35, 16, 19, 19, 30, 20, 30, 22, 14, 13, 7, 5, 10, 5, 11, 8, 12, 5, 6, 4, 11, 7, 6, 4, 5, 4, 4, 2, 5, 7, 3, 6, 2, 6, 13, 8, 21, 17, 24, 18, 18, 11, 8, 13, 9, 5, 3, 11] \n", + "#oldRawData = [757, 2195, 505, 293, 174, 120, 62, 60, 56, 46, 61, 20, 27, 23, 16, 26, 39, 14, 27, 17, 32, 33, 21, 17, 14, 10, 9, 10, 6, 2, 6, 4, 11, 3, 2, 4, 4, 5, 4, 9, 8, 6, 1, 4, 6, 3, 2, 7, 6, 7, 12, 21, 29, 21, 40, 36, 29, 21, 19, 15, 22, 15, 8, 8]\n", + "rawData[0] = 0 # Not interested in nodes without validators\n", + "maxValPnode = 1000\n", + "for i in range(maxValPnode):\n", + " if i >= len(rawData):\n", + " rawData.append(0)\n", + "\n", + "# Prepare synthetic data for over 64 topic subscription\n", + "\n", + "# Peaks\n", + "mus = [256, 384, 512, 640, 768] # Means\n", + "sigmas = [20, 20, 20, 20, 20] # Standard deviations\n", + "nodes = [25, 50, 100, 200, 300]\n", + "\n", + "# Bumpy\n", + "#mus = [1, 100, 200, 300, 400] # Means\n", + "#sigmas = [0.9, 20, 20, 20, 20] # Standard deviations\n", + "#nodes = [5000, 500, 500, 500, 400]\n", + "\n", + "# Flat\n", + "#mus = [1, 100, 200, 300, 400] # Means\n", + "#sigmas = [0.9, 30, 30, 30, 25] # Standard deviations\n", + "#nodes = [5000, 500, 500, 500, 400]\n", + "\n", + "dist = [[],[],[],[],[]]\n", + "for i in range(5):\n", + " dist[i] = np.random.normal(mus[i], sigmas[i], nodes[i])\n", + "\n", + "valPnode = [0]*maxValPnode\n", + "for d in dist:\n", + " for i in d:\n", + " if int(i) > 0:\n", + " valPnode[int(i)] += 1\n", + "\n", + "# Merge both to get statistics\n", + "\n", + "totalList = [x + y for x, y in zip(rawData, valPnode)]\n", + "totalNodes = 0\n", + "totalValidators = 0\n", + "totalAllSubnets = 0\n", + "for i in range(len(totalList)):\n", + " totalValidators += i*totalList[i]\n", + " totalNodes += totalList[i]\n", + " if i >= 64:\n", + " totalAllSubnets += totalList[i]\n", + "print(totalAllSubnets)\n", + "#print(rawData)\n", + "#print(valPnode)\n", + "\n", + "# Plotting the figure\n", + "fig = plt.figure(figsize=(20,5))\n", + "plt.rcParams[\"figure.facecolor\"] = \"white\"\n", + "plt.bar(range(maxValPnode), height=rawData, width=0.9, color=\"blue\", label=\"Observed\")\n", + "plt.bar(range(maxValPnode), height=valPnode, width=0.9, color=\"orange\", label=\"Synthetic\")\n", + "plt.xlabel(\"Number of validators per node\")\n", + "plt.ylabel(\"Count\")\n", + "plt.yscale(\"log\")\n", + "#plt.axis([0,maxValPnode,0,50])\n", + "plt.grid(True)\n", + "plt.legend(loc=1, ncol=2)\n", + "plt.title('Ethereum network with '+str(totalNodes)+\" nodes and \"+str(totalValidators)+\" validators\")\n", + "plt.savefig(\"valPnode.png\")\n", + "\n" + ] + } + ] +} \ No newline at end of file