Describe Soft And Hard Forks

Based on a suggestion made by @petertodd to the -devel mailing list and
the discussion in that thread by him and other participants.

* We've been using the term "consensus", but this commit introduces a
  formal definition for it and "consensus rules" as part of the block
  chain introduction.

* Describe that consensus rules may change and may happen when they
  do: hard or soft forks.

* Describe how full nodes can detect hard or soft forks, then describe
  how SPV clients can detect hard and soft forks using the more limited
  information available to them.
This commit is contained in:
David A. Harding 2014-10-23 12:39:18 -04:00
parent 2147b830f1
commit 2e8ceb26df
No known key found for this signature in database
GPG key ID: 4B29C30FF29EC4B7
9 changed files with 462 additions and 6 deletions

49
img/dev/en-hard-fork.dot Normal file
View file

@ -0,0 +1,49 @@
digraph {
size=6.25;
rankdir=LR
//splines = ortho;
ranksep = 0.2;
nodesep = 0.1;
edge [ penwidth = 1.75, fontname="Sans" ]
node [ penwidth = 1.75, shape = "box", fontname="Sans", label = "", width=0.3, height=0.3 ]
graph [ penwidth = 1.75, fontname="Sans" ]
invis1 [ shape = "none", label = "Blocks\nFrom\nUpgraded\nNodes" ]
invis0 [ shape = "none", label = "Blocks\nFrom Non-\nUpgraded\nNodes" ];
subgraph cluster_honest {
block0 [ label = "Follows\nOld\nRules" ];
block1 [ label = "Follows\nOld\nRules" ];
block2_1 [ label = "Follows\nOld\nRules" ];
block3_1 [ label = "Follows\nOld\nRules" ];
//block2_1 -> block4 [ style = "invis", minlen = 2 ];
style = "invis";
}
subgraph cluster_attack {
block2 [ label = "Follows\nNew\nRules" ];
block3 [ label = "Follows\nNew\nRules" ];
block4 [ label = "Follows\nNew\nRules" ];
block5 [ label = "Follows\nNew\nRules" ];
style = "invis"
}
invis0 -> block0 [ minlen = 2, style = "dashed" ];
block2_1 -> block3_1;
block0 -> block1 -> block2 -> block3 -> block4 -> block5;
block1 -> block2_1
label = "A Hard Fork: Non-Upgraded Nodes Reject The New Rules, Diverging The Chain"
}

BIN
img/dev/en-hard-fork.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

