mirror of
https://github.com/seigler/dash-docs
synced 2025-07-27 09:46:12 +00:00
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:
parent
2147b830f1
commit
2e8ceb26df
9 changed files with 462 additions and 6 deletions
|
@ -48,6 +48,8 @@ confirmed:
|
|||
confirmation:
|
||||
confirmations:
|
||||
confirmed transactions:
|
||||
consensus:
|
||||
consensus rules:
|
||||
denomination:
|
||||
denominations: denomination
|
||||
DER format: der
|
||||
|
@ -65,8 +67,11 @@ extended keys: extended key
|
|||
extended private key:
|
||||
extended public key:
|
||||
fiat:
|
||||
fork: accidental fork
|
||||
fork:
|
||||
forks: fork
|
||||
genesis block:
|
||||
hard fork:
|
||||
hard forks: hard fork
|
||||
hardened extended private key:
|
||||
HD protocol:
|
||||
header nonce:
|
||||
|
@ -184,6 +189,8 @@ signature hash:
|
|||
signature script:
|
||||
signature scripts: signature script
|
||||
signatures: signature
|
||||
soft fork:
|
||||
soft forks: soft fork
|
||||
SPV:
|
||||
stack:
|
||||
stale block:
|
||||
|
@ -217,10 +224,14 @@ wallet import format:
|
|||
x.509: x509
|
||||
X509Certificates:
|
||||
|
||||
## BIPS in numerical order; don't use padding zeros (e.g. BIP70 not BIP0070)
|
||||
## BIPs in numerical order; don't use padding zeros (e.g. BIP70 not BIP0070)
|
||||
BIP16:
|
||||
BIP21:
|
||||
BIP30:
|
||||
BIP32:
|
||||
BIP34:
|
||||
BIP39:
|
||||
BIP50:
|
||||
BIP70:
|
||||
BIP71:
|
||||
BIP72:
|
||||
|
|
|
@ -4,8 +4,15 @@
|
|||
|
||||
The block chain provides Bitcoin's public ledger, an ordered and timestamped record
|
||||
of transactions. This system is used to protect against double spending
|
||||
and modification of previous transaction records, using proof of
|
||||
work verified by the peer-to-peer network to maintain a global consensus.
|
||||
and modification of previous transaction records.
|
||||
|
||||
Each full node in the Bitcoin network independently stores a block chain
|
||||
containing only blocks validated by that node. When several nodes all
|
||||
have the same blocks in their block chain, they are considered to be in
|
||||
[consensus][]{:#term-consensus}{:.term}. The validation rules these
|
||||
nodes follow to maintain consensus are called [consensus
|
||||
rules][]{:#term-consensus-rules}{:.term}. This section describes many of
|
||||
the consensus rules used by Bitcoin Core.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
@ -148,7 +155,7 @@ block 2016 is where difficulty could have first been adjusted.
|
|||
|
||||
Multiple blocks can all have the same block height, as is common when
|
||||
two or more miners each produce a block at roughly the same time. This
|
||||
creates an apparent [fork][accidental fork]{:#term-accidental-fork}{:.term} in the block chain, as shown in the
|
||||
creates an apparent [fork][]{:#term-fork}{:.term} in the block chain, as shown in the
|
||||
illustration above.
|
||||
|
||||
When miners produce simultaneous blocks at the end of the block chain, each
|
||||
|
@ -244,3 +251,104 @@ Since it is impractical to have separate transactions with identical txids, this
|
|||
otherwise, a valid block with the duplicates eliminated could have the same merkle root and block hash, but be rejected by the cached invalid outcome, resulting in security bugs such as CVE-2012-2459.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Consensus Rule Changes
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
To maintain consensus, all full nodes validate blocks using the same
|
||||
consensus rules. However, sometimes the consensus rules are changed to
|
||||
introduce new features or prevent network abuse. When the new rules are
|
||||
implemented, there will likely be a period of time when non-upgraded
|
||||
nodes follow the old rules and upgraded nodes follow the new rules,
|
||||
creating two possible ways consensus can break:
|
||||
|
||||
1. A block following the new consensus rules is accepted by upgraded
|
||||
nodes but rejected by non-upgraded nodes. For example, a new
|
||||
transaction feature is used within a block: upgraded nodes understand
|
||||
the feature and accept it, but non-upgraded nodes reject it because
|
||||
it violates the old rules.
|
||||
|
||||
2. A block violating the new consensus rules is rejected by upgraded
|
||||
nodes but accepted by non-upgraded nodes. For example, an abusive
|
||||
transaction feature is used within a block: upgraded nodes reject it
|
||||
because it violates the new rules, but non-upgraded nodes accept it
|
||||
because it follows the old rules.
|
||||
|
||||
In the first case, rejection by non-upgraded nodes, mining software
|
||||
which gets block chain data from those non-upgraded nodes refuses to
|
||||
build on the same chain as mining software getting data from upgraded
|
||||
nodes. This creates permanently divergent chains---one for non-upgraded
|
||||
nodes and one for upgraded nodes---called a [hard
|
||||
fork][]{:#term-hard-fork}{:.term}.
|
||||
|
||||

|
||||
|
||||
In the second case, rejection by upgraded nodes, it's possible to keep
|
||||
the block chain from permanently diverging if upgraded nodes control a
|
||||
majority of the hash rate. That's because, in this case, non-upgraded
|
||||
nodes will accept as valid all the same blocks as upgraded nodes, so the
|
||||
upgraded nodes can build a stronger chain that the non-upgraded nodes
|
||||
will accept as the best valid block chain. This is called a [soft
|
||||
fork][]{:#term-soft-fork}{:.term}.
|
||||
|
||||

|
||||
|
||||
Although a fork is an actual divergence in block chains, changes to the
|
||||
consensus rules are often described by their potential to create either
|
||||
a hard or soft fork. For example, "increasing the block size above 1 MB
|
||||
requires a hard fork." In this example, an actual block chain fork is
|
||||
not required---but it is a possible outcome.
|
||||
|
||||
**Resources:** [BIP16][], [BIP30][], and [BIP34][] were implemented as
|
||||
changes which might have lead to soft forks. [BIP50][] describes both an
|
||||
accidental hard fork, resolved by temporary downgrading the capabilities
|
||||
of upgraded nodes, and an intentional hard fork when the temporary
|
||||
downgrade was removed. A document from Gavin Andresen outlines [how
|
||||
future rule changes may be
|
||||
implemented](https://gist.github.com/gavinandresen/2355445).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Detecting Forks
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Non-upgraded nodes may use and distribute incorrect information during
|
||||
both types of forks, creating several situations which could lead to
|
||||
financial loss. In particular, non-upgraded nodes may relay and accept
|
||||
transactions that are considered invalid by upgraded nodes and so will
|
||||
never become part of the universally-recognized best block chain.
|
||||
Non-upgraded nodes may also refuse to relay blocks or transactions which
|
||||
have already been added to the best block chain, or soon will be, and so
|
||||
provide incomplete information.
|
||||
|
||||
<!-- paragraph below based on src/main.cpp CheckForkWarningConditions() -->
|
||||
|
||||
Bitcoin Core includes code that detects a hard fork by looking at block
|
||||
chain proof of work. If a node receives block chain headers
|
||||
demonstrating six blocks more proof of work than the best chain this
|
||||
node considers valid, the node reports an error in the `getinfo` RPC
|
||||
results and runs the `-alertnotify` command if set.
|
||||
|
||||
Full nodes can also check block and transaction version numbers. If the
|
||||
block or transaction version numbers seen in several recent blocks are
|
||||
higher than the version numbers the node uses, it can assume it doesn't
|
||||
use the current consensus rules. Future versions of Bitcoin Core
|
||||
(>0.9.3) will likely report this situation through the `getinfo` RPC and
|
||||
`-alertnotify` command if set.
|
||||
|
||||
In either case, data should not be relied upon if it comes from a node
|
||||
that apparently isn't using the current consensus rules.
|
||||
|
||||
SPV clients which connect to full nodes can detect a likely hard fork by
|
||||
connecting to several full nodes and ensuring that they're all on the
|
||||
same chain with the same block height, plus or minus several blocks to
|
||||
account for transmission delays and stale blocks. If there's a
|
||||
divergence, the client can disconnect from nodes with weaker chains.
|
||||
|
||||
SPV clients should also monitor for block and transaction version number
|
||||
increases to ensure they process received transactions and create new
|
||||
transactions using the current consensus rules.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
[51 percent attack]: /en/developer-guide#term-51-attack "The ability of someone controlling a majority of hashing power to revise transactions history and prevent new transactions from confirming"
|
||||
[accidental fork]: /en/developer-guide#term-accidental-fork "When two or more blocks have the same block height, forking the block chain. Happens occasionally by accident"
|
||||
[addresses]: /en/developer-guide#term-address "A 20-byte hash formatted as a P2PKH or P2SH Bitcoin Address"
|
||||
[address]: /en/developer-guide#term-address "A 20-byte hash formatted as a P2PKH or P2SH Bitcoin Address"
|
||||
[base58Check]: /en/developer-reference#term-base58check "The method used in Bitcoin for converting 160-bit hashes into Bitcoin addresses"
|
||||
|
@ -30,6 +29,8 @@
|
|||
[confirmed transactions]: /en/developer-guide#term-confirmation "Transactions included in a block currently on the block chain"
|
||||
[confirmation]: /en/developer-guide#term-confirmation "The number of blocks which would need to be modified to remove or modify a transaction"
|
||||
[confirmations]: /en/developer-guide#term-confirmation "The number of blocks which would need to be modified to remove or modify a transaction"
|
||||
[consensus]: /en/developer-guide#term-consensus "When several nodes (usually most nodes on the network) all have the same blocks in their locally-validated block chain."
|
||||
[consensus rules]: /en/developer-guide#term-consensus-rules "The block validation rules that full nodes follow to stay in consensus with other nodes."
|
||||
[denomination]: /en/developer-guide#term-denomination "bitcoins (BTC), bitcents (cBTC), millibits (mBTC), microbits (uBTC), or satoshis"
|
||||
[difficulty]: /en/developer-guide#term-difficulty "A number corresponding to the target threshold which indicates how difficult it will be to find the next block"
|
||||
[double spend]: /en/developer-guide#term-double-spend "Attempting to spend the same satoshis which were spent in a previous transaction"
|
||||
|
@ -38,7 +39,9 @@
|
|||
[extended public key]: /en/developer-guide#term-extended-public-key "A public key extended with the chain code so that it can derive child public keys"
|
||||
[escrow contract]: /en/developer-guide#term-escrow-contract "A contract in which the spender and receiver store satoshis in a multisig output until both parties agree to release the satoshis"
|
||||
[fiat]: /en/developer-guide#term-fiat "National currencies such as the dollar or euro"
|
||||
[fork]: /en/developer-guide#term-fork "When two or more blocks have the same block height, forking the block chain."
|
||||
[genesis block]: /en/developer-guide#term-genesis-block "The first block created; also called block 0"
|
||||
[hard fork]: /en/developer-guide#term-hard-fork "A permanent divergence in the the block chain, commonly occurs when non-upgraded nodes can't validate blocks created by upgraded nodes following newer consensus rules."
|
||||
[hardened extended private key]: /en/developer-guide#term-hardened-extended-private-key "A private key whose corresponding public key cannot derive child keys"
|
||||
[HD protocol]: /en/developer-guide#term-hd-protocol "The Hierarchical Deterministic (HD) key creation and transfer protocol"
|
||||
[header nonce]: /en/developer-reference#term-header-nonce "Four bytes of arbitrary data in a block header used to let miners create headers with different hashes for proof of work"
|
||||
|
@ -132,6 +135,7 @@
|
|||
[signature]: /en/developer-guide#term-signature "The result of combining a private key and some data in an ECDSA signature operation which allows anyone with the corresponding public key to verify the signature"
|
||||
[signature hash]: /en/developer-guide#term-signature-hash "A byte appended onto signatures generated in Bitcoin which allows the signer to specify what data was signed, allowing modification of the unsigned data"
|
||||
[signature script]: /en/developer-guide#term-signature-script "Data generated by a spender which is almost always used as variables to satisfy a pubkey script"
|
||||
[soft fork]: /en/developer-guide#term-soft-fork "A temporary fork in the block chain which commonly occurs when miners using non-upgraded nodes violate a new consensus rule their nodes don't know about."
|
||||
[spv]: /en/developer-guide#simplified-payment-verification-spv "A method for verifying particular transactions were included in blocks without downloading the entire contents of the block chain"
|
||||
[ssl signature]: /en/developer-examples#term-ssl-signature "Signatures created and recognized by major SSL implementations such as OpenSSL"
|
||||
[stack]: /en/developer-guide#term-stack "An evaluation stack used in Bitcoin's script language"
|
||||
|
@ -160,9 +164,13 @@
|
|||
[X509Certificates]: /en/developer-examples#term-x509certificates
|
||||
|
||||
[BFGMiner]: https://github.com/luke-jr/bfgminer
|
||||
[BIP16]: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
||||
[BIP21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
|
||||
[BIP30]: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
|
||||
[BIP32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
[BIP34]: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
|
||||
[BIP39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
[BIP50]: https://github.com/bitcoin/bips/blob/master/bip-0050.mediawiki
|
||||
[BIP70]: https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki
|
||||
[BIP71]: https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki
|
||||
[BIP72]: https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki
|
||||
|
|
49
img/dev/en-hard-fork.dot
Normal file
49
img/dev/en-hard-fork.dot
Normal 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
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
128
img/dev/en-hard-fork.svg
Normal 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:  Non-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-</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->block0 -->
|
||||
<g id="edge4" class="edge"><title>invis0->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->block1 -->
|
||||
<g id="edge8" class="edge"><title>block0->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->block2_1 -->
|
||||
<g id="edge14" class="edge"><title>block1->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->block2 -->
|
||||
<g id="edge9" class="edge"><title>block1->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->block3_1 -->
|
||||
<g id="edge6" class="edge"><title>block2_1->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->block3 -->
|
||||
<g id="edge10" class="edge"><title>block2->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->block4 -->
|
||||
<g id="edge11" class="edge"><title>block3->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->block5 -->
|
||||
<g id="edge12" class="edge"><title>block4->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
47
img/dev/en-soft-fork.dot
Normal 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
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
105
img/dev/en-soft-fork.svg
Normal 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:  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-</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->block0 -->
|
||||
<g id="edge6" class="edge"><title>invis0->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->block1 -->
|
||||
<g id="edge8" class="edge"><title>block0->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->block2_1 -->
|
||||
<g id="edge13" class="edge"><title>block1->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 & New</text>
|
||||
<text text-anchor="middle" x="358.5" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
|
||||
</g>
|
||||
<!-- block1->block2 -->
|
||||
<g id="edge9" class="edge"><title>block1->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->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 & New</text>
|
||||
<text text-anchor="middle" x="487.5" y="-48.9" font-family="Sans" font-size="14.00">Rules</text>
|
||||
</g>
|
||||
<!-- block2->block3 -->
|
||||
<g id="edge10" class="edge"><title>block2->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->block4 -->
|
||||
<g id="edge11" class="edge"><title>block3->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 |
Loading…
Add table
Add a link
Reference in a new issue