diff --git a/_autocrossref.yaml b/_autocrossref.yaml
index a1fe539c..407398c4 100644
--- a/_autocrossref.yaml
+++ b/_autocrossref.yaml
@@ -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:
diff --git a/_includes/guide_block_chain.md b/_includes/guide_block_chain.md
index 12b010a5..1c7d3aa1 100644
--- a/_includes/guide_block_chain.md
+++ b/_includes/guide_block_chain.md
@@ -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.
+
+
+
+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 %}
diff --git a/_includes/references.md b/_includes/references.md
index 1155fdb4..cb9faa75 100644
--- a/_includes/references.md
+++ b/_includes/references.md
@@ -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
diff --git a/img/dev/en-hard-fork.dot b/img/dev/en-hard-fork.dot
new file mode 100644
index 00000000..b485f501
--- /dev/null
+++ b/img/dev/en-hard-fork.dot
@@ -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"
+}
diff --git a/img/dev/en-hard-fork.png b/img/dev/en-hard-fork.png
new file mode 100644
index 00000000..beb3a020
Binary files /dev/null and b/img/dev/en-hard-fork.png differ
diff --git a/img/dev/en-hard-fork.svg b/img/dev/en-hard-fork.svg
new file mode 100644
index 00000000..36a7bb6e
--- /dev/null
+++ b/img/dev/en-hard-fork.svg
@@ -0,0 +1,128 @@
+
+
+
+
+
diff --git a/img/dev/en-soft-fork.dot b/img/dev/en-soft-fork.dot
new file mode 100644
index 00000000..830a4a9d
--- /dev/null
+++ b/img/dev/en-soft-fork.dot
@@ -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"
+}
diff --git a/img/dev/en-soft-fork.png b/img/dev/en-soft-fork.png
new file mode 100644
index 00000000..335c8300
Binary files /dev/null and b/img/dev/en-soft-fork.png differ
diff --git a/img/dev/en-soft-fork.svg b/img/dev/en-soft-fork.svg
new file mode 100644
index 00000000..48bc07f5
--- /dev/null
+++ b/img/dev/en-soft-fork.svg
@@ -0,0 +1,105 @@
+
+
+
+
+