128
img/dev/en-hard-fork.svg Normal file
View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
-->
<!-- Title: _anonymous_0 Pages: 1 -->
<svg width="450pt" height="147pt"
viewBox="0.00 0.00 450.00 146.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph1" class="graph" transform="scale(0.716561 0.716561) rotate(0) translate(4 201)">
<title>_anonymous_0</title>
<polygon fill="white" stroke="white" points="-4,5 -4,-201 625,-201 625,5 -4,5"/>
<text text-anchor="middle" x="310" y="-8.4" font-family="Sans" font-size="14.00">A Hard Fork: &#160;Non&#45;Upgraded Nodes Reject The New Rules, Diverging The Chain</text>
<g id="graph2" class="cluster"><title>cluster_honest</title>
</g>
<g id="graph3" class="cluster"><title>cluster_attack</title>
</g>
<!-- invis1 -->
<g id="node1" class="node"><title>invis1</title>
<text text-anchor="middle" x="45" y="-90.4" font-family="Sans" font-size="14.00">Blocks</text>
<text text-anchor="middle" x="45" y="-73.4" font-family="Sans" font-size="14.00">From</text>
<text text-anchor="middle" x="45" y="-56.4" font-family="Sans" font-size="14.00">Upgraded</text>
<text text-anchor="middle" x="45" y="-39.4" font-family="Sans" font-size="14.00">Nodes</text>
</g>
<!-- invis0 -->
<g id="node2" class="node"><title>invis0</title>
<text text-anchor="middle" x="45" y="-173.4" font-family="Sans" font-size="14.00">Blocks</text>
<text text-anchor="middle" x="45" y="-156.4" font-family="Sans" font-size="14.00">From Non&#45;</text>
<text text-anchor="middle" x="45" y="-139.4" font-family="Sans" font-size="14.00">Upgraded</text>
<text text-anchor="middle" x="45" y="-122.4" font-family="Sans" font-size="14.00">Nodes</text>
</g>
<!-- block0 -->
<g id="node4" class="node"><title>block0</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="190,-181.5 122,-181.5 122,-122.5 190,-122.5 190,-181.5"/>
<text text-anchor="middle" x="156" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="156" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="156" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- invis0&#45;&gt;block0 -->
<g id="edge4" class="edge"><title>invis0&#45;&gt;block0</title>
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M89.5084,-152C96.8055,-152 104.367,-152 111.66,-152"/>
<polygon fill="black" stroke="black" points="111.736,-155.5 121.736,-152 111.736,-148.5 111.736,-155.5"/>
</g>
<!-- block1 -->
<g id="node5" class="node"><title>block1</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="272,-181.5 204,-181.5 204,-122.5 272,-122.5 272,-181.5"/>
<text text-anchor="middle" x="238" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="238" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="238" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block0&#45;&gt;block1 -->
<g id="edge8" class="edge"><title>block0&#45;&gt;block1</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M190.3,-152C191.419,-152 192.545,-152 193.675,-152"/>
<polygon fill="black" stroke="black" points="193.837,-155.5 203.837,-152 193.837,-148.5 193.837,-155.5"/>
</g>
<!-- block2_1 -->
<g id="node6" class="node"><title>block2_1</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="356,-181.5 288,-181.5 288,-122.5 356,-122.5 356,-181.5"/>
<text text-anchor="middle" x="322" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="322" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="322" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block1&#45;&gt;block2_1 -->
<g id="edge14" class="edge"><title>block1&#45;&gt;block2_1</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M272.166,-152C273.946,-152 275.745,-152 277.551,-152"/>
<polygon fill="black" stroke="black" points="277.864,-155.5 287.864,-152 277.864,-148.5 277.864,-155.5"/>
</g>
<!-- block2 -->
<g id="node9" class="node"><title>block2</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="356,-99.5 288,-99.5 288,-40.5 356,-40.5 356,-99.5"/>
<text text-anchor="middle" x="322" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="322" y="-65.9" font-family="Sans" font-size="14.00">New</text>
<text text-anchor="middle" x="322" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block1&#45;&gt;block2 -->
<g id="edge9" class="edge"><title>block1&#45;&gt;block2</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M267.852,-122.859C273.422,-117.421 279.304,-111.679 285.058,-106.062"/>
<polygon fill="black" stroke="black" points="287.533,-108.537 292.244,-99.0472 282.644,-103.528 287.533,-108.537"/>
</g>
<!-- block3_1 -->
<g id="node7" class="node"><title>block3_1</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="438,-181.5 370,-181.5 370,-122.5 438,-122.5 438,-181.5"/>
<text text-anchor="middle" x="404" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="404" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="404" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block2_1&#45;&gt;block3_1 -->
<g id="edge6" class="edge"><title>block2_1&#45;&gt;block3_1</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M356.3,-152C357.419,-152 358.545,-152 359.675,-152"/>
<polygon fill="black" stroke="black" points="359.837,-155.5 369.837,-152 359.837,-148.5 359.837,-155.5"/>
</g>
<!-- block3 -->
<g id="node10" class="node"><title>block3</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="438,-99.5 370,-99.5 370,-40.5 438,-40.5 438,-99.5"/>
<text text-anchor="middle" x="404" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="404" y="-65.9" font-family="Sans" font-size="14.00">New</text>
<text text-anchor="middle" x="404" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block2&#45;&gt;block3 -->
<g id="edge10" class="edge"><title>block2&#45;&gt;block3</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M356.3,-70C357.419,-70 358.545,-70 359.675,-70"/>
<polygon fill="black" stroke="black" points="359.837,-73.5001 369.837,-70 359.837,-66.5001 359.837,-73.5001"/>
</g>
<!-- block4 -->
<g id="node11" class="node"><title>block4</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="522,-99.5 454,-99.5 454,-40.5 522,-40.5 522,-99.5"/>
<text text-anchor="middle" x="488" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="488" y="-65.9" font-family="Sans" font-size="14.00">New</text>
<text text-anchor="middle" x="488" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block3&#45;&gt;block4 -->
<g id="edge11" class="edge"><title>block3&#45;&gt;block4</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M438.166,-70C439.946,-70 441.745,-70 443.551,-70"/>
<polygon fill="black" stroke="black" points="443.864,-73.5001 453.864,-70 443.864,-66.5001 443.864,-73.5001"/>
</g>
<!-- block5 -->
<g id="node12" class="node"><title>block5</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="604,-99.5 536,-99.5 536,-40.5 604,-40.5 604,-99.5"/>
<text text-anchor="middle" x="570" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="570" y="-65.9" font-family="Sans" font-size="14.00">New</text>
<text text-anchor="middle" x="570" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block4&#45;&gt;block5 -->
<g id="edge12" class="edge"><title>block4&#45;&gt;block5</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M522.3,-70C523.419,-70 524.545,-70 525.675,-70"/>
<polygon fill="black" stroke="black" points="525.837,-73.5001 535.837,-70 525.837,-66.5001 525.837,-73.5001"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

