From 1634212dd5550bb9b610341668b4b7b5fa3690a5 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Tue, 28 Oct 2014 14:28:14 -0400 Subject: [PATCH 1/4] Dev Docs: Add P2P Messages That Request Or Reply With Data Adds to the devel reference page detailed documentation on the following messages: block, getblocks, getdata, getheaders, headers, inv, mempool, merkleblock, notfound, and tx. Adds to the devel examples page an example of requesting and parsing a merkleblock message. Adds to the devel docs overview pages links to the above two new P2P sections. Tweaks the autocrossref plugin ignore pattern to not crossref in the middle of a GIF image name; this allows the inclusion of animated GIFs. --- _autocrossref.yaml | 32 +- _includes/example_p2p_networking.md | 212 +++++++ _includes/ref_p2p_networking.md | 564 ++++++++++++++++++ _includes/references.md | 44 +- _plugins/autocrossref.rb | 4 +- en/developer-documentation.md | 2 + en/developer-examples.md | 2 + en/developer-reference.md | 2 + img/dev/animated-en-merkleblock-creation.gif | Bin 0 -> 16316 bytes img/dev/animated-en-merkleblock-parsing.gif | Bin 0 -> 14866 bytes img/dev/en-p2p-data-messages.dot | 36 ++ img/dev/en-p2p-data-messages.png | Bin 0 -> 7637 bytes img/dev/en-p2p-data-messages.svg | 118 ++++ img/dev/gifs/README.md | 31 + .../en-merkleblock-creation-001.dot | 148 +++++ .../en-merkleblock-creation-002.dot | 148 +++++ .../en-merkleblock-creation-003.dot | 148 +++++ .../en-merkleblock-creation-004.dot | 148 +++++ .../en-merkleblock-creation-005.dot | 148 +++++ .../en-merkleblock-creation-006.dot | 148 +++++ .../en-merkleblock-creation-007.dot | 148 +++++ .../en-merkleblock-creation-008.dot | 148 +++++ .../en-merkleblock-creation-009.dot | 148 +++++ .../en-merkleblock-creation-010.dot | 148 +++++ .../en-merkleblock-creation-011.dot | 148 +++++ .../en-merkleblock-creation-012.dot | 148 +++++ .../en-merkleblock-parsing-001.dot | 138 +++++ .../en-merkleblock-parsing-001.png | Bin 0 -> 5951 bytes .../en-merkleblock-parsing-001.svg | 288 +++++++++ .../en-merkleblock-parsing-002.dot | 140 +++++ .../en-merkleblock-parsing-002.png | Bin 0 -> 6043 bytes .../en-merkleblock-parsing-002.svg | 291 +++++++++ .../en-merkleblock-parsing-003.dot | 141 +++++ .../en-merkleblock-parsing-003.png | Bin 0 -> 6347 bytes .../en-merkleblock-parsing-003.svg | 299 ++++++++++ .../en-merkleblock-parsing-004.dot | 142 +++++ .../en-merkleblock-parsing-004.png | Bin 0 -> 6323 bytes .../en-merkleblock-parsing-004.svg | 294 +++++++++ .../en-merkleblock-parsing-005.dot | 140 +++++ .../en-merkleblock-parsing-005.png | Bin 0 -> 6343 bytes .../en-merkleblock-parsing-005.svg | 293 +++++++++ .../en-merkleblock-parsing-006.dot | 140 +++++ .../en-merkleblock-parsing-006.png | Bin 0 -> 6657 bytes .../en-merkleblock-parsing-006.svg | 301 ++++++++++ .../en-merkleblock-parsing-007.dot | 140 +++++ .../en-merkleblock-parsing-007.png | Bin 0 -> 6919 bytes .../en-merkleblock-parsing-007.svg | 304 ++++++++++ .../en-merkleblock-parsing-008.dot | 140 +++++ .../en-merkleblock-parsing-008.png | Bin 0 -> 6913 bytes .../en-merkleblock-parsing-008.svg | 301 ++++++++++ .../en-merkleblock-parsing-009.dot | 141 +++++ .../en-merkleblock-parsing-009.png | Bin 0 -> 7329 bytes .../en-merkleblock-parsing-009.svg | 312 ++++++++++ .../en-merkleblock-parsing-010.dot | 141 +++++ .../en-merkleblock-parsing-011.dot | 141 +++++ .../en-merkleblock-parsing-011.png | Bin 0 -> 7290 bytes .../en-merkleblock-parsing-011.svg | 308 ++++++++++ 57 files changed, 7352 insertions(+), 6 deletions(-) create mode 100644 _includes/example_p2p_networking.md create mode 100644 _includes/ref_p2p_networking.md create mode 100644 img/dev/animated-en-merkleblock-creation.gif create mode 100644 img/dev/animated-en-merkleblock-parsing.gif create mode 100644 img/dev/en-p2p-data-messages.dot create mode 100644 img/dev/en-p2p-data-messages.png create mode 100644 img/dev/en-p2p-data-messages.svg create mode 100644 img/dev/gifs/README.md create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-001.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-002.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-003.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-004.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-005.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-006.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-007.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-008.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-009.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-010.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-011.dot create mode 100644 img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-012.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.svg create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-010.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.dot create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.png create mode 100644 img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.svg diff --git a/_autocrossref.yaml b/_autocrossref.yaml index db8a0553..8c383bec 100644 --- a/_autocrossref.yaml +++ b/_autocrossref.yaml @@ -24,6 +24,7 @@ block chain: block-chain: block chain block header: block height: +'`block` message': block message block reward: block time: block version: @@ -79,11 +80,15 @@ extended public key: fiat: fork: forks: fork +'`getblocks` message': getblocks message +'`getdata` message': getdata message +'`getheaders` message': getheaders message genesis block: hard fork: hard forks: hard fork hardened extended private key: HD protocol: +'`headers` message': headers message high-priority transaction: high-priority transactions high-priority transactions: inputs: input @@ -91,8 +96,11 @@ input: intermediate certificate: intermediate certificates: intermediate certificate internal byte order: +'`inv` message': inv message IP address: DO NOT AUTOCROSSREF IP addresses: DO NOT AUTOCROSSREF +inventories: inventory +inventory: key index: key pair: '`label`': label @@ -105,8 +113,13 @@ man-in-the-middle: master chain code: master private key: '`memo`': pp memo +'`mempool` message': mempool message '`message`': message +message header: +message payload: '`merchant_data`': pp merchant data +merkleblock: merkleblock message +'`merkleblock` message': merkleblock message merkle root: merkle tree: merge: @@ -120,9 +133,13 @@ minimum fee: mining: mine millibitcoin: millibitcoins millibitcoins: +'`MSG_BLOCK`': msg_block +'`MSG_FILTERED_BLOCK`': msg_filtered_block +'`MSG_TX`': msg_tx multisig: nbits: network: +'`notfound` message': notfound message null data: '`op_checkmultisig`': op_checkmultisig '`op_checksig`': op_checksig @@ -152,6 +169,7 @@ PaymentRequest: PaymentRequests: paymentrequest peer: peers: peer +peer-to-peer: network peer-to-peer network: network pki: '`pki_type`': pp pki type @@ -162,6 +180,11 @@ proof of work: proof-of-work: proof of work protocol buffer: protobuf protocol buffers: protobuf +protocol version 60000: section protocol versions +protocol version 60001: section protocol versions +protocol version 60002: section protocol versions +protocol version 70001: section protocol versions +protocol version 70002: section protocol versions pubkey: public key pubkey hash: pubkey hashes: pubkey hash @@ -218,6 +241,7 @@ standard script: standard scripts: standard script standard transaction: standard script standard transactions: standard script +start string: target: testnet: #transaction -- Recommend we don't autocrossref this; it occurs too often @@ -227,6 +251,7 @@ transaction malleability: transaction object format: transaction version number: '`transactions`': pp transactions +'`tx` message': tx message txid: txids: txid unconfirmed: @@ -337,5 +362,10 @@ CVE-2012-2459: '`walletpassphrase`': rpc walletpassphrase '`walletpassphrasechange`': rpc walletpassphrasechange -Bitcoin Core 0.9.3: +## Versions of Bitcoin Core (linked to Bitcoin.org release notes) +Bitcoin Core 0.6.0: +Bitcoin Core 0.6.1: Bitcoin Core 0.7.0: +Bitcoin Core 0.8.0: +Bitcoin Core 0.9.0: +Bitcoin Core 0.9.3: diff --git a/_includes/example_p2p_networking.md b/_includes/example_p2p_networking.md new file mode 100644 index 00000000..e1792447 --- /dev/null +++ b/_includes/example_p2p_networking.md @@ -0,0 +1,212 @@ +## P2P Network + +### Retrieving A MerkleBlock + +{% autocrossref %} + +For the `merkleblock` message documentation on the reference page, an +actual merkleblock was retrieved from the network and manually +processed. This section walks through each step of the process, +demonstrating basic network communication and merkleblock processing. + +{% highlight python %} + +#!/usr/bin/env python + +from time import sleep +from hashlib import sha256 +import struct +import sys + +network_string = "f9beb4d9".decode("hex") # Mainnet + +def send(msg,payload): + ## Command is ASCII text, null padded to 12 bytes + command = msg + ( ( 12 - len(msg) ) * "\00" ) + + ## Payload length is a uint32_t + payload_raw = payload.decode("hex") + payload_len = struct.pack("I", len(payload_raw)) + + ## Checksum is first 4 bytes of SHA256(SHA256()) + checksum = sha256(sha256(payload_raw).digest()).digest()[:4] + + sys.stdout.write( + network_string + + command + + payload_len + + checksum + + payload_raw + ) + sys.stdout.flush() +{% endhighlight %} + +To connect to the P2P network, the trivial Python function above was +developed to compute message headers and send payloads decoded from hex. + +{% highlight python %} +## Create a version message +send("version", + "71110100" # ........................ Protocol Version: 70001 + + "0000000000000000" # ................ Services: Headers Only (SPV) + + "c6925e5400000000" # ................ Time: 1415484102 + + "00000000000000000000000000000000" + + "0000ffff7f000001208d" # ............ Receiver IP Address/Port + + "00000000000000000000000000000000" + + "0000ffff7f000001208d" # ............ Sender IP Address/Port + + "0000000000000000" # ................ Nonce (not used here) + + "1b" # .............................. Bytes in version string + + "2f426974636f696e2e6f726720457861" + + "6d706c653a302e392e332f" # .......... Version string + + "93050500" # ........................ Starting block height: 329107 + + "00" # .............................. Relay transactions: false +) +{% endhighlight %} + +Peers on the network will not accept any requests until you send them a +`version` message. The receiving node will reply with their `version` +message and a `verack` message. + +{% highlight python %} +sleep(1) +send("verack", "") +{% endhighlight %} + +We're not going to validate their `version` message with this simple +script, but we will sleep a short bit and send back our own `verack` +message as if we had accepted their `version` message. + +{% highlight python %} +send("filterload", "02b50f0b0000000000000000") +{% endhighlight %} + +We set a bloom filter with the `filterload` message. This filter was +quickly created using [python-bitcoinlib][]'s bloom module. + +{% highlight python %} +send("getdata", + "01" # ................................. Number of inventories: 1 + + "03000000" # ........................... Inventory type: filtered block + + "a4deb66c0d726b0aefb03ed51be407fb" + + "ad7331c6e8f9eef231b7000000000000" # ... Block header hash +) +{% endhighlight %} + +We request a merkleblock for transactions matching our filter, +completing our script. + +To run the script, we simply pipe it to the Unix [`netcat` +command][netcat] or one of its many clones, one of which is available +for practically any platform. For example, with the original netcat and +using hexdump (`hd`) to display the output: + +{% highlight bash %} +## Connect to the Bitcoin Core peer running on localhost +python get-merkle.py | nc localhost 8333 | hd +{% endhighlight %} + +Part of the response is shown in the section below. + +{% endautocrossref %} + +### Parsing A MerkleBlock + +{% autocrossref %} + +In the section above, we retrieved a merkleblock from the network; now +we will parse it. Most of the block header has been omitted. For +a more complete hexdump, see the example in the [`merkleblock` message +section][merkleblock message]. + +{% highlight text %} +7f16c5962e8bd963659c793ce370d95f +093bc7e367117b3c30c1f8fdd0d97287 ... Merkle root + +07000000 ........................... Transaction count: 7 +04 ................................. Hash count: 4 + +3612262624047ee87660be1a707519a4 +43b1c1ce3d248cbfc6c15870f6c5daa2 ... Hash #1 +019f5b01d4195ecbc9398fbf3c3b1fa9 +bb3183301d7a1fb3bd174fcfa40a2b65 ... Hash #2 +41ed70551dd7e841883ab8f0b16bf041 +76b7d1480e4f0af9f3d4c3595768d068 ... Hash #3 +20d2a7bc994987302e5b1ac80fc425fe +25f8b63169ea78e68fbaaefa59379bbf ... Hash #4 + +01 ................................. Flag bytes: 1 +1d ................................. Flags: 1 0 1 1 1 0 0 0 +{% endhighlight %} + +We parse the above `merkleblock` message using the following +instructions. Each illustration is described in the paragraph below it. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.svg) + +We start by building the structure of a merkle tree based on the number +of transactions in the block. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.svg) + +The first flag is a 1 and the merkle root is (as always) a non-TXID +node, so we will need to compute the hash later based on this node's +children. Accordingly, we descend into the merkle root's left child and +look at the next flag for instructions. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.svg) + +The next flag in the example is a 0 and this is also a non-TXID node, so +we apply the first hash from the `merkleblock` message to this node. We +also don't process any child nodes---according to the peer which created +the `merkleblock` message, none of those nodes will lead to TXIDs of +transactions that match our filter, so we don't need them. We go back up +to the merkle root and then descend into its right child and look at the +next (third) flag for instructions. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.svg) + +The third flag in the example is another 1 on another non-TXID node, so +we descend into its left child. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.svg) + +The fourth flag is also a 1 on another non-TXID node, so we descend +again---we will always continue descending until we reach a TXID node or +a non-TXID node with a 0 flag (or we finish filling out the tree). + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.svg) + +Finally, on the fifth flag in the example (a 1), we reach a TXID node. +The 1 flag indicates this TXID's transaction matches our filter and +that we should take the next (second) hash and use it as this node's +TXID. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.svg) + +The sixth flag also applies to a TXID, but it's a 0 flag, so this +TXID's transaction doesn't match our filter; still, we take the next +(third) hash and use it as this node's TXID. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.svg) + +We now have enough information to compute the hash for the fourth node +we encountered---it's the hash of the concatenated hashes of the two +TXIDs we filled out. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.svg) + +Moving to the right child of the third node we encountered, we fill it +out using the seventh flag and final hash---and discover there are no +more child nodes to process. + +![Parsing A MerkleBlock](/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.svg) + +We hash as appropriate to fill out the tree. Note that the eighth flag is +not used---this is acceptable as it was required to pad out a flag byte. + +The final steps would be to ensure the computed computed merkle root +is identical to the merkle root in the header and check the other steps +of the parsing checklist in the `merkleblock` message section. + +{% endautocrossref %} diff --git a/_includes/ref_p2p_networking.md b/_includes/ref_p2p_networking.md new file mode 100644 index 00000000..006ba3a0 --- /dev/null +++ b/_includes/ref_p2p_networking.md @@ -0,0 +1,564 @@ +## P2P Network + +{% autocrossref %} + +This section describes the Bitcoin P2P network protocol (but it is not a +specification). It does not describe the discontinued direct [IP-to-IP +payment protocol][], the [BIP70 payment protocol][payment protocol], the +[GetBlockTemplate mining protocol][section getblocktemplate], or any +network protocol never implemented in an official version of Bitcoin Core. + +All peer-to-peer communication occurs entirely over TCP. + +**Note:** unless their description says otherwise, all multi-byte +integers mentioned in this section are transmitted in little-endian order. + +{% endautocrossref %} + +### Constants And Defaults + +{% autocrossref %} + +The following constants and defaults are taken from Bitcoin Core's +[chainparams.cpp][core chainparams.cpp] source code file. + +| Network | Default Port | [Start String][]{:#term-start-string}{:.term} | Max nBits +|---------|--------------|-----------------------------------------------|--------------- +| Mainnet | 8333 | 0xf9beb4d9 | 0x1d00ffff +| Testnet | 18333 | 0x0b110907 | 0x1d00ffff +| Regtest | 18444 | 0xfabfb5da | 0x207fffff + +Note: the testnet start string and nBits above are for testnet3; the +original testnet used a different string and higher (less difficult) +nBits. + +Command line parameters can change what port a node listens on (see +`-help`). Start strings are hardcoded constants that appear at the start +of all messages sent on the Bitcoin network; they may also appear in +data files such as Bitcoin Core's block database. The nBits displayed +above are in big-endian order; they're sent over the network in +little-endian order. + +Bitcoin Core's [chainparams.cpp][core chainparams.cpp] also includes +other constants useful to programs, such as the hash of the genesis +blocks for the different networks as well as the alert keys for mainnet +and testnet. + +{% endautocrossref %} + +### Protocol Versions + +{% autocrossref %} + +The table below lists some notable versions of the P2P network protocol, +with the most recent versions listed first. (If you would like to help +document older protocol versions, please [open an issue][docs issue].) + +| Version | Implementation | Major Changes +|---------|-------------------------------------|-------------- +| 70002 | Bitcoin Core 0.9.0 (March 2014) | Added `reject` message (see [BIP61][]). Send multiple `inv` messages in response to `mempool` message if necessary. +| 70001 | Bitcoin Core 0.8.0 (February 2013) | Added `filterload` message, `filteradd` message, `filterclear` message, and `merkleblock` message; also added relay field to `version` message and `MSG_FILTERED_BLOCK` inventory type to `getdata` message (see [BIP37][]). +| 60002 | Bitcoin Core 0.7.0 (September 2012) | Added `mempool` message and extended `getdata` message to allow download of memory pool transactions (see [BIP35][]). +| 60001 | Bitcoin Core 0.6.1 (May 2012) | Added `pong` message (see [BIP31][]). +| 60000 | Bitcoin Core 0.6.0 (March 2012) | Separated protocol version from Bitcoin Core version (see [BIP14][]). + +{% endautocrossref %} + +### Message Headers + +{% autocrossref %} + +All messages in the network protocol use the same container format, +which provides a required multi-field header and an optional payload. +The header format is: + +| Bytes | Name | Data Type | Description +|-------|--------------|-----------|------------- +| 4 | start string | char[4] | Magic bytes indicating the originating network; used to seek to next message when stream state is unknown. +| 12 | command name | char[12] | ASCII string which identifies what message type is contained in the payload. Followed by nulls (0x00) to pad out byte count; for example: `version\0\0\0\0\0`. +| 4 | payload size | uint32_t | Number of bytes in payload. The current maximum number of bytes ([`MAX_SIZE`][max_size]) allowed in the payload by Bitcoin Core is 32 MiB---messages with a payload size larger than this will be dropped or rejected. +| 4 | checksum | char[4] | First 4 bytes of SHA256(SHA256(payload)) in internal byte order.

