|
146 | 146 | "from itertools import product as cartesian_product \n",
|
147 | 147 | "from pathlib import Path\n",
|
148 | 148 | "\n",
|
149 |
| - "from experiments.forking_simulation import ForkingSimulation" |
| 149 | + "from experiments.forking_simulation import ForkingSimulation\n", |
| 150 | + "from experiments.graph import create_network_graph" |
150 | 151 | ]
|
151 | 152 | },
|
152 | 153 | {
|
|
178 | 179 | "target_spacings = [4, 8, 12, 16] # Expected averate time between blocks\n",
|
179 | 180 | "time_steps = [1, 2, 4, 6, 8] # Time granularity used to generate block hashes\n",
|
180 | 181 | "latencies = [0, 0.1, 0.5, 1.0] # Block propagation delays\n",
|
| 182 | + "num_network_topologies = 3 # How many networks will be used to experiment with other parameters\n", |
| 183 | + "\n", |
| 184 | + "# We create a list of network topologies for each graph size, and not for each settings combination.\n", |
| 185 | + "network_topologies = {\n", |
| 186 | + " graph_size: [\n", |
| 187 | + " create_network_graph(\n", |
| 188 | + " num_nodes=graph_size,\n", |
| 189 | + " num_outbound_connections=8,\n", |
| 190 | + " max_inbound_connections=125,\n", |
| 191 | + " graph_model='preferential_attachment'\n", |
| 192 | + " ) for _ in range(num_network_topologies)\n", |
| 193 | + " ]\n", |
| 194 | + " for graph_size in {\n", |
| 195 | + " num_proposer_nodes + num_validator_nodes + num_relay_nodes for (\n", |
| 196 | + " num_proposer_nodes,\n", |
| 197 | + " num_validator_nodes,\n", |
| 198 | + " num_relay_nodes\n", |
| 199 | + " ) in cartesian_product(\n", |
| 200 | + " num_proposer_nodes_values,\n", |
| 201 | + " num_validator_nodes_values,\n", |
| 202 | + " num_relay_nodes_values,\n", |
| 203 | + " )\n", |
| 204 | + " }\n", |
| 205 | + "}\n", |
181 | 206 | "\n",
|
182 | 207 | "settings_tuples = list(cartesian_product(\n",
|
183 | 208 | " num_proposer_nodes_values,\n",
|
|
190 | 215 | "\n",
|
191 | 216 | "settings_tuples = sorted([\n",
|
192 | 217 | " (\n",
|
193 |
| - " num_proposer_nodes_values,\n", |
194 |
| - " num_validator_nodes_values,\n", |
195 |
| - " num_relay_nodes_values,\n", |
| 218 | + " num_proposer_nodes,\n", |
| 219 | + " num_validator_nodes,\n", |
| 220 | + " num_relay_nodes,\n", |
196 | 221 | " target_spacings,\n",
|
197 | 222 | " time_steps,\n",
|
198 |
| - " latencies\n", |
| 223 | + " latencies,\n", |
| 224 | + " graph_id, # Just used to create directory names\n", |
| 225 | + " graph_edges # Besides filtering, we also add this\n", |
199 | 226 | " )\n",
|
200 | 227 | " for (\n",
|
201 |
| - " num_proposer_nodes_values,\n", |
202 |
| - " num_validator_nodes_values,\n", |
203 |
| - " num_relay_nodes_values,\n", |
| 228 | + " num_proposer_nodes,\n", |
| 229 | + " num_validator_nodes,\n", |
| 230 | + " num_relay_nodes,\n", |
204 | 231 | " target_spacings,\n",
|
205 | 232 | " time_steps,\n",
|
206 | 233 | " latencies\n",
|
207 | 234 | " ) in settings_tuples\n",
|
208 | 235 | " \n",
|
| 236 | + " # That's like a nested loop, but \"unrolled\" in the list comprehension\n", |
| 237 | + " # We keep the graph id to construct directory names\n", |
| 238 | + " for graph_id, graph_edges in enumerate(network_topologies[\n", |
| 239 | + " num_proposer_nodes +\n", |
| 240 | + " num_validator_nodes +\n", |
| 241 | + " num_relay_nodes\n", |
| 242 | + " ])\n", |
| 243 | + " \n", |
209 | 244 | " if (\n",
|
210 | 245 | " time_steps < target_spacings and\n",
|
211 | 246 | " target_spacings % time_steps == 0\n",
|
|
248 | 283 | "\n",
|
249 | 284 | "# We generate a dataset per settings tuple\n",
|
250 | 285 | "for c, settings in enumerate(settings_tuples):\n",
|
251 |
| - " num_proposer_nodes, num_validator_nodes, num_relay_nodes, target_spacing, time_step, latency = settings\n", |
| 286 | + " (\n", |
| 287 | + " num_proposer_nodes,\n", |
| 288 | + " num_validator_nodes,\n", |
| 289 | + " num_relay_nodes,\n", |
| 290 | + " target_spacing,\n", |
| 291 | + " time_step,\n", |
| 292 | + " latency,\n", |
| 293 | + " graph_id,\n", |
| 294 | + " graph_edges\n", |
| 295 | + " ) = settings\n", |
252 | 296 | "\n",
|
253 | 297 | " # Each simulation stores results in a different path\n",
|
254 | 298 | " result_directory = results_path.joinpath(\n",
|
255 |
| - " '_'.join(str(v) for v in settings)\n", |
| 299 | + " # We discard `graph_edges` to construct the directory name\n", |
| 300 | + " '_'.join(str(v) for v in settings[:-1])\n", |
256 | 301 | " ).resolve()\n",
|
257 | 302 | "\n",
|
258 | 303 | " # Previous data will be overwritten\n",
|
|
275 | 320 | " num_relay_nodes=num_relay_nodes,\n",
|
276 | 321 | " simulation_time=simulation_time,\n",
|
277 | 322 | " sample_time=sample_time,\n",
|
278 |
| - " graph_model=graph_model,\n", |
| 323 | + " graph_edges=graph_edges,\n", |
279 | 324 | " block_time_seconds=target_spacing,\n",
|
280 | 325 | " block_stake_timestamp_interval_seconds=time_step,\n",
|
281 | 326 | " network_stats_file_name=network_stats_filename,\n",
|
|
0 commit comments