47
img/dev/en-soft-fork.dot Normal file
View file

@ -0,0 +1,47 @@
digraph {
size=6.25;
rankdir=LR
//splines = ortho;
ranksep = 0.2;
nodesep = 0.1;
edge [ penwidth = 1.75, fontname="Sans" ]
node [ penwidth = 1.75, shape = "box", fontname="Sans", label = "", width=0.3, height=0.3 ]
graph [ penwidth = 1.75, fontname="Sans" ]
invis1 [ shape = "none", label = "Blocks\nFrom\nUpgraded\nNodes" ]
invis0 [ shape = "none", label = "Blocks\nFrom Non-\nUpgraded\nNodes" ];
subgraph cluster_honest {
block0 [ label = "Follows\nOld\nRules" ];
block1 [ label = "Follows\nOld\nRules" ];
block2_1 [ label = "Follows Old Rules\nBut Violates\nNew Rules", style = "filled" ];
block2_1 -> block4 [ style = "invis", minlen = 2 ];
block4 [ label = "Follows\nOld\nRules" ];
style = "invis";
}
subgraph cluster_attack {
block2 [ label = "Follows\nOld & New\nRules" ];
block3 [ label = "Follows\nOld & New\nRules" ];
style = "invis"
}
invis0 -> block0 [ minlen = 2, style = "dashed" ];
block0 -> block1 -> block2 -> block3 -> block4;
block1 -> block2_1
label = "A Soft Fork: Blocks Violating New Rules Are Made Stale By The Upgraded Mining Majority"
}

BIN
img/dev/en-soft-fork.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

