mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-22 16:18:11 +00:00
125 lines
13 KiB
Plaintext
125 lines
13 KiB
Plaintext
[[ch6]]
|
|
== Chapter 6 - The Bitcoin Network
|
|
|
|
*DRAFT - DO NOT SUBMIT ISSUES OR PULL REQUESTS YET PLEASE - CONSTANT CHANGES HAPPENING*
|
|
|
|
=== Introduction
|
|
|
|
=== Peer-to-Peer Network Architecture
|
|
=== Nodes and Roles
|
|
=== Network Discovery
|
|
=== Network Protocol Messages
|
|
|
|
=== Node Types
|
|
|
|
=== Full Node
|
|
|
|
=== Simple Payment Verification Node
|
|
|
|
=== Bloom Filters
|
|
|
|
=== Independently Verifying Transactions
|
|
|
|
In the previous chapter we saw how wallet software creates transactions by collecting UTXO, providing the appropriate unlocking scripts and then constructing new outputs assigned to a new owner. The resulting transaction is then sent to the neighboring nodes in the bitcoin network so that it may be propagated across the entire bitcoin network.
|
|
|
|
Every bitcoin node that receives a transaction will first verify the transaction before forwarding it to its neighbors. This ensures that only valid transactions are propagated across the network, while invalid transactions are discarded at the first node that encounters them.
|
|
|
|
Each node verifies every transaction against a long checklist of criteria:
|
|
|
|
* Check the syntactic correctness of the transaction's data structure
|
|
* Make sure neither lists of inputs or outputs are empty
|
|
* The transaction size in bytes is less than MAX_BLOCK_SIZE
|
|
* Each output value, as well as the total, must be within the allowed range of values (less than 21m coins, more than 0)
|
|
* Check none of the inputs have hash=0, N=-1 (coinbase transactions should not be relayed)
|
|
* Check that nLockTime is less than or equal to INT_MAX
|
|
* Check that the transaction size in bytes is greater than or equal to 100
|
|
* Check the number of signature operations contained in the transaction is less than the signature operation limit
|
|
* Reject "nonstandard" transactions: unlocking script (scriptSig) doing anything other than pushing numbers on the stack, or the locking script (scriptPubkey) not matching isStandard forms
|
|
* Check for a matching transaction in the pool, or in a block in the main branch, if so reject this transaction
|
|
* For each input, if the referenced output exists in any other transaction in the pool, reject this transaction.
|
|
* For each input, look in the main branch and the transaction pool to find the referenced output transaction. If the output transaction is missing for any input, this will be an orphan transaction. Add to the orphan transactions, if a matching transaction is not already in the pool.
|
|
* For each input, if the referenced output transaction is a coinbase output, it must have at least COINBASE_MATURITY (100) confirmations; else reject this transaction
|
|
* For each input, if the referenced output does not exist (e.g. never existed or has already been spent), reject this transaction
|
|
* Using the referenced output transactions to get input values, check that each input value, as well as the sum, are in the allowed range of values (less than 21m coins, more than 0)
|
|
* Reject if the sum of input values < sum of output values
|
|
* Reject if transaction fee would be too low to get into an empty block
|
|
* Verify the unlocking scripts for each input against the corresponding output locking scripts
|
|
|
|
These conditions can be seen in detail in the functions AcceptToMemoryPool, CheckTransaction and CheckInputs in the bitcoin reference client. Note that the conditions change over time, to address new types of Denial-of-Service attacks or sometimes to relax the rules so as to include more types of transactions.
|
|
|
|
By independently verifying each transaction as it is received and before propagating it, every node builds a pool of valid new transactions (the transaction pool), roughly in the same order.
|
|
|
|
[[transaction_pools]]
|
|
=== Transaction Pools
|
|
|
|
Almost every node on the bitcoin network maintains a temporary list of unconfirmed transactions called the memory pool or transaction pool. Once a transaction is verified using the detailed checklist introduced in the section above, it is added to the transaction pool. Nodes use this pool to keep track of transactions that are known to the network but are not yet included in the blockchain. For example, a node that holds a users wallet will use the transaction pool to track incoming payments to the users wallet that have been received on the network but are not yet confirmed. Every node also maintains a separate pool of orphaned transactions as detailed in <<orphan_transactions>>. If a transactions inputs refer to a transaction that is not yet known, a missing parent, then it will be stored temporarily in the orphan pool until the parent transaction arrives. Both the transaction pool and orphan pool are stored in local memory and are not saved on persistent storage, rather they are dynamically populated from incoming network messages. When a node starts, both pools are empty and are gradually populated with new transactions received on the network.
|
|
|
|
As transactions are received and verified using the criteria in the previous section, they are added to the transaction pool and relayed to the neighboring nodes to propagate on the network.
|
|
|
|
When a transaction is added to the transaction pool, the orphan pool is checked for any orphans that reference this transaction's outputs (its children). Any orphans found are pulled from the orphan pool and validated using the above checklist. If valid, they are also added to the transaction pool, completing the chain that started with the parent transaction. In light of the newly added transaction which is no longer an orphan, the process is repeated recursively looking for any further descendants, until no more descendants are found. Through this process, the arrival of a parent transaction triggers a cascade reconstruction of an entire chain of interdependent transactions by re-uniting the orphans with their parents all the way down the chain.
|
|
|
|
Some implementations of the bitcoin client also maintain a UTXO pool which is the set of all unspent outputs on the blockchain. This may be housed in local memory or as an indexed database table on persistent storage. Unlike the transaction and orphan pools, the UTXO pool is not initialized empty but instead contains millions of entries of unspent transaction outputs including some dating back to 2009. Whereas the transaction and orphan pools represent a nodes local perspective and may vary significantly from node to node depending upon when the node was started or restarted, the UTXO pool represents the emergent consensus of the network and therefore will vary little between nodes. Furthermore the transaction and orphan pools only contain unconfirmed transactions, while the UTXO pool only contains confirmed outputs.
|
|
|
|
|
|
[[merkle_trees]]
|
|
=== Merkle Trees
|
|
|
|
As part of populating the block header, a mining node will create a summary of all the transactions added to the block. This summary is created by computing the _root_ of the Merkle Tree, which is a binary hash tree data structure. The merkle root is a 32-byte hash that provides a shortcut to identify individual transactions contained within that block.
|
|
|
|
A _Merkle Tree_, also known as a _Binary Hash Tree_ is a data structure created by Ralph Merkle used for efficiently summarizing and verifying the integrity of large sets of data. Merkle Trees are binary trees containing cryptographic hashes. When N data elements are hashed and summarized in a Merkle Tree, you can check to see if any one data element is included in the tree with at most +2*log~2~(N)+ calculations, making this a very efficient data structure. The term "tree" is used in computer science to describe a branching data structure, but these trees are usually displayed upside down with the "root" at the top and the "leaves" at the bottom of a diagram, as you will see in the examples that follow.
|
|
|
|
Merkle trees are used in bitcoin to summarize all the transactions in a block, producing an overall digital fingerprint of the entire set of transactions, which can be used to prove that a transaction is included in the set. A merkle tree is constructed by recursively hashing pairs of nodes until there is only one hash, called the _root_, or _merkle root_. The cryptographic hash algorithm used in bitcoin's merkle trees is SHA256 applied twice, also known as double-SHA256.
|
|
|
|
The merkle tree is constructed bottom-up. In the example below, we start with four transactions A, B, C and D, which form the _leaves_ of the Merkle Tree, shown in the diagram at the bottom. The transactions are not stored in the merkle tree, rather their data is hashed and the resulting hash is stored in each leaf node as H~A~, H~B~, H~C~ and H~D~:
|
|
|
|
+H~A~ = SHA256(SHA256(Transaction A))+
|
|
|
|
Consecutive pairs of leaf nodes are then summarized in a parent node, by concatenating the two hashes and hashing them together. For example, to construct the parent node H~AB~, the two 32-byte hashes of the children are concatenated to create a 64-byte string. That string is then double-hashed to produce the parent node's hash:
|
|
|
|
+H~AB~ = SHA256(SHA256(H~A~ + H~B~))+
|
|
|
|
The process continues until there is only one node at the top, the node known as the Merkle Root. That 32-byte hash is stored in the block header and summarizes all the data in all four transactions.
|
|
|
|
[[simple_merkle]]
|
|
.Calculating the nodes in a Merkle Tree
|
|
image::images/MerkleTree.png["merkle_tree"]
|
|
|
|
Since the merkle tree is a binary tree, it needs an even number of leaf nodes. If there is an odd number of transactions to summarize, the last transaction hash is duplicated to create an even number of leaf nodes, also known as a _balanced tree_. This is shown in the example below, where transaction C is duplicated:
|
|
|
|
[[merkle_tree_odd]]
|
|
.An even number of data elements, by duplicating one data element
|
|
image::images/MerkleTreeOdd.png["merkle_tree_odd"]
|
|
|
|
The same method for constructing a tree from four transactions can be generalized to construct trees of any size. In bitcoin it is common to have several hundred to more than a thousand transactions in a single block, which are summarized in exactly the same way producing just 32-bytes of data from a single merkle root. In the diagram below, you will see a tree built from 16 transactions:
|
|
|
|
[[merkle_tree_large]]
|
|
.A Merkle Tree summarizing many data elements
|
|
image::images/MerkleTreeLarge.png["merkle_tree_large"]
|
|
|
|
To prove that a specific transaction is included in a block, a node need only produce +log~2~(N)+ 32-byte hashes, constituting an _authentication path_ or _merkle path_ connecting the specific transaction to the root of the tree. This is especially important as the number of transactions increases, because the base-2 logarithm of the number of transactions increases much more slowly. This allows bitcoin nodes to efficiently produce paths of ten or twelve hashes (320-384 bytes) which can provide proof of a single transaction out of more than a thousand transactions in a megabyte sized block. In the example below, a node can prove that a transaction K is included in the block by producing a merkle path that is only four 32-byte hashes long (128 bytes total). The path consists of the four hashes H~L~, H~IJ~, H~MNOP~ and H~ABCDEFGH~. With those four hashes provided as an authentication path, any node can prove that H~K~ is included in the merkle root by computing four additional pair-wise hashes H~KL~, H~IJKL~ and H~IJKLMNOP~ that lead to the merkle root.
|
|
|
|
[[merkle_tree_path]]
|
|
.A Merkle Path used to prove inclusion of a data element
|
|
image::images/MerkleTreePathToK.png["merkle_tree_path"]
|
|
|
|
The efficiency of merkle trees becomes obvious as the scale increases. For example, proving that a transaction is part of a block requires:
|
|
|
|
[[block_structure]]
|
|
.Merkle Tree Efficiency
|
|
[options="header"]
|
|
|=======
|
|
|Number of Transactions| Approx. Size of Block | Path Size (Hashes) | Path Size (Bytes)
|
|
| 16 transactions | 4 kilobytes | 4 hashes | 128 bytes
|
|
| 512 transactions | 128 kilobytes | 9 hashes | 288 bytes
|
|
| 2048 transactions | 512 kilobytes | 11 hashes | 352 bytes
|
|
| 65,535 transactions | 16 megabytes | 16 hashes | 512 bytes
|
|
|=======
|
|
|
|
As you can see from the table above, while the block size increases rapidly, from 4KB with 16 transactions to a block size of 16 MB to fit 65,535 transactions, the merkle path required to prove the inclusion of a transaction increases much more slowly, from 128 bytes to only 512 bytes. With merkle trees, a node can download just the block headers (80 bytes per block) and still be able to identify a transaction's inclusion in a block by retrieving a small merkle path from a full node, without storing or transmitting the vast majority of the blockchain which may be several gigabytes in size. Nodes which do not maintain a full blockchain, called Simple Payment Verification or SPV nodes use merkle paths to verify transactions without downloading full blocks.
|
|
|
|
=== Block Propagation and Verification
|
|
|
|
=== Alert Messages
|
|
|
|
|