If payload is empty, as in `verack` and `getaddr` messages, the checksum is always 0x5df6e0e2 (SHA256(SHA256(\))).

*The checksum field was introduced in protocol version 209; Bitcoin Core 0.2.9, May 2010.* + +The following example is an annotated hex dump of a mainnet message +header from a `verack` message which has no payload. + +{% highlight text %} +f9beb4d9 ................... Start string: Mainnet +76657261636b000000000000 ... Command name: verack + null padding +00000000 ................... Byte count: 0 +5df6e0e2 ................... Checksum: SHA256(SHA256()) +{% endhighlight %} + +{% endautocrossref %} + +### Data Messages + +{% autocrossref %} + +The following network messages all request or provide data related to +transactions and blocks. + +![Overview Of P2P Protocol Data Request And Reply Messages](/img/dev/en-p2p-data-messages.svg) + +Many of the data messages use +[inventories][inventory]{:#term-inventory}{:.term} as unique identifiers for +for transactions and blocks. Inventories have a simple 36-byte +structure: + +| Bytes | Name | Data Type | Description +|-------|-----------------|-----------|------------- +| 4 | type identifier | uint32_t | The type of object which was hashed. See list of type identifiers below. +| 32 | hash | char[32] | SHA256(SHA256()) hash of the object in internal byte order. + +The currently-available type identifiers are: + +| Type Identifier | Name | Description +|-----------------|-------------------------------------------------------------------------------|--------------- +| 1 | [`MSG_TX`][msg_tx]{:#term-msg_tx}{:.term} | The hash is a TXID. +| 2 | [`MSG_BLOCK`][msg_block]{:#term-msg_block}{:.term} | The hash is of a block header. +| 3 | [`MSG_FILTERED_BLOCK`][msg_filtered_block]{:#term-msg_filtered_block}{:.term} | The hash is of a block header; identical to `MSG_BLOCK`. When used in a `getdata` message, this indicates the response should be a `merkleblock` message rather than a `block` message (but this only works if a bloom filter was previously configured). **Only for use in `getdata` messages.** + +Type identifier zero and type identifiers greater than three are reserved +for future implementations. Bitcoin Core ignores all inventories with +one of these unknown types. + +{% endautocrossref %} + +#### Block + +{% autocrossref %} + +The `block` message transmits a single serialized block in the format +described in the [serialized blocks section][section serialized blocks]. +See that section for an example hexdump. + +It is sent in reply to a `getdata` message which had an inventory type of +`MSG_BLOCK` and the header hash of the particular block being requested. + +{% endautocrossref %} + +#### GetBlocks + +{% autocrossref %} + +The `getblocks` message requests an `inv` message that provides block +header hashes starting from a particular point in the block chain. It +allows a peer which has been disconnected or started for the first time +to get the data it needs to request the blocks it hasn't seen. + +Peers which have been disconnected may have stale blocks in their +locally-stored block chain, so the `getblocks` message allows the +requesting peer to provide the receiving peer with multiple header +hashes at various heights on their local chain. This allows the +receiving peer to find, within that list, the last header hash they had +in common and reply with all subsequent header hashes. + +Note: the receiving peer itself may respond with an `inv` message +containing header hashes of stale blocks. It is up to the requesting +peer to poll all of its peers to find the best block chain. + +If the receiving peer does not find a common header hash within the +list, it will assume the last common block was the genesis block (block +zero), so it will reply with in `inv` message containing header hashes +starting with block one (the first block after the genesis block). + +| Bytes | Name | Data Type | Description +|----------|----------------------|------------------|---------------- +| 4 | version | uint32_t | The protocol version number; the same as sent in the `version` message. +| *Varies* | hash count | compactSize uint | The number of header hashes provided not including the stop hash. There is no limit except that the byte size of the entire message must be below the [`MAX_SIZE`][max_size] limit; typically from 1 to 200 hashes are sent. +| *Varies* | block header hashes | char[32] | One or more block header hashes (32 bytes each) in internal byte order. Hashes should be provided in reverse order of block height, so highest-height hashes are listed first and lowest-height hashes are listed last. +| 32 | stop hash | char[32] | The header hash of the last header hash being requested; set to all zeroes to request an `inv` message with 500 header hashes (the maximum which will ever be sent as a reply to this message). + +The following annotated hexdump shows a `getblocks` message. (The +message header has been omitted.) + +{% highlight text %} +71110100 ........................... Protocol version: 70001 +02 ................................. Hash count: 2 + +d39f608a7775b537729884d4e6633bb2 +105e55a16a14d31b0000000000000000 ... Hash #1 + +5c3e6403d40837110a2e8afb602b1c01 +714bda7ce23bea0a0000000000000000 ... Hash #2 + +00000000000000000000000000000000 +00000000000000000000000000000000 ... Stop hash +{% endhighlight %} + +{% endautocrossref %} + +#### GetData + +{% autocrossref %} + +The `getdata` message requests one or more data objects from another +node. The objects are requested by an inventory, which the requesting +node typically previously received by way of an `inv` message. + +The response to a `getdata` message can be a `tx` message, `block` +message, `merkleblock` message, or `notfound` message. + +This message cannot be used to request arbitrary data, such as historic +transactions no longer in the memory pool or relay set. Full nodes may +not even be able to provide older blocks if they've pruned old +transactions from their block database. For this reason, the `getdata` +message should usually only be used to request data from a node which +previously advertised it had that data by sending an `inv` message. + +The format and maximum size limitations of the `getdata` message are +identical to the `inv` message; only the message header differs. + +{% endautocrossref %} + +#### GetHeaders + +{% autocrossref %} + +The `getheaders` message requests a `headers` message that provides block headers +starting from a particular point in the block chain. It allows a +peer which has been disconnected or started for the first time to get +the headers it hasn’t seen yet. + +The `getheaders` message is nearly identical to the `getblocks` message, +with one minor difference: the `inv` reply to the `getblocks` message +will include no more than 500 block header hashes; the `headers` reply +to the `getheaders` message will include as many as 2,000 block headers. + +#### Headers + +The `headers` message sends one or more block headers to a node which +previously requested certain headers with a `getheaders` message. + +| Bytes | Name | Data Type | Description +|----------|---------|------------------|----------------- +| *Varies* | count | compactSize uint | Number of block headers up to a maximum of 2,000. +| *Varies* | headers | block_header | Block headers: each 80-byte block header is in the format described in the [block headers section][block header] with an additional 0x00 suffixed. This 0x00 is called the transaction count, but because the headers message doesn't include any transactions, the transaction count is always zero. + +The following annotated hexdump shows a `headers` message. (The message +header has been omitted.) + +{% highlight text %} +01 ................................. Header count: 1 + +02000000 ........................... Block version: 2 +b6ff0b1b1680a2862a30ca44d346d9e8 +910d334beb48ca0c0000000000000000 ... Hash of previous block's header +9d10aa52ee949386ca9385695f04ede2 +70dda20810decd12bc9b048aaab31471 ... Merkle root +24d95a54 ........................... Unix time: 1415239972 +30c31b18 ........................... Target (bits) +fe9f0864 ........................... Nonce + +00 ......... Transaction Count (0x00) +{% endhighlight %} + +{% endautocrossref %} + +#### Inv + +{% autocrossref %} + +The `inv` message (inventory message) transmits one or more inventories of +objects known to the transmitting peer. It can be sent unsolicited to +announce new transactions or blocks, or it can be sent in reply to a +`getblocks` message or `mempool` message. + +The receiving peer can compare the inventories from an `inv` message +against the inventories it has already seen, and then use a follow-up +message to request unseen objects. + +| Bytes | Name | Data Type | Description +|----------|-----------|-----------------------|----------------- +| *Varies* | count | compactSize uint | The number of inventory entries. +| *Varies* | inventory | inventory | One or more inventory entries up to a maximum of 50,000 entries. + +The following annotated hexdump shows an `inv` message with two +inventory entries. (The message header has been omitted.) + +{% highlight text %} +02 ................................. Count: 2 + +01000000 ........................... Type: MSG_TX +de55ffd709ac1f5dc509a0925d0b1fc4 +42ca034f224732e429081da1b621f55a ... Hash (TXID) + +01000000 ........................... Type: MSG_TX +91d36d997037e08018262978766f24b8 +a055aaf1d872e94ae85e9817b2c68dc7 ... Hash (TXID) +{% endhighlight %} + +{% endautocrossref %} + +#### MemPool + +{% autocrossref %} + +The `mempool` message requests the TXIDs of transactions that the +receiving node has verified are valid but which have not yet appeared in +a block. That is, transactions which are in the receiving node's memory +pool. The response to the `mempool` message is one or more `inv` +messages containing the TXIDs in the usual inventory format. The +`mempool` message was introduced in protocol version 60002 as +implemented in Bitcoin Core 0.7.0 (September 2012). + +Sending the `mempool` message is mostly useful when a program first +connects to the network. Full nodes can use it to quickly gather most or +all of the unconfirmed transactions available on the network; this is +especially useful for miners trying to gather transactions for their +transaction fees. SPV clients can set a filter before sending a +`mempool` to only receive transactions that match that filter; this +allows a recently-started client to get most or all unconfirmed +transactions related to its wallet. + +The `inv` response to the `mempool` message is, at best, one node's +view of the network---not a complete list of unconfirmed transactions +on the network. Here are some additional reasons the list might not +be complete: + +* Before Bitcoin Core 0.9.0, the response to the `mempool` message was + only one `inv` message. An `inv` message is limited to 50,000 + inventories, so a node with a memory pool larger than 50,000 entries + would not send everything. Later versions of Bitcoin Core send as + many `inv` messages as needed to reference its complete memory pool. + +* The `mempool` message is not currently fully compatible with the + `filterload` message's `BLOOM_UPDATE_ALL` and + `BLOOM_UPDATE_P2PUBKEY_ONLY` flags. Mempool transactions are not + sorted like in-block transactions, so a transaction (tx2) spending an + output can appear before the transaction (tx1) containing that output, + which means the automatic filter update mechanism won't operate until + the second-appearing transaction (tx1) is seen---missing the + first-appearing transaction (tx2). It has been proposed in [Bitcoin + Core issue #2381][] that the transactions should be sorted before + being processed by the filter. + +There is no payload in a `mempool` message. See the [message header +section][message header] for an example of a message without a payload. + +{% endautocrossref %} + +#### MerkleBlock + +{% autocrossref %} + +The `merkleblock` message is a reply to a `getdata` message which +requested a block using the inventory type `MSG_MERKLEBLOCK`. It is +only part of the reply: if any matching transactions are found, they will +be sent separately as `tx` messages. + +This message is part of the bloom filters described in BIP37, added in +protocol version 70001 and implemented in Bitcoin Core 0.8.0 +(February 2013). + +If a filter has been previous set with the `filterload` message, the +`merkleblock` message will contain the TXIDs of any transactions in the +requested block that matched the filter, as well as any parts of the +block's merkle tree necessary to connect those transactions to the +block header's merkle root. The message also contains a complete copy +of the block header to allow the client to hash it and confirm its +proof of work. + +| Bytes | Name | Data Type | Description +|----------|--------------------|------------------|---------------- +| 80 | block header | block_header | The block header in the format described in the [block header section][block header]. +| 4 | transaction count | uint32_t | The number of transactions in the block (including ones that don't match the filter). +| *Varies* | hash count | compactSize uint | The number of hashes in the following field. +| *Varies* | hashes | char[32] | One or more hashes of both transactions and merkle nodes in internal byte order. Each hash is 32 bits. +| *Varies* | flag byte count | compactSize uint | The number of flag bytes in the following field. +| *Varies* | flags | byte[] | A sequence of bits packed eight in a byte with the least significant bit first. May be padded to the nearest byte boundary but must not contain any more bits than that. Used to assign the hashes to particular nodes in the merkle tree as described below. + +The annotated hexdump below shows a `merkleblock` message which +corresponds to the examples below. (The message header has been +omitted.) + +{% highlight text %} +01000000 ........................... Block version: 1 +82bb869cf3a793432a66e826e05a6fc3 +7469f8efb7421dc88067010000000000 ... Hash of previous block's header +7f16c5962e8bd963659c793ce370d95f +093bc7e367117b3c30c1f8fdd0d97287 ... Merkle root +76381b4d ........................... Time: 1293629558 +4c86041b ........................... nBits: 0x04864c * 256**(0x1b-3) +554b8529 ........................... Nonce + +07000000 ........................... Transaction count: 7 +04 ................................. Hash count: 4 + +3612262624047ee87660be1a707519a4 +43b1c1ce3d248cbfc6c15870f6c5daa2 ... Hash #1 +019f5b01d4195ecbc9398fbf3c3b1fa9 +bb3183301d7a1fb3bd174fcfa40a2b65 ... Hash #2 +41ed70551dd7e841883ab8f0b16bf041 +76b7d1480e4f0af9f3d4c3595768d068 ... Hash #3 +20d2a7bc994987302e5b1ac80fc425fe +25f8b63169ea78e68fbaaefa59379bbf ... Hash #4 + +01 ................................. Flag bytes: 1 +1d ................................. Flags: 1 0 1 1 1 0 0 0 +{% endhighlight %} + +Note: when fully decoded, the above `merkleblock` message provided the +TXID for a single transaction that matched the filter. In the network +traffic dump this output was taken from, the full transaction belonging +to that TXID was sent immediately after the the `merkleblock` message as +a `tx` message. + +**Parsing A MerkleBlock** + +As seen in the annotated hexdump above, the `merkleblock` message +provides three special data types: a transaction count, a list of +hashes, and a list of one-bit flags. + +You can use the transaction count to construct an empty merkle tree. +We'll call each entry in the tree a node; on the bottom are TXID +nodes---the hashes for these nodes are TXIDs; the remaining nodes +(including the merkle root) are non-TXID nodes---they may actually have +the same hash as a TXID, but we treat them differently. + +![Example Of Parsing A MerkleBlock Message](/img/dev/animated-en-merkleblock-parsing.gif) + +Keep the hashes and flags in the order they appear in the `merkleblock` +message. When we say "next flag" or "next hash", we mean the next flag +or hash on the list, even if it's the first one we've used so far. + +Start with the merkle root node and the first flag. The table below +describes how to evaluate a flag based on whether the node being +processed is a TXID node or a non-TXID node. Once you apply a flag to a +node, never apply another flag to that same node or reuse that same +flag again. + +| Flag | TXID Node | Non-TXID Node +|-------|------------------------------------------------------------------------------------------|---- +| **0** | Use the next hash as this node's TXID, but this transaction didn't match the filter. | Use the next hash as this node's hash. Don't process any descendant nodes. +| **1** | Use the next hash as this node's TXID, and mark this transaction as matching the filter. | The hash needs to be computed. Process the left child node to get its hash; process the right child node to get its hash; then concatenate the two hashes as 64 raw bytes and hash them to get this node's hash. + +Any time you descend into a node for the first time, evaluate the next +flag. Never use a flag at any other time. + +When processing a child node, you may need to process its children (the +grandchildren of the original node) or further-descended nodes before +returning to the parent node. This is expected---keep processing depth +first until you reach a TXID node or a non-TXID node with a flag of 0. + +After you process a TXID node or a non-TXID node with a flag of 0, stop +processing flags and begin to ascend the tree. As you ascend, compute +the hash of any nodes for which you now have both child hashes or for +which you now have the sole child hash. See the [merkle tree +section][section merkle trees] for hashing instructions. If you reach a +node where only the left hash is known, descend into its right child (if +present) and further descendants as necessary. + +However, if you find a node whose left and right children both have the +same hash, fail. This is related to CVE-2012-2459. + +Continue descending and ascending until you have enough information to +obtain the hash of the merkle root node. If you run out of flags or +hashes before that condition is reached, fail. Then perform the +following checks (order doesn't matter): + +* Fail if there are unused hashes in the hashes list. + +* Fail if there are unused flag bits---except for the minimum number of + bits necessary to pad up to the next full byte. + +* Fail unless the hash of the merkle root node is identical to the + merkle root in the block header. + +* Fail if the block header is invalid. Remember to ensure that the hash + of the header is less than or equal to the target threshold encoded by + the nBits header field. Your program should also, of course, attempt + to ensure the header belongs to the best block chain and that the user + knows how many confirmations this block has. + +For a detailed example of parsing a `merkleblock` message, please see +the corresponding [merkleblock examples section][section merkleblock +example]. + +**Creating A MerkleBlock** + +It's easier to understand how to create a `merkleblock` message after +you understand how to parse an already-created message, so we recommend +you read the parsing section above first. + +Create a complete merkle tree with TXIDs on the bottom row and all the +other hashes calculated up to the merkle root on the top row. For each +transaction that matches the filter, track its TXID node and all of its +ancestor nodes. + +![Example Of Creating A MerkleBlock Message](/img/dev/animated-en-merkleblock-creation.gif) + +Start processing the tree with the merkle root node. The table below +describes how to process both TXID nodes and non-TXID nodes based on +whether the node is a match, a match ancestor, or neither a match nor a +match ancestor. + +| | TXID Node | Non-TXID Node +|--------------------------------------|------------------------------------------------------------------------|---- +| **Neither Match Nor Match Ancestor** | Append a 0 to the flag list; append this node's TXID to the hash list. | Append a 0 to the flag list; append this node's hash to the hash list. Do not descend into its child nodes. +| **Match Or Match Ancestor** | Append a 1 to the flag list; append this node's TXID to the hash list. | Append a 1 to the flag list; process the left child node. Then, if the node has a right child, process the right child. Do not append a hash to the hash list for this node. + +Any time you descend into a node for the first time, a flag should be +appended to the flag list. Never put a flag on the list at any other +time, except when processing is complete to pad out the flag list to a +byte boundary. + +When processing a child node, you may need to process its children (the +grandchildren of the original node) or further-descended nodes before +returning to the parent node. This is expected---keep processing depth +first until you reach a TXID node or a node which is neither a TXID nor +a match ancestor. + +After you process a TXID node or a node which is neither a TXID nor a +match ancestor, stop processing and begin to ascend the tree until you +find a node with a right child you haven't processed yet. Descend into +that right child and begin processing again. + +After you fully process the merkle root node according to the +instructions in the table above, processing is complete. Pad your flag +list to a byte boundary and construct the `merkleblock` message using the +template near the beginning of this subsection. + +{% endautocrossref %} + +#### NotFound + +{% autocrossref %} + +The `notfound` message is a reply to a `getdata` message which +requested an object the receiving node does not have available for +relay. (Nodes are not expected to relay historic transactions which +are no longer in the memory pool or relay set. Nodes may also have +pruned spent transactions from older blocks, making them unable to +send those blocks.) + +The format and maximum size limitations of the `notfound` message are +identical to the `inv` message; only the message header differs. + +{% endautocrossref %} + +#### Tx + +{% autocrossref %} + +The `tx` message transmits a single transaction in the raw transaction +format. It can be sent in a variety of situations; + +* **Transaction Response:** Bitcoin Core and BitcoinJ will send it in + response to a `getdata` message that requests the transaction with an + inventory type of `MSG_TX`. + +* **MerkleBlock Response:** Bitcoin Core will send it in response to a + `getdata` message that requests a merkleblock with an inventory type + of `MSG_MERKLEBLOCK`. (This is in addition to sending a `merkleblock` + message.) Each `tx` message in this case provides a matched + transaction from that block. + +* **Unsolicited:** BitcoinJ will send a `tx` message unsolicited for + transactions it originates. + +For an example hexdump of the raw transaction format, see the [raw +transaction section][raw format]. + +{% endautocrossref %} + diff --git a/_includes/references.md b/_includes/references.md index 77dac5e3..1cd9afe3 100644 --- a/_includes/references.md +++ b/_includes/references.md @@ -12,6 +12,7 @@ [block chain]: /en/developer-guide#block-chain "A chain of blocks with each block linking to the block that preceded; the most-difficult-to-recreate chain is The Block Chain" [block header]: /en/developer-reference#block-headers "An 80-byte header belonging to a single block which is hashed repeatedly to create proof of work" [block height]: /en/developer-guide#term-block-height "The number of chained blocks preceding this block" +[block message]: /en/developer-reference#block "The P2P network message which sends a serialized block" [block reward]: /en/developer-reference#term-block-reward "New satoshis given to a miner for creating one of the first 6,929,999 blocks" [block time]: /en/developer-reference#term-block-time "The time field in the block header" [block version]: /en/developer-reference#term-block-version "The version field in the block header" @@ -46,14 +47,20 @@ [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" +[getblocks message]: /en/developer-reference#getblocks "A P2P protocol message used to request an inv message containing a range of block header hashes" +[getdata message]: /en/developer-reference#getdata "A P2P protocol message used to request one or more transactions, blocks, or merkleblocks" +[getheaders message]: /en/developer-reference#getheaders "A P2P protocol message used to request a range of block headers" [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" +[headers message]: /en/developer-reference#headers "A P2P protocol message containing one or more block headers" [high-priority transactions]: /en/developer-guide#term-high-priority-transactions "Transactions which don't pay a transaction fee; only transactions spending long-idle outputs are eligible" [input]: /en/developer-guide#term-input "The input to a transaction linking to the output of a previous transaction which permits spending of satoshis" [inputs]: /en/developer-guide#term-input "The input to a transaction linking to the output of a previous transaction which permits spending of satoshis" [intermediate certificate]: /en/developer-examples#term-intermediate-certificate "A intermediate certificate authority certificate which helps connect a leaf (receiver) certificate to a root certificate authority" [internal byte order]: /en/developer-reference#hash-byte-order "The standard order in which hash digests are displayed as strings---the same format used in blocks" +[inv message]: /en/developer-reference#inv "A P2P protocol message used to send inventories of transactions and blocks known to the transmitting peer" +[inventory]: /en/developer-reference#term-inventory "A data type identifier and a hash; used to identify transactions and blocks available for download through the P2P network." [key index]: /en/developer-guide#term-key-index "An index number used in the HD wallet formula to generate child keys from a parent key" [key pair]: /en/developer-guide#term-key-pair "A private key and its derived public key" [label]: /en/developer-guide#term-label "The label parameter of a bitcoin: URI which provides the spender with the receiver's name (unauthenticated)" @@ -63,19 +70,26 @@ [mainnet]: /en/developer-examples#term-mainnet "The Bitcoin main network used to transfer satoshis (compare to testnet, the test network)" [master chain code]: /en/developer-guide#term-master-chain-code "The chain code derived from the root seed" [master private key]: /en/developer-guide#term-master-private-key "A private key derived from the root seed" +[mempool message]: /en/developer-reference#mempool "A P2P protocol message used to request one or more inv messages with currently-unconfirmed transactions" [merge]: /en/developer-guide#term-merge "Spending, in the same transaction, multiple outputs which can be traced back to different previous spenders, leaking information about how many satoshis you control" [merge avoidance]: /en/developer-guide#term-merge-avoidance "A strategy for selecting which outputs to spend that avoids merging outputs with different histories that could leak private information" -[message]: /en/developer-guide#term-message "A parameter of bitcoin: URIs which allows the receiver to optionally specify a message to the spender" [merkle root]: /en/developer-guide#term-merkle-root "The root node of a merkle tree descended from all the hashed pairs in the tree" [merkle tree]: /en/developer-guide#term-merkle-tree "A tree constructed by hashing paired data, then pairing and hashing the results until a single hash remains, the merkle root" +[merkleblock message]: /en/developer-reference#merkleblock "A P2P protocol message used to request a filtered block useful for SPV proofs" +[message]: /en/developer-guide#term-message "A parameter of bitcoin: URIs which allows the receiver to optionally specify a message to the spender" +[message header]: /en/developer-reference#message-headers "The four header fields prefixed to all messages on the P2P network" [millibitcoins]: /en/developer-guide#term-millibitcoins "0.001 bitcoins (100,000 satoshis)" [mine]: /en/developer-guide#term-miner "Creating Bitcoin blocks which solve proof-of-work puzzles in exchange for block rewards and transaction fees" [miner]: /en/developer-guide#term-miner "Creators of Bitcoin blocks who solve proof-of-work puzzles in exchange for block rewards and transaction fees" [miners]: /en/developer-guide#term-miner "Creators of Bitcoin blocks who solve proof-of-work puzzles in exchange for block rewards and transaction fees" -[minimum fee]: /en/developer-guide#term-minimum-fee "The minimum fee a transaction must pay in must circumstances to be mined or broadcast by peers across the network" +[minimum fee]: /en/developer-guide#term-minimum-fee "The minimum fee a transaction must pay in most circumstances to be mined or broadcast by peers across the network" +[msg_tx]: /en/developer-reference#term-msg_tx "The TXID data type identifier of an inventory on the P2P network" +[msg_block]: /en/developer-reference#term-msg_block "The block header hash data type identifier of an inventory on the P2P network" +[msg_filtered_block]: /en/developer-reference#term-msg_block "An alternative to the block header hash data type identifier of an inventory on the P2P network used to request a merkleblock" [multisig]: /en/developer-guide#term-multisig "An pubkey script using OP_CHECKMULTISIG to check for multiple signatures" [nbits]: /en/developer-reference#target-nbits "The encoded form of the target threshold as it appears in the block header" [network]: /en/developer-guide#term-network "The Bitcoin P2P network which broadcasts transactions and blocks" +[notfound message]: /en/developer-reference#notfound "A P2P protocol message sent to indicate that the requested data was not available" [Null data]: /en/developer-guide#term-null-data "A standard transaction type which allows adding 40 bytes of arbitrary data to the block chain up to once per transaction" [op_checkmultisig]: /en/developer-reference#term-op-checkmultisig "Op code which returns true if one or more provided signatures (m) sign the correct parts of a transaction and match one or more provided public keys (n)" [op_checksig]: /en/developer-reference#term-op-checksig "Op code which returns true if a signature signs the correct parts of a transaction and matches a provided public key" @@ -147,15 +161,17 @@ [stack]: /en/developer-guide#term-stack "An evaluation stack used in Bitcoin's script language" [stale block]: /en/developer-guide#term-stale-block "Blocks which were successfully mined but which aren't included on the current valid block chain" [standard script]: /en/developer-guide#standard-transactions "A pubkey script which matches the IsStandard() patterns specified in Bitcoin Core---or a transaction containing only standard outputs. Only standard transactions are mined or broadcast by peers running the default Bitcoin Core software" +[start string]: /en/developer-reference#term-start-string "Four defined bytes which start every message in the P2P protocol to allow seeking to the next message" [target]: /en/developer-guide#term-target "The threshold below which a block header hash must be in order for the block to be added to the block chain" [testnet]: /en/developer-examples#testnet "A Bitcoin-like network where the satoshis have no real-world value to allow risk-free testing" [transaction fee]: /en/developer-guide#term-transaction-fee "The amount remaining when all outputs are subtracted from all inputs in a transaction; the fee is paid to the miner who includes that transaction in a block" [transaction fees]: /en/developer-guide#term-transaction-fee "The amount remaining when all outputs are subtracted from all inputs in a transaction; the fee is paid to the miner who includes that transaction in a block" [transaction malleability]: /en/developer-guide#transaction-malleability "The ability of an attacker to change the transaction identifier (txid) of unconfirmed transactions, making dependent transactions invalid" -[txid]: /en/developer-guide#term-txid "A hash of a completed transaction which allows other transactions to spend its outputs" [transaction]: /en/developer-guide#transactions "A transaction spending satoshis" [transaction version number]: /en/developer-guide#term-transaction-version-number "A version number prefixed to transactions to allow upgrading"" [transactions]: /en/developer-guide#transactions "A transaction spending satoshis" +[tx message]: /en/developer-reference#tx "A P2P protocol message which sends a single serialized transaction" +[txid]: /en/developer-guide#term-txid "A hash of a completed transaction which allows other transactions to spend its outputs" [unconfirmed]: /en/developer-guide#term-unconfirmed-transactions "A transaction which has not yet been added to the block chain" [unconfirmed transactions]: /en/developer-guide#term-unconfirmed-transactions "A transaction which has not yet been added to the block chain" [unique addresses]: /en/developer-guide#term-unique-address "Address which are only used once to protect privacy and increase security" @@ -244,7 +260,11 @@ [rpc walletpassphrasechange]: /en/developer-reference#walletpassphrasechange +[Bitcoin Core 0.6.0]: /en/release/v0.6.0 +[Bitcoin Core 0.6.1]: /en/release/v0.6.1 [Bitcoin Core 0.7.0]: /en/release/v0.7.0 +[Bitcoin Core 0.8.0]: /en/release/v0.8.0 +[Bitcoin Core 0.9.0]: /en/release/v0.9.0 [Bitcoin Core 0.9.3]: /en/release/v0.9.3 [bitcoin URI subsection]: /en/developer-guide#bitcoin-uri [bitcoinpdf]: https://bitcoin.org/bitcoin.pdf @@ -266,8 +286,12 @@ [RPC]: /en/developer-reference#remote-procedure-calls-rpcs [RPCs]: /en/developer-reference#remote-procedure-calls-rpcs [section detecting forks]: /en/developer-guide#detecting-forks +[section getblocktemplate]: /en/developer-guide#getblocktemplate-rpc [section hash byte order]: /en/developer-reference#hash-byte-order [section merkle trees]: /en/developer-reference#merkle-trees +[section merkleblock example]: /en/developer-examples#parsing-a-merkleblock +[section protocol versions]: /en/developer-reference#protocol-versions +[section serialized blocks]: /en/developer-reference#serialized-blocks [section simple raw transaction]: /en/developer-examples#simple-raw-transaction [section verifying payment]: /en/developer-guide#verifying-payment [signature script modification warning]: /en/developer-reference#signature_script_modification_warning @@ -277,13 +301,18 @@ +[BIP14]: https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki [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 +[BIP31]: https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki [BIP32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki [BIP34]: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki +[BIP35]: https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki +[BIP37]: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki [BIP39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki [BIP50]: https://github.com/bitcoin/bips/blob/master/bip-0050.mediawiki +[BIP61]: https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki [BIP62]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki [BIP70]: https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki [BIP71]: https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki @@ -296,12 +325,14 @@ [BFGMiner]: https://github.com/luke-jr/bfgminer [bitcoin core fee drop commit]: https://github.com/bitcoin/bitcoin/commit/6a4c196dd64da2fd33dc7ae77a8cdd3e4cf0eff1 +[Bitcoin Core issue #2381]: https://github.com/bitcoin/bitcoin/issues/2381 [Bitcoin Seeder]: https://github.com/sipa/bitcoin-seeder [bitcoin-documentation mailing list]: https://groups.google.com/forum/#!forum/bitcoin-documentation [BitcoinJ]: http://bitcoinj.github.io [block170]: https://www.biteasy.com/block/00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee [casascius address utility]: https://github.com/casascius/Bitcoin-Address-Utility [core base58.h]: https://github.com/bitcoin/bitcoin/blob/master/src/base58.h +[core chainparams.cpp]: https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp [core git]: https://github.com/bitcoin/bitcoin [core paymentrequest.proto]: https://github.com/bitcoin/bitcoin/blob/master/src/qt/paymentrequest.proto [core script.h]: https://github.com/bitcoin/bitcoin/blob/master/src/script.h @@ -317,16 +348,19 @@ [high-speed block relay network]: https://www.mail-archive.com/bitcoin-development@lists.sourceforge.net/msg03189.html [HMAC-SHA512]: https://en.wikipedia.org/wiki/HMAC [HTTP longpoll]: https://en.wikipedia.org/wiki/Push_technology#Long_polling +[IP-to-IP payment protocol]: https://en.bitcoin.it/wiki/IP_Transactions [irc channels]: https://en.bitcoin.it/wiki/IRC_channels [libblkmaker]: https://gitorious.org/bitcoin/libblkmaker [makeseeds script]: https://github.com/bitcoin/bitcoin/tree/master/contrib/seeds [man-in-the-middle]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack [MIME]: https://en.wikipedia.org/wiki/Internet_media_type [mozrootstore]: https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/ +[netcat]: https://en.wikipedia.org/wiki/Netcat [Payment Request Generator]: http://bitcoincore.org/~gavin/createpaymentrequest.php [Piotr Piasecki's testnet faucet]: https://tpfaucet.appspot.com/ [prime symbol]: https://en.wikipedia.org/wiki/Prime_%28symbol%29 [protobuf]: https://developers.google.com/protocol-buffers/ +[python-bitcoinlib]: https://github.com/petertodd/python-bitcoinlib [python-blkmaker]: https://gitorious.org/bitcoin/python-blkmaker [SHA256]: https://en.wikipedia.org/wiki/SHA-2 [Stratum mining protocol]: http://mining.bitcoin.cz/stratum-mining @@ -335,3 +369,7 @@ [wiki script]: https://en.bitcoin.it/wiki/Script [x509]: https://en.wikipedia.org/wiki/X.509 + +[MAX_SIZE]: https://github.com/bitcoin/bitcoin/blob/60abd463ac2eaa8bc1d616d8c07880dc53d97211/src/serialize.h#L23 diff --git a/_plugins/autocrossref.rb b/_plugins/autocrossref.rb index 95a972e8..2d99bb8a 100644 --- a/_plugins/autocrossref.rb +++ b/_plugins/autocrossref.rb @@ -65,9 +65,9 @@ require 'yaml' (?![^\s]*) ## No subst if after key (?!((?!
).)*(<\/pre>))  ## No subst on a line with a closing pre tag. This 
                                         ## prevents matching in {% highlight %} code blocks.
-            (?![^\(]*(\.svg|\.png))  ## No subst if key inside an image name. This 
+            (?![^\(]*(\.svg|\.png|\.gif))  ## No subst if key inside an image name. This 
 		     ## simple regex has the side effect that we can't
-		     ## use .svg or .png in non-image base text; if that
+		     ## use .svg, .png, or .gif in non-image base text; if that
 		     ## becomes an issue, we can devise a more complex
 		     ## regex
             (?!\w)  ## Don't match inside words
diff --git a/en/developer-documentation.md b/en/developer-documentation.md
index 83ec5498..1ade78b4 100644
--- a/en/developer-documentation.md
+++ b/en/developer-documentation.md
@@ -62,6 +62,8 @@ title: "Developer Documentation - Bitcoin"
     

IconP2P Network

P2P Network Guide

+

P2P Network Reference

+

P2P Network Examples

diff --git a/en/developer-examples.md b/en/developer-examples.md index ae17bd1d..c8e040f0 100644 --- a/en/developer-examples.md +++ b/en/developer-examples.md @@ -30,6 +30,8 @@ title: "Developer Examples - Bitcoin" {% include example_payment_processing.md %} +{% include example_p2p_networking.md %} + {% include references.md %}
diff --git a/en/developer-reference.md b/en/developer-reference.md index 01801548..a85668d0 100644 --- a/en/developer-reference.md +++ b/en/developer-reference.md @@ -30,6 +30,8 @@ title: "Developer Reference - Bitcoin" {% include ref_wallets.md %} +{% include ref_p2p_networking.md %} + ## Bitcoin Core APIs + + + +_anonymous_0 + +Overview Of P2P Protocol Data Request And Reply Messages + +getblocks + +getblocks + + +inv + +inv + + +getblocks->inv + + + +getdata + +getdata + + +inv->getdata + + + +mempool + +mempool + + +mempool->inv + + + +tx + +tx + + +getdata->tx + + + +block + +block + + +getdata->block + + + +merkleblock + +merkleblock + + +getdata->merkleblock + + + +notfound + +notfound + + +getdata->notfound + + + +getheaders + +getheaders + + +headers + +headers + + +getheaders->headers + + + +label1 +Request For Help +Getting Up To Date + + +label2 +Reply With +Inventory + + + +label3 +Request For Specific Data + + + +label4 +Reply With +Requested Data + + + + diff --git a/img/dev/gifs/README.md b/img/dev/gifs/README.md new file mode 100644 index 00000000..3163c9b8 --- /dev/null +++ b/img/dev/gifs/README.md @@ -0,0 +1,31 @@ +# Some Animated GIF Hints + +An excellent set of background information can be found here: + + http://www.imagemagick.org/Usage/anim_basics/ + +1. Create source images. GraphViz supports direct GIF output, but its + white background is not-quite-white and its transparent backgroud is + hideous---so we output to PNG and then convert to GIF. + + for f in *dot ; do dot -o ${f/.dot}.png -T png $f ; done + +2. Create animated GIF using ImageMagick. Manually prefix first frame + and suffix last frame to provide a brief pause in the animation on + those frames. This wastes space but the optimization removes all of + that wasted space except for 3 bytes. + + convert -delay 100 \ + en-merkleblock-parsing-001.gif \ + *gif \ + en-merkleblock-parsing-011.gif \ + -loop 0 \ + animated-en-merkleblock-parsing.gif + +3. Compress animated GIF (118 KB -> 15 KB in this example). You may need + to play with color settings; 8 worked in this example but 4 was too + few. Fewer colors (base-2) results in much better compression. + + gifsicle -b -O3 --colors 8 --no-background \ + animated-en-merkleblock-parsing.gif + diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-001.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-001.dot new file mode 100644 index 00000000..6b2db10b --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-001.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0" ]; + flag1 [ label = "1" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5" ]; + D [ label = "H4" ]; + C [ label = "H3" ]; + B [ label = "H2" ]; + A [ label = "H1" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB [ label = "H8" ]; + CD [ label = "H9" ]; + EF [ label = "H10" ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12" ]; + EFG2 [ label = "H13" ]; + + ABCD -> ROOT; + EFG2 -> ROOT; + + ROOT -> ABCD [ constraint = false, style = "invis" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "H14" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-002.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-002.dot new file mode 100644 index 00000000..f098f09e --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-002.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0" ]; + flag1 [ label = "1" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4 ]; + D [ label = "H4" ]; + C [ label = "H3" ]; + B [ label = "H2" ]; + A [ label = "H1" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB [ label = "H8" ]; + CD [ label = "H9" ]; + EF [ label = "H10", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12" ]; + EFG2 [ label = "H13", penwidth = 4 ]; + + ABCD -> ROOT; + EFG2 -> ROOT; + + ROOT -> ABCD [ constraint = false, style = "invis" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "H14", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-003.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-003.dot new file mode 100644 index 00000000..ab25828b --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-003.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0" ]; + flag1 [ label = "1", style = "filled" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4 ]; + D [ label = "H4" ]; + C [ label = "H3" ]; + B [ label = "H2" ]; + A [ label = "H1" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB [ label = "H8" ]; + CD [ label = "H9" ]; + EF [ label = "H10", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12" ]; + EFG2 [ label = "H13", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT; + + ROOT -> ABCD [ constraint = false, style = "invis" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4, style = "filled" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-004.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-004.dot new file mode 100644 index 00000000..8c1273b8 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-004.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0", style = "filled" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H12", style = "filled" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4 ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "H10", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals,filled" ]; + EFG2 [ label = "H13", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-005.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-005.dot new file mode 100644 index 00000000..44accd32 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-005.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1", style = "filled" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4 ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "H10", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4, style = "filled" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-006.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-006.dot new file mode 100644 index 00000000..d49957d9 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-006.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1", style = "filled" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4 ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "↓", penwidth = 4, style = "filled" ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-007.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-007.dot new file mode 100644 index 00000000..85ab3983 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-007.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1", style = "filled" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H5", style = "filled" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6" ]; + E [ label = "H5", penwidth = 4, style = "diagonals,filled" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "↓", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-008.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-008.dot new file mode 100644 index 00000000..a8135e40 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-008.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0", style = "filled" ]; + flag5 [ label = "1", style = "" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H6", style = "filled" ]; + hash2 [ label = "H5", style = "" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6", style = "diagonals,filled" ]; + E [ label = "H5", penwidth = 4, style = "diagonals" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "↓", penwidth = 4 ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-009.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-009.dot new file mode 100644 index 00000000..68bb82ea --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-009.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0", style = "" ]; + flag5 [ label = "1", style = "" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H6", style = "" ]; + hash2 [ label = "H5", style = "" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "H7" ]; + F [ label = "H6", style = "diagonals" ]; + E [ label = "H5", penwidth = 4, style = "diagonals" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "", penwidth = 4, style = "filled" ]; + G2 [ label = "H11" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-010.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-010.dot new file mode 100644 index 00000000..9f7cf9c9 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-010.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "filled" ]; + flag6 [ label = "0", style = "" ]; + flag5 [ label = "1", style = "" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H11", style = "filled" ]; + hash3 [ label = "H6", style = "" ]; + hash2 [ label = "H5", style = "" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "" ]; + F [ label = "H6", style = "diagonals" ]; + E [ label = "H5", penwidth = 4, style = "diagonals" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "", penwidth = 4 ]; + G2 [ label = "H11", style = "diagonals,filled" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "↓", penwidth = 4 ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-011.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-011.dot new file mode 100644 index 00000000..db5cdfdf --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-011.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "" ]; + flag6 [ label = "0", style = "" ]; + flag5 [ label = "1", style = "" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H11", style = "" ]; + hash3 [ label = "H6", style = "" ]; + hash2 [ label = "H5", style = "" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "" ]; + F [ label = "H6", style = "diagonals" ]; + E [ label = "H5", penwidth = 4, style = "diagonals" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "", penwidth = 4 ]; + G2 [ label = "H11", style = "diagonals" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "", penwidth = 4, style = "filled" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, dir = "back" ]; + + ROOT [ label = "↓", penwidth = 4 ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-012.dot b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-012.dot new file mode 100644 index 00000000..6f5a2db0 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-creation/en-merkleblock-creation-012.dot @@ -0,0 +1,148 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.07 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none", style = "invis" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "" ]; + flag6 [ label = "0", style = "" ]; + flag5 [ label = "1", style = "" ]; + flag4 [ label = "1", style = "" ]; + flag3 [ label = "1", style = "" ]; + flag2 [ label = "0", style = "" ]; + flag1 [ label = "1", style = "" ]; + flag_label [ label = "Flags", style = "", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none", style = "invis" ]; + + hash4 [ label = "H11", style = "" ]; + hash3 [ label = "H6", style = "" ]; + hash2 [ label = "H5", style = "" ]; + hash1 [ label = "H12", style = "" ]; + hash_label [ label = "Hashes", style = "", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "Match Or\nMatch\nAncestor" ]; + hash_from_list_label [ label = "Hash\nOn\nList" ]; + hash_computed_label [ label = "Hash\nNot\nNeeded" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4 ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G [ label = "" ]; + F [ label = "H6", style = "diagonals" ]; + E [ label = "H5", penwidth = 4, style = "diagonals" ]; + D [ label = "" ]; + C [ label = "" ]; + B [ label = "" ]; + A [ label = "" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB [ label = "" ]; + CD [ label = "" ]; + EF [ label = "", penwidth = 4 ]; + G2 [ label = "H11", style = "diagonals" ]; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD [ label = "H12", style = "diagonals" ]; + EFG2 [ label = "", penwidth = 4, ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, dir = "back" ]; + + ROOT [ label = "", penwidth = 4, style = "filled" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.dot new file mode 100644 index 00000000..3286c0a5 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.dot @@ -0,0 +1,138 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0" ]; + flag1 [ label = "1" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E; + D; + C; + B; + A; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT; + EFG2 -> ROOT; + + ROOT -> ABCD [ constraint = false, style = "invis" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-001.png new file mode 100644 index 0000000000000000000000000000000000000000..c69aaf7df39968aae76c888a7967faac615ce887 GIT binary patch literal 5951 zcmaKQWn5H2-}bU}Nv|MMO9~4}Nhu{E-LUi_6;VoBkS-|^>5`6JVCgQATskF{kPf9K z=v`K>V zm%_|kL@E^(0R%x5=iI8A;2{IqRwcyL%M>LEdX5P1feJOCGrk^w;oaDYG%?6!slX9f{t zYPVnqm}1lDQDhAW@+>QinQ{>qB_r5*&+DlUCl>6(E7VeQoj2(AI}mXP7%cC; zL~uvdBX}Q+FIkVFNux$i-6K(VLNnRTUQr&jAr0!Bf%v{gF*PV@ia*r$lHT%apoUX< zGHE7oCH*PkwOC@3SP2;N{~B_QIx(pcDh;dbwa$3@TK$!PMCN2%oH6geH~z>(*`@=y zuX*|uegeybfA%gC&MGM^xk`mdv_1?=5Q7Es3K@jv{+|WG3ounh_Hr zhW3wV*ZBW>GY1r$;|%6Y@zuLAY=r$jBv7B=rNse^h#-avZzMrrP|^yJ^HQJ)gauOl z1Gya^I0*9JF%Q7KttCAPD8NPS-a(FLJ$dU9chJwn(TJ$+lz20*G|Uxug9{dqYoH1x}R5bSb7PcsL1vY?`VpgIt|f95(5 z24*wcT%JH14vglLRgo57%n95vk<{rk>mzslsAs=#$J@P^qaYf_M(wJ;HPul#dw!u= z>p@Z9#FB4B3d|;IOsDZ$x_sF)aj+oVIlsL0#6s;VC;M`$%w3tUayr~S3YLAi2pBdQ zIz5yn+YV2|$7BV`Px*EoHLK)Zm!2kE^?TUBY&?;qXCG(veT%cgYdzwQswx#KYbL6+ zq!as(q(I<+zOSOZANItFg=3Utqgv|y81LnVlnS8@5VACXUY;dBJW|qLVWo?>qtqC9 zGOqG6ni`HS@Y~fVfK8@nli+>to}8g!wI>b{7Er~4?F6#FW+P3iA?xlS66dDG&-oRa zdG6&~$q36xXRIW_WNBZA@l+(osv>9o@T3g2-#$f6a5p*zb$m+p5F66dY=s2_MUfz@ ziiH{I2$eMp*>ut;jvk2sM^()igs*UTl&~>#7Q%3_H)cysSNq1fj7V+rctkHAOHm(1WAQju zL=Q`@%(6zwTrfd}Ot-17gyNT>6(6z*;$k*fKnOWtdC6^KF>${oJxJt-alY=ViCNbe8j}`#aj9$E?{J|0&K0aPXvBU71-zsF&^s;k>fPMf%JIh z5t5RLu(*l86bZ0R0Jc~;tU1gD8MspE-n3=vGzckjxm5`WQNW{f>PDPw!k!(`r=p|# zC_(5X6WITK(MPvEBTsA725pQKKogSI-Vm}@M_a^T!A$U?B9qndRqWmg@n2gnUF9V3 zf_D;ZLt5)*ahtFEU}$=E5JJZ*o)kjGpL*xh;FaC=rF6?loy?}qkv0po@N)nGtUjVF zfAP_aO6r`5w?f8rs1&b$x6d}~qG+F9Az!KxjdCd9;-uKs!WmEif)|SB39Y(0>5h*O zM`)0MFrzMZi&1UXKiJy9mFL96Y(}apu6C|MbF4~dDiI6hYB+H~R-?2~r%3&e73$EOE>}K{GhKv8a_#+V;`(AR^){#jn_iD%LAhzT< zIUAGG1+9(=vw`o+S#X1N}N$k>A&&HU(?_L$nb;s5RV?Zy z@pf5mRZZY`U4xLKf~H-AMvf9~P}0yd$>CKH=kJs#a2C4j0c{Ox-O_!hs!brkmWSJW z{SxKTgjd{8-#;U#Q7VHb$IhpxceI8bFpef9EfVP?Mq_0_Xgs$v^O5J^=DIMh9~MkkgQjGxmx(3% zd5iBrNhgUEzY2d`J`R>Zo#9kMkkr*SA~X6OIqWG4Jyk z-VsXNt{ItF_kVKS5?nj8#~OdecRiZFqQoV0H#Ef~vqGcbP6IaFU_<4&HPIoDCS^dz z5T^*&^qqEr!Hs(@6)NTV%ZfUyCjdHRdAwr2-mqZmoCrZWt?Opw{GGesOB1pc(WB8} zl~v*wdL6(^6{dPKT9(P(ZJXH;h)j0`b5plaZ}*ipYKHn;Z`p7H0wa??kL~``oHV_C zw(-_sUPw0wuEarsT&Ab-kr~+oi^_yp4>06Nt&9<77fkrlx)<>4GUKo=x1dgO?6_0Z zeX4OLR^T->%v|Od(EV8VGEVbNQIa%(4k+;7oMsf6P`}`=QI97aU(IdioN6p~n-bJ2 z846YiU$D+9X(p=BJ{o?FX*&_QVCyRe{mPK4Xpm>qRQF&<=iLdING?Y?$ zKD7x`KzQm8>pD1BXo)8tSEx=`XxryxHy%p1e?Zt=m*@3@l4$g<44!;3k5N%g5cipD zQw62jk!!t|Nch6s2B+0 znn*LFq1bB>sEMuh5Y;M$b7+4RTN>judh!?e^pV#3Nl55^#Z8R(J$CY!#7qbJ`Z=^mgM{ z5RK^p$@(y^x{lI&z!1I0HC@YxyT~RBOFpfXk&nZ=1$IE5+e|%38)|P z#Bt}R$5M66!4Ju$*)<^1v-Z5>JvJ(9WLT18x25{nh<`y9SbxH-d;v-b`UXsWG>x8R z>L`T*sga}xaO9fG{^Yld9#W?e^CUP;%QOY%{PJa{osELj>2;i5f@%)Ek9N(F@$L^W zCfss*cIzi@yOu(wHhU(7t;wW-W;9QI9EQ50wp*e;CXPS(?yGlRL$!Ub7lH^L^~OhS zYA;ux*IJpn6w+sTK-g4!X`+d+V0KN*MlBtzZxHULE*q6xRV&_4gLqwv-3bcmK`?AM zwNXp^*oxOhq=GJLq1kQgFjw+$e=;NfrwV1or*6qm2(p1eU$dK)#0jb{y}J_$x2!CU9~&zeZQ4fd&IKM z21Ol@*qn(>NUWU9>LlR$aAJ{N0v{nCqcyh0Jr)NCuiWke@#R4uFTMF9@3z6K_C_h4 zKfYLS8{_=h{-uoR87Tj2&gyzTeQ76q7ag^vPirE6h91gxAb8zp_TfUyVX6J+k;#j- zY86SX;YP+;%7wk{YnAZAU|#b^3`5lpZgEb8#NokzD9jJQN_(>TJb7VSBm8Rh^%6{< zjFL9RF#@J`diJr;Qb-`AK^gJ-@8R!QCKGrr^O4KG+l}PmW8@JUAB9A^Yh*-*R6gZ> zfiiZ!5V7Bn&y;EHUHz?o6c=9e=H+;>l%g zdFsX{eEF>Z2+!aU9v$~NkG5Spy)SVNNIY1W(vNbQD!LS2I{qDO zOSRqewzo*ktr55Tz3GUg#O92ehL&>+S504CN7KGx(1wJ6jB4=>OY+h$*MpO18@-)dnEDz<-vYY!$ zRJT%|_PnHSZ}?k4X>D14p|`tciWD;b5uSD!yHGgtr>+CHr2L9_TqNhLd6D$fNmW1r zOK2VLbnZK`Uj}AZ(>mAd3Cx5j@|}K}0Wq(@a{iEg%PV9U8}Y< zMQhFtiy!~9z;4AkIsNaB zG6hb&T=T83Qob8{9@OosFS=cB9+o*~WrhrV-s$IE%y9Whnf`-q5h z)j+S|^YX?th-ZYAY{PpyZHysagN67Q@G~=csn+V4v_WVlAC%?et8lxzc_3F5+W8spO`CX7_R8qx;k{bQ&-CUZ3;3 z$$GBF>%U?N<;&-5+k9%DyhvGwHT@>n5=YdIaSVu;Qu|F#0TWF5#Ru^|4k}>4!gDBT z)VPO~36iTT>V$gj{V0lTVdY-T+@WDT$ua(?V?l@@V9V%%uO+7xqXqKd)motv3>(9z z>>Xc3zl_gIb1^aQy~o7>3LRgX5!nxisn=iJN*+4Yx>s3g5WoUbwME7DF4}vUPpPs{ zwr#z7=VO)0YJgasW5cG*zQIRPgZ?W*)%_lmO}owaS7WV0)sTe82O%SEr_5-yEyHGkE5+jAN<_tzw$HHhq4!}K4Us%Jk1 z!a8js2cP^X*2T|DUQ~i$vw)?(3I0U%#H!Qx{lf=}6~xlacRiy1SfLn>YzlTRH4W-M zfuj!lZQ=*Iz^XUbJC3Qd*izKIkN{f*F!uWClTy}Xiop11^2B$$(wKr@L);mQ{rPmv z3h93u?59eVw_I`tdW7-1vYI2}FkuS)#{T zyd$j5|NQFRP_x9h$s}qRN7Q}PX1C~I@{P4)j+%iqt~G}pK8!d3MNn-imHI%8hGV9aRR-OLMChDP ziWbiW?b5;|yBjV>ryAiH80n?OehSIw)Gb~MvDf@qTvo43h#@O~-gB=gcw@4I z1r-~z$rn1|nm~ENG-+`2m&~a(M#+>V=gs3Nh+ z0DW@ULi&D7bCtw_(ScW((-$R ztY~6>A6~xSxpUndJ0l%6@O@A1`;;|=iD2!aQ{`p~bC7Dy=vTe%jM(wL$zJjtUe&_z z$*ibu>_{!Z-GsG7K^TrT9_A2ak6KryKh5vF$M;$+9uLu4vwS8D&%z0PB@--SGWW3Z zuu~9b_)vZe=t!gR-|)E0h*~*Vh`bp*A9r5ltUi}v4i|^3sgbiZ4|4IwHW$wieI+0B zyEfcF%rXJLWuUbF5cOPq+5@QILYT{=_#8eR118EY$4|@mp~{`*VF6y_F>ts#@$>5AUzUUC8IFn#$CPXcV= + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 +1 + + +flag4 +1 + + +flag3 +1 + + +flag2 +0 + + +flag1 +1 + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 +H2 + + +hash1 +H1 + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + +F->EF + + + +E + + + +E->EF + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + + + +ABCD + + + +AB->ABCD + + + + + +CD->ABCD + + + + + +EFG2 + + + +EF->EFG2 + + + + +G2->EFG2 + + + + + +ROOT + + + +ABCD->ROOT + + + + + +EFG2->ROOT + + + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.dot new file mode 100644 index 00000000..5b6c06ec --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.dot @@ -0,0 +1,140 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0" ]; + flag1 [ label = "1", style = "filled" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E; + D; + C; + B; + A; + + ROOT [ style = "filled", label = "↓" ] + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT; + + ROOT -> ABCD [ constraint = false, style = "invis" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-002.png new file mode 100644 index 0000000000000000000000000000000000000000..93da2d39d6147883407fb34dd5462c016f7eb66c GIT binary patch literal 6043 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 + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 +1 + + +flag4 +1 + + +flag3 +1 + + +flag2 +0 + + +flag1 + +1 + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 +H2 + + +hash1 +H1 + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + +F->EF + + + +E + + + +E->EF + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + +ROOT + + + + +ABCD + + + + +EFG2 + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + + +EF->EFG2 + + + + +G2->EFG2 + + + +ABCD->ROOT + + + + + + +EFG2->ROOT + + + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.dot new file mode 100644 index 00000000..68a2a34d --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.dot @@ -0,0 +1,141 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1" ]; + flag2 [ label = "0", style = "filled" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1", style = "filled" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E; + D; + C; + B; + A; + + ABCD [ style = "filled,diagonals", label = "H1" ] + ROOT [ label = "↓" ] + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-003.png new file mode 100644 index 0000000000000000000000000000000000000000..543dedf4035851c7593149565d93f40264ba46cb GIT binary patch literal 6347 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 + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 +1 + + +flag4 +1 + + +flag3 +1 + + +flag2 + +0 + + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 +H2 + + +hash1 + +H1 + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + +F->EF + + + +E + + + +E->EF + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + +ABCD + + + + + +H1 + + +ROOT + + + + +ABCD->ROOT + + + + + + +ROOT->ABCD + + + + +EFG2 + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + + +EF->EFG2 + + + + +G2->EFG2 + + + +EFG2->ROOT + + + + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.dot new file mode 100644 index 00000000..ba3e4e3a --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.dot @@ -0,0 +1,142 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1" ]; + flag3 [ label = "1", style = "filled" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" + +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E; + D; + C; + B; + A; + + EFG2 [ style = "filled", label = "↓" ] + ABCD [ style = "diagonals", label = "H1" ] + ROOT [ label = "↓" ] + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF; + F -> EF; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcb53f2669948a298dbe7966504b2c5bb114a3b GIT binary patch literal 6323 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 literal 0 HcmV?d00001 diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.svg b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.svg new file mode 100644 index 00000000..67e7facd --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-004.svg @@ -0,0 +1,294 @@ + + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 +1 + + +flag4 +1 + + +flag3 + +1 + + + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 +H2 + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + +F->EF + + + +E + + + +E->EF + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + +EFG2 + + + + +ROOT + + + + +EFG2->ROOT + + + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + + +EF->EFG2 + + + + + +G2->EFG2 + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.dot new file mode 100644 index 00000000..827fbd02 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.dot @@ -0,0 +1,140 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1" ]; + flag4 [ label = "1", style = "filled" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E; + D; + C; + B; + A; + + EF [ style = "filled", label = "↓" ]; + EFG2 [ label = "↓" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, style = "invis" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.png new file mode 100644 index 0000000000000000000000000000000000000000..4d9c0bdcbab4920165fc49b64cd5d4bb99ea6b6e GIT binary patch literal 6343 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 literal 0 HcmV?d00001 diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.svg b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.svg new file mode 100644 index 00000000..81ca27ae --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-005.svg @@ -0,0 +1,293 @@ + + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 +1 + + +flag4 + +1 + + + + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 +H2 + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + + +F->EF + + + +E + + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + + + +EFG2 + + + + +EF->EFG2 + + + + + +ROOT + + + + +EFG2->ROOT + + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + +G2->EFG2 + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.dot new file mode 100644 index 00000000..5687ebc1 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.dot @@ -0,0 +1,140 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0" ]; + flag5 [ label = "1", style = "filled" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3" ]; + hash2 [ label = "H2", style = "filled" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F; + E [ penwidth = 4, style = "filled,diagonals", label = "H2" ]; + D; + C; + B; + A; + + EF [ label = "↓" ]; + EFG2 [ label = "↓" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, style = "invis" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.png new file mode 100644 index 0000000000000000000000000000000000000000..1f78aa758e04083ae595ad9dce2c6590bf22b1d9 GIT binary patch literal 6657 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 H!2|yfa%h_@ literal 0 HcmV?d00001 diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.svg b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.svg new file mode 100644 index 00000000..6ef673f7 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-006.svg @@ -0,0 +1,301 @@ + + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 +0 + + +flag5 + +1 + + + + + + +flag_label +Flags + + +hash4 +H4 + + +hash3 +H3 + + +hash2 + +H2 + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + +EF + + + + +F->EF + + + + +E + + + + + +H2 + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + + +EF->E + + + + +EFG2 + + + + +EF->EFG2 + + + + + +ROOT + + + + +EFG2->ROOT + + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + +G2->EFG2 + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.dot new file mode 100644 index 00000000..112256b5 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.dot @@ -0,0 +1,140 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0", style = "filled" ]; + flag5 [ label = "1", style = "invis" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3", style = "filled" ]; + hash2 [ label = "H2", style = "invis" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F [ style = "filled,diagonals" label = "H3" ]; + E [ penwidth = 4, style = "diagonals", label = "H2" ]; + D; + C; + B; + A; + + EF [ label = "↓" ]; + EFG2 [ label = "↓" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, style = "invis" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.png new file mode 100644 index 0000000000000000000000000000000000000000..905abf155351a5954f8b8a31dcc2d0eb0e8fa077 GIT binary patch literal 6919 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 literal 0 HcmV?d00001 diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.svg b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.svg new file mode 100644 index 00000000..246e4bd8 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-007.svg @@ -0,0 +1,304 @@ + + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + +flag6 + +0 + + + + + + + +flag_label +Flags + + +hash4 +H4 + + +hash3 + +H3 + + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + + + +H3 + + +EF + + + + +F->EF + + + + +E + + + + + +H2 + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + +EF->F + + + + +EF->E + + + + +EFG2 + + + + +EF->EFG2 + + + + + +ROOT + + + + +EFG2->ROOT + + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + +G2->EFG2 + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.dot new file mode 100644 index 00000000..ca6bd768 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.dot @@ -0,0 +1,140 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0" ]; + flag6 [ label = "0", style = "invis" ]; + flag5 [ label = "1", style = "invis" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4" ]; + hash3 [ label = "H3", style = "invis" ]; + hash2 [ label = "H2", style = "invis" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F [ style = "diagonals", label = "H3" ]; + E [ penwidth = 4, style = "diagonals", label = "H2" ]; + D; + C; + B; + A; + + EF [ label = "H()", style = "filled" ]; + EFG2 [ label = "↓" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, style = "invis" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-008.png new file mode 100644 index 0000000000000000000000000000000000000000..c647758ad9be449be6f7adb7be88ccc6aa127292 GIT binary patch literal 6913 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 + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 +0 + + + + + + + + +flag_label +Flags + + +hash4 +H4 + + + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + +G->G2 + + + +F + + + + + +H3 + + +EF + +H() + + +F->EF + + + + +E + + + + + +H2 + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + +EF->F + + + + +EF->E + + + + +EFG2 + + + + +EF->EFG2 + + + + +EFG2->EF + + + + +ROOT + + + + +EFG2->ROOT + + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + +G2->EFG2 + + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.dot new file mode 100644 index 00000000..a697d90b --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.dot @@ -0,0 +1,141 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "filled" ]; + flag6 [ label = "0", style = "invis" ]; + flag5 [ label = "1", style = "invis" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4", style = "filled" ]; + hash3 [ label = "H3", style = "invis" ]; + hash2 [ label = "H2", style = "invis" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F [ style = "diagonals", label = "H3" ]; + E [ penwidth = 4, style = "diagonals", label = "H2" ]; + D; + C; + B; + A; + + G2 [ label = "H4", style = "filled,diagonals" ]; + EF [ label = "H()", ]; + EFG2 [ label = "↓" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, style = "invis" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-009.png new file mode 100644 index 0000000000000000000000000000000000000000..5648800398e8bd9885a6d1a8785cb59c06bb716f GIT binary patch literal 7329 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 + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + +flag7 + +0 + + + + + + + + +flag_label +Flags + + +hash4 + +H4 + + + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + + + +H4 + + +G->G2 + + + +F + + + + + +H3 + + +EF + +H() + + +F->EF + + + + +E + + + + + +H2 + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + + +EFG2 + + + + +G2->EFG2 + + + + +EF->F + + + + +EF->E + + + + +EF->EFG2 + + + + +EFG2->G2 + + + + +EFG2->EF + + + + +ROOT + + + + +EFG2->ROOT + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-010.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-010.dot new file mode 100644 index 00000000..23d9e8e6 --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-010.dot @@ -0,0 +1,141 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "invis" ]; + flag6 [ label = "0", style = "invis" ]; + flag5 [ label = "1", style = "invis" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4", style = "invis" ]; + hash3 [ label = "H3", style = "invis" ]; + hash2 [ label = "H2", style = "invis" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F [ style = "diagonals", label = "H3" ]; + E [ penwidth = 4, style = "diagonals", label = "H2" ]; + D; + C; + B; + A; + + G2 [ label = "H4", style = "diagonals" ]; + EF [ label = "H()" ]; + EFG2 [ label = "H()", style = "filled" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "↓" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, dir = "back" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.dot b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.dot new file mode 100644 index 00000000..f86a9e5e --- /dev/null +++ b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.dot @@ -0,0 +1,141 @@ +digraph merkleblock { + +//size="6.25,2.22"; +size="6.25"; +rankdir=BT +nodesep=0.1 +splines="false" + +edge [ penwidth = 1.75, fontname="Sans" ] +node [ penwidth = 1.75, shape = "box", fontname="Sans", ] +graph [ penwidth = 1.75, fontname="Sans", fontsize = 16 ] + +subgraph cluster_flags { + node [ label = "", width=0.2, height=0.2, fontsize = 14, shape = "none" ]; + graph [ penwidth = 0 ]; + + flag8 [ label = "0" ]; + flag7 [ label = "0", style = "invis" ]; + flag6 [ label = "0", style = "invis" ]; + flag5 [ label = "1", style = "invis" ]; + flag4 [ label = "1", style = "invis" ]; + flag3 [ label = "1", style = "invis" ]; + flag2 [ label = "0", style = "invis" ]; + flag1 [ label = "1", style = "invis" ]; + flag_label [ label = "Flags", shape = "none", fontsize = 16 ]; +} + +subgraph cluster_hashes { + graph [ penwidth = 0 ]; + node [ shape = "none" ]; + + hash4 [ label = "H4", style = "invis" ]; + hash3 [ label = "H3", style = "invis" ]; + hash2 [ label = "H2", style = "invis" ]; + hash1 [ label = "H1", style = "invis" ]; + hash_label [ label = "Hashes", shape = "none", fontsize = 16 ]; +} + +hash_label -> flag_label [ style = "invis" ]; + +subgraph cluster_legend { + node [ label = "", fontsize = 18 ]; + graph [ penwidth = 0 ]; + edge [ style = "invis" ]; + ranksep = 3; + + + { + node [ shape = "none" ]; + matched_filter_label [ label = "TXID\nFilter\nMatch" ]; + hash_from_list_label [ label = "Hash\nFrom\nList" ]; + hash_computed_label [ label = "Hash\nCom-\nputed" ]; + waiting_label [ label = "Wait\nFor\nChild" ]; + } + + matched_filter [ penwidth = 4, style = "diagonals", bgcolor = grey ]; + hash_from_list [ label = "H1", style = "diagonals" ]; + hash_computed [ label = "H()" ]; + waiting [ label = "↓" ]; + + pre_legend_label [ label = "", style = "invis", width=0, height=0 ]; + legend_label [ label = "", style = "invis", width=0, height=0 ]; + pre_legend_label -> legend_label [ style = "invis" ]; + + waiting_label -> waiting; + hash_from_list_label -> hash_from_list; + hash_computed_label -> hash_computed; + matched_filter_label -> matched_filter; + + labelloc = b; + label = "Legend" +} + +legend_label -> hash_label [ style = "invis" ]; + +subgraph cluster_tree { + edge [ dir = "none" ]; + node [ label = "", fontsize = 16 ]; + graph [ penwidth = 0 ]; + + { + root_row [ shape = "none" ]; + row1 [ shape = "none", label = "Non-TXID\nNodes" ]; + row2 [ shape = "none", style = "invis", width = 1.2 ]; + txid_row [ label = "TXID\nNodes", shape = "none" ]; + + row2 -> row1 [ dir = "back" ]; + row1 -> root_row [ dir = ""]; + txid_row -> row2 [ style = "invis" ]; + } + + G; + F [ style = "diagonals", label = "H3" ]; + E [ penwidth = 4, style = "diagonals", label = "H2" ]; + D; + C; + B; + A; + + G2 [ label = "H4", style = "diagonals" ]; + EF [ label = "H()", ]; + EFG2 [ label = "H()" ]; + ABCD [ style = "diagonals", label = "H1" ]; + ROOT [ label = "H()", style = "filled" ]; + + A -> AB; + B -> AB; + C -> CD; + D -> CD; + E -> EF [ dir = "back" ]; + F -> EF [ dir = "back" ]; + G -> G2; + + AB -> A [ constraint = false, style = "invis" ]; + AB -> B [ constraint = false, style = "invis" ]; + CD -> C [ constraint = false, style = "invis" ]; + CD -> D [ constraint = false, style = "invis" ]; + EF -> E [ constraint = false, dir = "back" ]; + EF -> F [ constraint = false, dir = "back" ]; + G2 -> G [ constraint = false, style = "invis" ]; + + AB -> ABCD; + CD -> ABCD; + EF -> EFG2 [ dir = "back" ]; + G2 -> EFG2 [ dir = "back" ]; + + ABCD -> AB [ constraint = false, style = "invis" ]; + ABCD -> CD [ constraint = false, style = "invis" ]; + EFG2 -> EF [ constraint = false, dir = "back" ]; + EFG2 -> G2 [ constraint = false, dir = "back" ]; + + ABCD -> ROOT [ dir = "back" ]; + EFG2 -> ROOT [ dir = "back" ]; + + ROOT -> ABCD [ constraint = false, dir = "back" ]; + ROOT -> EFG2 [ constraint = false, dir = "back" ]; + +} + +//label = "Parsing A MerkleBlock Message" +} diff --git a/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.png b/img/dev/gifs/en-merkleblock-parsing/en-merkleblock-parsing-011.png new file mode 100644 index 0000000000000000000000000000000000000000..4b12af0f56cb0d37e7027320aca293990b1817e6 GIT binary patch literal 7290 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 + + + + + +merkleblock + +cluster_flags + + +cluster_hashes + + +cluster_legend + +Legend + +cluster_tree + + + +flag8 +0 + + + + + + + + + +flag_label +Flags + + + + + + +hash_label +Hashes + + + +matched_filter_label +TXID +Filter +Match + + +matched_filter + + + + + + + + +hash_from_list_label +Hash +From +List + + +hash_from_list + + + + + +H1 + + + +hash_computed_label +Hash +Com- +puted + + +hash_computed + +H() + + + +waiting_label +Wait +For +Child + + +waiting + + + + + + + + + +root_row + + +row1 +Non-TXID +Nodes + + +row1->root_row + + + + + +row2->row1 + + + + +txid_row +TXID +Nodes + + + +G + + + +G2 + + + + + +H4 + + +G->G2 + + + +F + + + + + +H3 + + +EF + +H() + + +F->EF + + + + +E + + + + + +H2 + + +E->EF + + + + +D + + + +CD + + + +D->CD + + + +C + + + +C->CD + + + +B + + + +AB + + + +B->AB + + + +A + + + +A->AB + + + + +EFG2 + +H() + + +G2->EFG2 + + + + +EF->F + + + + +EF->E + + + + +EF->EFG2 + + + + +EFG2->G2 + + + + +EFG2->EF + + + + +ROOT + +H() + + +EFG2->ROOT + + + + +ABCD + + + + + +H1 + + +ABCD->ROOT + + + + + + +ROOT->EFG2 + + + + +ROOT->ABCD + + + + + + +AB->ABCD + + + + + +CD->ABCD + + + + From 0437d7c434b93c9f9a1c317d17ad01f160e085fb Mon Sep 17 00:00:00 2001 From: Saivann Date: Fri, 14 Nov 2014 20:01:33 -0500 Subject: [PATCH 2/4] Format "protocol versions" table content to improve readability --- _includes/ref_p2p_networking.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_includes/ref_p2p_networking.md b/_includes/ref_p2p_networking.md index 006ba3a0..5f264691 100644 --- a/_includes/ref_p2p_networking.md +++ b/_includes/ref_p2p_networking.md @@ -56,11 +56,11 @@ document older protocol versions, please [open an issue][docs issue].) | Version | Implementation | Major Changes |---------|-------------------------------------|-------------- -| 70002 | Bitcoin Core 0.9.0 (March 2014) | Added `reject` message (see [BIP61][]). Send multiple `inv` messages in response to `mempool` message if necessary. -| 70001 | Bitcoin Core 0.8.0 (February 2013) | Added `filterload` message, `filteradd` message, `filterclear` message, and `merkleblock` message; also added relay field to `version` message and `MSG_FILTERED_BLOCK` inventory type to `getdata` message (see [BIP37][]). -| 60002 | Bitcoin Core 0.7.0 (September 2012) | Added `mempool` message and extended `getdata` message to allow download of memory pool transactions (see [BIP35][]). -| 60001 | Bitcoin Core 0.6.1 (May 2012) | Added `pong` message (see [BIP31][]). -| 60000 | Bitcoin Core 0.6.0 (March 2012) | Separated protocol version from Bitcoin Core version (see [BIP14][]). +| 70002 | Bitcoin Core 0.9.0
(Mar. 2014) | - Added `reject` message (see [BIP61][]).
- Send multiple `inv` messages in response to `mempool` message if necessary. +| 70001 | Bitcoin Core 0.8.0
(Feb. 2013) | - Added `filterload` message.
- Added `filteradd` message.
- Added `filterclear` message.
- Added `merkleblock` message; also added relay field to `version` message and `MSG_FILTERED_BLOCK` inventory type to `getdata` message (see [BIP37][]). +| 60002 | Bitcoin Core 0.7.0
(Sep. 2012) | - Added `mempool` message.
- Extended `getdata` message to allow download of memory pool transactions (see [BIP35][]). +| 60001 | Bitcoin Core 0.6.1
(May. 2012) | - Added `pong` message (see [BIP31][]). +| 60000 | Bitcoin Core 0.6.0
(Mar. 2012) | - Separated protocol version from Bitcoin Core version (see [BIP14][]). {% endautocrossref %} From ade6d1aca1aec0621da84d0c33f74cd9958cdd84 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sat, 15 Nov 2014 10:41:51 -0500 Subject: [PATCH 3/4] Dev Docs: Tweak Revised Protocol Versions Table Style --- _includes/ref_p2p_networking.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_includes/ref_p2p_networking.md b/_includes/ref_p2p_networking.md index 5f264691..5dc1cc4a 100644 --- a/_includes/ref_p2p_networking.md +++ b/_includes/ref_p2p_networking.md @@ -54,13 +54,13 @@ The table below lists some notable versions of the P2P network protocol, with the most recent versions listed first. (If you would like to help document older protocol versions, please [open an issue][docs issue].) -| Version | Implementation | Major Changes -|---------|-------------------------------------|-------------- -| 70002 | Bitcoin Core 0.9.0
(Mar. 2014) | - Added `reject` message (see [BIP61][]).
- Send multiple `inv` messages in response to `mempool` message if necessary. -| 70001 | Bitcoin Core 0.8.0
(Feb. 2013) | - Added `filterload` message.
- Added `filteradd` message.
- Added `filterclear` message.
- Added `merkleblock` message; also added relay field to `version` message and `MSG_FILTERED_BLOCK` inventory type to `getdata` message (see [BIP37][]). -| 60002 | Bitcoin Core 0.7.0
(Sep. 2012) | - Added `mempool` message.
- Extended `getdata` message to allow download of memory pool transactions (see [BIP35][]). -| 60001 | Bitcoin Core 0.6.1
(May. 2012) | - Added `pong` message (see [BIP31][]). -| 60000 | Bitcoin Core 0.6.0
(Mar. 2012) | - Separated protocol version from Bitcoin Core version (see [BIP14][]). +| Version | Implementation | Major Changes +|---------|------------------------------------|-------------- +| 70002 | Bitcoin Core 0.9.0
(Mar 2014) | • Send multiple `inv` messages in response to a `mempool` message if necessary

[BIP61][]:
• Added `reject` message +| 70001 | Bitcoin Core 0.8.0
(Feb 2013) | [BIP37][]:
• Added `filterload` message.
• Added `filteradd` message.
• Added `filterclear` message.
• Added `merkleblock` message.
• Added relay field to `version` message
• Added `MSG_FILTERED_BLOCK` inventory type to `getdata` message. +| 60002 | Bitcoin Core 0.7.0
(Sep 2012) | [BIP35][]:
• Added `mempool` message.
• Extended `getdata` message to allow download of memory pool transactions +| 60001 | Bitcoin Core 0.6.1
(May 2012) | [BIP31][]:
• Added `pong` message +| 60000 | Bitcoin Core 0.6.0
(Mar 2012) | [BIP14][]:
• Separated protocol version from Bitcoin Core version {% endautocrossref %} From 9ee7b8b73b88850d5e75c6488316d8513173d8d5 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sat, 15 Nov 2014 12:12:56 -0500 Subject: [PATCH 4/4] Dev Docs: Fix Typos/Confusions In P2P Data Messages As Reported By @saivann (Thanks!) --- _includes/ref_p2p_networking.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_includes/ref_p2p_networking.md b/_includes/ref_p2p_networking.md index 5dc1cc4a..3429b2f0 100644 --- a/_includes/ref_p2p_networking.md +++ b/_includes/ref_p2p_networking.md @@ -101,7 +101,7 @@ transactions and blocks. ![Overview Of P2P Protocol Data Request And Reply Messages](/img/dev/en-p2p-data-messages.svg) Many of the data messages use -[inventories][inventory]{:#term-inventory}{:.term} as unique identifiers for +[inventories][inventory]{:#term-inventory}{:.term} as unique identifiers for transactions and blocks. Inventories have a simple 36-byte structure: @@ -167,7 +167,7 @@ starting with block one (the first block after the genesis block). | 4 | version | uint32_t | The protocol version number; the same as sent in the `version` message. | *Varies* | hash count | compactSize uint | The number of header hashes provided not including the stop hash. There is no limit except that the byte size of the entire message must be below the [`MAX_SIZE`][max_size] limit; typically from 1 to 200 hashes are sent. | *Varies* | block header hashes | char[32] | One or more block header hashes (32 bytes each) in internal byte order. Hashes should be provided in reverse order of block height, so highest-height hashes are listed first and lowest-height hashes are listed last. -| 32 | stop hash | char[32] | The header hash of the last header hash being requested; set to all zeroes to request an `inv` message with 500 header hashes (the maximum which will ever be sent as a reply to this message). +| 32 | stop hash | char[32] | The header hash of the last header hash being requested; set to all zeroes to request an `inv` message with all subsequent header hashes (a maximum of 500 will be sent as a reply to this message; if you need more than 500, you will need to send another `getblocks` message with a higher-height header hash as the first entry in block header hash field). The following annotated hexdump shows a `getblocks` message. (The message header has been omitted.) @@ -250,7 +250,7 @@ b6ff0b1b1680a2862a30ca44d346d9e8 30c31b18 ........................... Target (bits) fe9f0864 ........................... Nonce -00 ......... Transaction Count (0x00) +00 ................................. Transaction count (0x00) {% endhighlight %} {% endautocrossref %} @@ -295,7 +295,7 @@ a055aaf1d872e94ae85e9817b2c68dc7 ... Hash (TXID) {% autocrossref %} The `mempool` message requests the TXIDs of transactions that the -receiving node has verified are valid but which have not yet appeared in +receiving node has verified as valid but which have not yet appeared in a block. That is, transactions which are in the receiving node's memory pool. The response to the `mempool` message is one or more `inv` messages containing the TXIDs in the usual inventory format. The @@ -351,7 +351,7 @@ This message is part of the bloom filters described in BIP37, added in protocol version 70001 and implemented in Bitcoin Core 0.8.0 (February 2013). -If a filter has been previous set with the `filterload` message, the +If a filter has been previously set with the `filterload` message, the `merkleblock` message will contain the TXIDs of any transactions in the requested block that matched the filter, as well as any parts of the block's merkle tree necessary to connect those transactions to the @@ -401,7 +401,7 @@ bb3183301d7a1fb3bd174fcfa40a2b65 ... Hash #2 Note: when fully decoded, the above `merkleblock` message provided the TXID for a single transaction that matched the filter. In the network traffic dump this output was taken from, the full transaction belonging -to that TXID was sent immediately after the the `merkleblock` message as +to that TXID was sent immediately after the `merkleblock` message as a `tx` message. **Parsing A MerkleBlock** @@ -433,7 +433,7 @@ flag again. | **0** | Use the next hash as this node's TXID, but this transaction didn't match the filter. | Use the next hash as this node's hash. Don't process any descendant nodes. | **1** | Use the next hash as this node's TXID, and mark this transaction as matching the filter. | The hash needs to be computed. Process the left child node to get its hash; process the right child node to get its hash; then concatenate the two hashes as 64 raw bytes and hash them to get this node's hash. -Any time you descend into a node for the first time, evaluate the next +Any time you begin processing a node for the first time, evaluate the next flag. Never use a flag at any other time. When processing a child node, you may need to process its children (the @@ -462,7 +462,7 @@ following checks (order doesn't matter): * Fail if there are unused flag bits---except for the minimum number of bits necessary to pad up to the next full byte. -* Fail unless the hash of the merkle root node is identical to the +* Fail if the hash of the merkle root node is not identical to the merkle root in the block header. * Fail if the block header is invalid. Remember to ensure that the hash @@ -498,7 +498,7 @@ match ancestor. | **Neither Match Nor Match Ancestor** | Append a 0 to the flag list; append this node's TXID to the hash list. | Append a 0 to the flag list; append this node's hash to the hash list. Do not descend into its child nodes. | **Match Or Match Ancestor** | Append a 1 to the flag list; append this node's TXID to the hash list. | Append a 1 to the flag list; process the left child node. Then, if the node has a right child, process the right child. Do not append a hash to the hash list for this node. -Any time you descend into a node for the first time, a flag should be +Any time you begin processing a node for the first time, a flag should be appended to the flag list. Never put a flag on the list at any other time, except when processing is complete to pad out the flag list to a byte boundary. @@ -512,7 +512,7 @@ a match ancestor. After you process a TXID node or a node which is neither a TXID nor a match ancestor, stop processing and begin to ascend the tree until you find a node with a right child you haven't processed yet. Descend into -that right child and begin processing again. +that right child and process it. After you fully process the merkle root node according to the instructions in the table above, processing is complete. Pad your flag