105
img/dev/en-soft-fork.svg Normal file
View file

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
-->
<!-- Title: _anonymous_0 Pages: 1 -->
<svg width="450pt" height="143pt"
viewBox="0.00 0.00 450.00 143.02" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph1" class="graph" transform="scale(0.697674 0.697674) rotate(0) translate(4 201)">
<title>_anonymous_0</title>
<polygon fill="white" stroke="white" points="-4,5 -4,-201 642,-201 642,5 -4,5"/>
<text text-anchor="middle" x="318.5" y="-8.4" font-family="Sans" font-size="14.00">A Soft Fork: &#160;Blocks Violating New Rules Are Made Stale By The Upgraded Mining Majority</text>
<g id="graph2" class="cluster"><title>cluster_honest</title>
</g>
<g id="graph3" class="cluster"><title>cluster_attack</title>
</g>
<!-- invis1 -->
<g id="node1" class="node"><title>invis1</title>
<text text-anchor="middle" x="48.5" y="-90.4" font-family="Sans" font-size="14.00">Blocks</text>
<text text-anchor="middle" x="48.5" y="-73.4" font-family="Sans" font-size="14.00">From</text>
<text text-anchor="middle" x="48.5" y="-56.4" font-family="Sans" font-size="14.00">Upgraded</text>
<text text-anchor="middle" x="48.5" y="-39.4" font-family="Sans" font-size="14.00">Nodes</text>
</g>
<!-- invis0 -->
<g id="node2" class="node"><title>invis0</title>
<text text-anchor="middle" x="48.5" y="-173.4" font-family="Sans" font-size="14.00">Blocks</text>
<text text-anchor="middle" x="48.5" y="-156.4" font-family="Sans" font-size="14.00">From Non&#45;</text>
<text text-anchor="middle" x="48.5" y="-139.4" font-family="Sans" font-size="14.00">Upgraded</text>
<text text-anchor="middle" x="48.5" y="-122.4" font-family="Sans" font-size="14.00">Nodes</text>
</g>
<!-- block0 -->
<g id="node4" class="node"><title>block0</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="193.5,-181.5 125.5,-181.5 125.5,-122.5 193.5,-122.5 193.5,-181.5"/>
<text text-anchor="middle" x="159.5" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="159.5" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="159.5" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- invis0&#45;&gt;block0 -->
<g id="edge6" class="edge"><title>invis0&#45;&gt;block0</title>
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M93.0084,-152C100.305,-152 107.867,-152 115.16,-152"/>
<polygon fill="black" stroke="black" points="115.236,-155.5 125.236,-152 115.236,-148.5 115.236,-155.5"/>
</g>
<!-- block1 -->
<g id="node5" class="node"><title>block1</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="275.5,-181.5 207.5,-181.5 207.5,-122.5 275.5,-122.5 275.5,-181.5"/>
<text text-anchor="middle" x="241.5" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="241.5" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="241.5" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block0&#45;&gt;block1 -->
<g id="edge8" class="edge"><title>block0&#45;&gt;block1</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M193.8,-152C194.919,-152 196.045,-152 197.175,-152"/>
<polygon fill="black" stroke="black" points="197.337,-155.5 207.337,-152 197.337,-148.5 197.337,-155.5"/>
</g>
<!-- block2_1 -->
<g id="node6" class="node"><title>block2_1</title>
<polygon fill="lightgrey" stroke="black" stroke-width="1.75" points="426.5,-181.5 290.5,-181.5 290.5,-122.5 426.5,-122.5 426.5,-181.5"/>
<text text-anchor="middle" x="358.5" y="-164.9" font-family="Sans" font-size="14.00">Follows Old Rules</text>
<text text-anchor="middle" x="358.5" y="-147.9" font-family="Sans" font-size="14.00">But Violates</text>
<text text-anchor="middle" x="358.5" y="-130.9" font-family="Sans" font-size="14.00">New Rules</text>
</g>
<!-- block1&#45;&gt;block2_1 -->
<g id="edge13" class="edge"><title>block1&#45;&gt;block2_1</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M275.656,-152C276.946,-152 278.255,-152 279.58,-152"/>
<polygon fill="black" stroke="black" points="279.999,-155.5 289.999,-152 279.999,-148.5 279.999,-155.5"/>
</g>
<!-- block2 -->
<g id="node10" class="node"><title>block2</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="403.5,-99.5 313.5,-99.5 313.5,-40.5 403.5,-40.5 403.5,-99.5"/>
<text text-anchor="middle" x="358.5" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="358.5" y="-65.9" font-family="Sans" font-size="14.00">Old &amp; New</text>
<text text-anchor="middle" x="358.5" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block1&#45;&gt;block2 -->
<g id="edge9" class="edge"><title>block1&#45;&gt;block2</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M275.523,-124.375C280.165,-120.81 284.911,-117.267 289.5,-114 294.245,-110.622 299.241,-107.197 304.284,-103.827"/>
<polygon fill="black" stroke="black" points="306.358,-106.652 312.781,-98.2264 302.506,-100.808 306.358,-106.652"/>
</g>
<!-- block4 -->
<g id="node8" class="node"><title>block4</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="617.5,-181.5 549.5,-181.5 549.5,-122.5 617.5,-122.5 617.5,-181.5"/>
<text text-anchor="middle" x="583.5" y="-164.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="583.5" y="-147.9" font-family="Sans" font-size="14.00">Old</text>
<text text-anchor="middle" x="583.5" y="-130.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block2_1&#45;&gt;block4 -->
<!-- block3 -->
<g id="node11" class="node"><title>block3</title>
<polygon fill="none" stroke="black" stroke-width="1.75" points="532.5,-99.5 442.5,-99.5 442.5,-40.5 532.5,-40.5 532.5,-99.5"/>
<text text-anchor="middle" x="487.5" y="-82.9" font-family="Sans" font-size="14.00">Follows</text>
<text text-anchor="middle" x="487.5" y="-65.9" font-family="Sans" font-size="14.00">Old &amp; New</text>
<text text-anchor="middle" x="487.5" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
</g>
<!-- block2&#45;&gt;block3 -->
<g id="edge10" class="edge"><title>block2&#45;&gt;block3</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M404.344,-70C413.183,-70 422.534,-70 431.651,-70"/>
<polygon fill="black" stroke="black" points="431.804,-73.5001 441.804,-70 431.804,-66.5001 431.804,-73.5001"/>
</g>
<!-- block3&#45;&gt;block4 -->
<g id="edge11" class="edge"><title>block3&#45;&gt;block4</title>
<path fill="none" stroke="black" stroke-width="1.75" d="M523.732,-99.0918C529.712,-104.016 535.812,-109.115 541.5,-114 542.321,-114.705 543.148,-115.419 543.981,-116.141"/>
<polygon fill="black" stroke="black" points="541.724,-118.817 551.549,-122.781 546.34,-113.555 541.724,-118.817"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB