.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/consensus/attacks/plot_03_selfish_mining.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_consensus_attacks_plot_03_selfish_mining.py: Selfish mining: majority is not enough (Eyal and Sirer 2014) ============================================================ Bitcoin was thought incentive-compatible: a miner earns its share of blocks by publishing them. Eyal and Sirer showed a pool can earn more by keeping blocks secret and releasing them only to overtake or tie the honest chain, wasting honest work. Above a threshold hashrate, between 0 and 1/3 depending on how ties break, selfish mining pays. What to look for ---------------- The simulated state machine matches the closed-form revenue. With gamma = 0 (ties go to honest blocks) the threshold is 1/3; when the pool wins every tie, any pool profits. The history behind this experiment: :doc:`/history/consensus_breakthroughs`. .. GENERATED FROM PYTHON SOURCE LINES 22-24 Revenue against hashrate ------------------------ .. GENERATED FROM PYTHON SOURCE LINES 24-50 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import blockchainkit as bk alphas = np.linspace(0.02, 0.48, 24) fig, ax = plt.subplots(figsize=(7, 4.5)) ax.plot(alphas, alphas, "--", color="black", label="honest mining: revenue = alpha") for gamma, color in ((0.0, "#2563eb"), (0.5, "#16a34a"), (1.0, "#ea580c")): exact = [bk.consensus.selfish_mining_revenue(a, gamma) for a in alphas] ax.plot(alphas, exact, color=color, label=f"selfish, gamma = {gamma}") sims = [ bk.consensus.simulate_selfish_mining(a, gamma, blocks=40_000, seed=7).revenue for a in alphas[::4] ] ax.plot(alphas[::4], sims, "o", color=color) threshold = bk.consensus.selfish_mining_threshold(gamma) ax.axvline(threshold, color=color, linestyle=":", alpha=0.7) ax.set( xlabel="pool hashrate alpha", ylabel="pool share of blocks", title="Selfish mining pays above (1 - gamma)/(3 - 2 gamma)", ) ax.legend(fontsize=8) fig.tight_layout() .. image-sg:: /api/gallery/consensus/attacks/images/sphx_glr_plot_03_selfish_mining_001.png :alt: Selfish mining pays above (1 - gamma)/(3 - 2 gamma) :srcset: /api/gallery/consensus/attacks/images/sphx_glr_plot_03_selfish_mining_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 51-55 .. code-block:: Python result = bk.consensus.simulate_selfish_mining(0.4, 0.0, blocks=200_000, seed=1) assert result.revenue > 0.4 print(f"a 40% pool gets {result.revenue:.1%} of the blocks") .. rst-class:: sphx-glr-script-out .. code-block:: none a 40% pool gets 48.0% of the blocks .. GENERATED FROM PYTHON SOURCE LINES 56-61 Exercise -------- Selfish mining lowers the total rate of blocks on the main chain. Explain why difficulty retargeting (the next experiment) turns that into profit for the pool in absolute terms, not just as a share. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.330 seconds) .. _sphx_glr_download_api_gallery_consensus_attacks_plot_03_selfish_mining.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/consensus/attacks/plot_03_selfish_mining.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_selfish_mining.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_selfish_mining.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_selfish_mining.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_