.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/network/events/plot_01_discrete_event_simulation.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_network_events_plot_01_discrete_event_simulation.py: Discrete-event simulation: a network on an event queue (GPSS 1961, Simula 1965) =============================================================================== A discrete-event simulator keeps a queue of future events ordered by time. It pops the earliest, jumps the clock straight to it, and lets it schedule new events. Nothing happens between events, so no time is wasted waiting, and with a seeded random source every run is exactly reproducible. :class:`~blockchainkit.network.systems.gossip.SimulatedNetwork` simulates gossip this way: a message sent on a link becomes a delivery event a random number of ticks later. What to look for ---------------- Follow arrival times as the message crosses the network. An isolated peer misses it, and reconnecting the peer requires an explicit retransmission of old news. Rerunning with the same seed reproduces every arrival time. Read cells in order. An ``assert`` that produces no output has passed. The final exercise asks you to change an input and explain the result. The history behind this experiment: :doc:`/history/network_breakthroughs`. See :doc:`/exercises/network` for a worked solution to the exercise. .. GENERATED FROM PYTHON SOURCE LINES 28-40 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk network = bk.network.SimulatedNetwork(["alice", "bob", "carol", "dave"], seed=7) network.connect("alice", "bob", latency=(2, 4)) network.connect("bob", "carol", latency=(2, 4)) # Dave starts partitioned from the other three peers. network.broadcast("alice", b"a new block announcement") network.run(until=10) assert {event.recipient for event in network.deliveries} == {"alice", "bob", "carol"} .. GENERATED FROM PYTHON SOURCE LINES 41-43 Healing requires synchronization, not just a link ------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 43-50 .. code-block:: Python network.connect("carol", "dave", latency=(2, 2)) network.broadcast("carol", b"a new block announcement") network.run() assert network.deliveries[-1].recipient == "dave" assert network.deliveries[-1].time == 12 print([(event.recipient, event.time) for event in network.deliveries]) .. rst-class:: sphx-glr-script-out .. code-block:: none [('alice', 0), ('bob', 3), ('carol', 5), ('dave', 12)] .. GENERATED FROM PYTHON SOURCE LINES 51-55 Same seed, same history ----------------------- The simulator draws latencies from its own seeded generator, so a second run with the same operations reproduces every event exactly. .. GENERATED FROM PYTHON SOURCE LINES 55-71 .. code-block:: Python def replay(seed): net = bk.network.SimulatedNetwork(["alice", "bob", "carol", "dave"], seed=seed) net.connect("alice", "bob", latency=(2, 4)) net.connect("bob", "carol", latency=(2, 4)) net.broadcast("alice", b"a new block announcement") net.run(until=10) net.connect("carol", "dave", latency=(2, 2)) net.broadcast("carol", b"a new block announcement") net.run() return net.deliveries assert replay(7) == network.deliveries .. GENERATED FROM PYTHON SOURCE LINES 72-85 .. code-block:: Python fig, ax = plt.subplots(figsize=(8, 4)) names = [event.recipient for event in network.deliveries] times = [event.time for event in network.deliveries] ax.barh(names, times, color=["#2563eb"] * 3 + ["#ea580c"]) ax.axvline(10, color="black", linestyle="--", label="Partition healed") ax.scatter(times, names, color="black", zorder=3) ax.set( xlabel="First receipt time (simulation ticks)", title="Propagation and explicit resynchronization", ) ax.legend() fig.tight_layout() .. image-sg:: /api/gallery/network/events/images/sphx_glr_plot_01_discrete_event_simulation_001.png :alt: Propagation and explicit resynchronization :srcset: /api/gallery/network/events/images/sphx_glr_plot_01_discrete_event_simulation_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 86-91 Exercise -------- Connect a triangle and check that duplicate paths do not duplicate receipts. Disconnect a link while a message is in flight. Then replace fixed latency with a range and compare results under the same and different seeds. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.126 seconds) .. _sphx_glr_download_api_gallery_network_events_plot_01_discrete_event_simulation.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/network/events/plot_01_discrete_event_simulation.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_discrete_event_simulation.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_discrete_event_simulation.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_discrete_event_simulation.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_