content - p2p - Update compact block messages

- Add some info from bitcoin-dot-org/bitcoin.org#2092
  - Add detail to cmpctblock, sendcmpct, getblocktxn, blocktxn messages
  - Add reference terms
This commit is contained in:
thephez 2018-04-23 16:48:36 -04:00
parent 53531a8d73
commit edfa3226a0
No known key found for this signature in database
GPG key ID: BBC8A06DBE236099
2 changed files with 104 additions and 27 deletions

View file

@ -172,7 +172,7 @@ The currently-available type identifiers are:
| 17 | [`MSG_GOVERNANCE_OBJECT`][msg_governance_object]{:#term-msg_governance_object}{:.term} | The hash is a Governance Object. | 17 | [`MSG_GOVERNANCE_OBJECT`][msg_governance_object]{:#term-msg_governance_object}{:.term} | The hash is a Governance Object.
| 18 | [`MSG_GOVERNANCE_OBJECT_VOTE`][msg_governance_object_vote]{:#term-msg_governance_object_vote}{:.term} | The hash is a Governance Object Vote. | 18 | [`MSG_GOVERNANCE_OBJECT_VOTE`][msg_governance_object_vote]{:#term-msg_governance_object_vote}{:.term} | The hash is a Governance Object Vote.
| 19 | [`MSG_MASTERNODE_VERIFY`][msg_masternode_verify]{:#term-msg_masternode_verify}{:.term} | The hash is a Masternode Verify. | 19 | [`MSG_MASTERNODE_VERIFY`][msg_masternode_verify]{:#term-msg_masternode_verify}{:.term} | The hash is a Masternode Verify.
| 20 | [`MSG_CMPCT_BLOCK`][msg_cmpct_block]{:#term-msg_cmpct_block}{:.term} | The hash is of a compact block. | 20 | [`MSG_CMPCT_BLOCK`][msg_cmpct_block]{:#term-msg_cmpct_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 `cmpctblock` message. **Only for use in `getdata` messages.**
Type identifier zero and type identifiers greater than twenty are reserved Type identifier zero and type identifiers greater than twenty are reserved
for future implementations. Dash Core ignores all inventories with for future implementations. Dash Core ignores all inventories with
@ -211,7 +211,20 @@ different reasons:
*Added in protocol version 70209 of Dash Core as described by BIP152* *Added in protocol version 70209 of Dash Core as described by BIP152*
The `blocktxn` message sends requested block transactions to a node which The `blocktxn` message sends requested block transactions to a node which
previously requested them with a `getblocktxn` message. previously requested them with a `getblocktxn` message. It is defined as a message
containing a serialized `BlockTransactions` message.
Upon receipt of a properly-formatted requested `blocktxn` message, nodes should:
1. Attempt to reconstruct the full block by taking the prefilledtxn transactions from the original `cmpctblock` message and placing them in the marked positions
2. For each short transaction ID from the original `cmpctblock` message, in order, find the corresponding transaction (from either the `blocktxn` message or from other sources)
3. Place each short transaction ID in the first available position in the block
4. Once the block has been reconstructed, it shall be processed as normal.
**Short transaction IDs are expected to occasionally collide. Nodes must
not be penalized for such collisions.**
The structure of `BlockTransactions` is defined below.
| Bytes | Name | Data Type | Encoding | Description| | Bytes | Name | Data Type | Encoding | Description|
|----------|----------------------|----------------------|----------|------------| |----------|----------------------|----------------------|----------|------------|
@ -235,39 +248,63 @@ message header has been omitted.)
*Added in protocol version 70209 of Dash Core as described by BIP152* *Added in protocol version 70209 of Dash Core as described by BIP152*
The `cmpctblock` message transmits a single serialized compact block. A The `cmpctblock` message is a reply to a `getdata` message which
`HeaderAndShortIDs` structure is used to relay a block header, the short requested a block using the inventory type `MSG_CMPCT_BLOCK`. If the
transactions IDs used for matching already-available transactions, and a select requested block was recently announced and is close to the tip of the
few transactions which we expect a peer may be missing (PrefilledTransactions). best chain of the receiver and after having sent the requesting peer
It can be sent for two different reasons: a `sendcmpct` message, nodes respond with a `cmpctblock` message containing
data for the block.
1. **GetData Response:** Nodes will always send it in response to a **If the requested block is too old, the node responds with a *full non-compact block***
`getdata` message that requests the block with an inventory
type of `MSG_CMPCT_BLOCK` (provided the node has that block available for
relay).
2. **Unsolicited:** If a node has previously sent a `sendcmpct` message Upon receipt of a `cmpctblock` message, after sending a `sendcmpct` message,
requesting blocks be announced via a `cmpctblock` message. nodes should calculate the short transaction ID for each unconfirmed
transaction they have available (i.e. in their mempool) and compare each
to each short transaction ID in the `cmpctblock` message. After finding
already-available transactions, nodes which do not have all transactions
available to reconstruct the full block should request the missing transactions
using a `getblocktxn` message.
**HeaderAndShortIDs** A node must not send a `cmpctblock` message unless they are able to respond to
a `getblocktxn` message which requests every transaction in the block. A node
must not send a `cmpctblock` message without having validated that the header properly
commits to each transaction in the block, and properly builds on top of the existing,
fully-validated chain with a valid proof-of-work either as a part of the current most-work
valid chain, or building directly on top of it. A node may send a `cmpctblock` message before
validating that each transaction in the block validly spends existing UTXO set entries.
The `cmpctblock` message contains a vector of `PrefilledTransaction` whose
structure is defined below. A `PrefilledTransaction` is used in `HeaderAndShortIDs`
to provide a list of a few transactions explicitly.
| Bytes | Name | Data Type | Encoding | Description|
|----------|----------------------|----------------------|----------|------------|
| 1 or 3 | index | CompactSize | Compact Size, differentially encoded since the last PrefilledTransaction in a list | The index into the block at which this transaction is
| *Varies* | tx | Transaction | As encoded in `tx` messages sent in response to `getdata MSG_TX` | Transaction which is in the block at index `index`
The `cmpctblock` message is compromised of a serialized `HeaderAndShortIDs`
structure which is defined below. A `HeaderAndShortIDs` structure is used to
relay a block header, the short transactions IDs used for matching
already-available transactions, and a select few transactions which
we expect a peer may be missing.
| Bytes | Name | Data Type | Encoding | Description| | Bytes | Name | Data Type | Encoding | Description|
|----------|----------------------|----------------------|----------|------------| |----------|----------------------|----------------------|----------|------------|
| 80 | header | Block header | First 80 bytes of the block as defined by the encoding used by `block` messages | The header of the block being provided | 80 | header | Block header | First 80 bytes of the block as defined by the encoding used by `block` messages | The header of the block being provided
| 8 | nonce | uint64_t | Little Endian | A nonce for use in short transaction ID calculations | 8 | nonce | uint64_t | Little Endian | A nonce for use in short transaction ID calculations
| 1 or 3 | shortids_<br>length | CompactSize | As used to encode array lengths elsewhere | The number of short transaction IDs in `shortids` (i.e. block tx count - `prefilledtxn`<br>`_length`) | 1 or 3 | shortids_<br>length | CompactSize | As used to encode array lengths elsewhere | The number of short transaction IDs in `shortids` (i.e. block tx count - `prefilledtxn`<br>`_length`)
| 6 * `shortids`<br>`_length` | shortids | List of 6-byte integers | Little Endian | The short transaction IDs calculated from the transactions which were not provided explicitly in `prefilledtxn` | *Varies* | shortids | List of 6-byte integers | Little Endian | The short transaction IDs calculated from the transactions which were not provided explicitly in `prefilledtxn`
| 1 or 3 | prefilledtxn<br>_length | CompactSize | As used to encode array lengths elsewhere | The number of prefilled transactions in `prefilledtxn` (i.e. block tx count - `shortids`<br>`_length`) | 1 or 3 | prefilledtxn<br>_length | CompactSize | As used to encode array lengths elsewhere | The number of prefilled transactions in `prefilledtxn` (i.e. block tx count - `shortids`<br>`_length`)
| *Varies* * `prefilledtxn`<br>`_length` | prefilledtxn | List of Prefilled<br>Transactions | As defined by `Prefilled`<br>`Transaction` definition below | Used to provide the coinbase transaction and a select few which we expect a peer may be missing | *Varies* | prefilledtxn | List of Prefilled<br>Transactions | As defined by `Prefilled`<br>`Transaction` definition below | Used to provide the coinbase transaction and a select few which we expect a peer may be missing
**PrefilledTransaction** **Short Transaction ID calculation**
A `PrefilledTransaction` structure is used in `HeaderAndShortIDs` to provide a list of a few transactions explicitly. Short transaction IDs are used to represent a transaction without sending a full 256-bit hash. They are calculated as follows,
| Bytes | Name | Data Type | Encoding | Description| * A single-SHA256 hashing the block header with the nonce appended (in little-endian)
|----------|----------------------|----------------------|----------|------------| * Running SipHash-2-4 with the input being the transaction ID and the keys (k0/k1) set to the first two little-endian 64-bit integers from the above hash, respectively.
| 1 or 3 | index | CompactSize | Compact Size, differentially encoded since the last PrefilledTransaction in a list | The index into the block at which this transaction is * Dropping the 2 most significant bytes from the SipHash output to make it 6 bytes.
| *Varies* | tx | Transaction | As encoded in `tx` messages sent in response to `getdata MSG_TX` | Transaction which is in the block at index `index` <!-- * Two null-bytes appended so it can be read as an 8-byte integer. -->
The following annotated hexdump shows a `cmpctblock` message. (The The following annotated hexdump shows a `cmpctblock` message. (The
message header has been omitted.) message header has been omitted.)
@ -384,13 +421,24 @@ d39f608a7775b537729884d4e6633bb2
*Added in protocol version 70209 of Dash Core as described by BIP152* *Added in protocol version 70209 of Dash Core as described by BIP152*
The `getblocktxn` message requests a `blocktxn` message for any transactions The `getblocktxn` message requests a `blocktxn` message for any transactions
that it has not seen after a compact block is received. that it has not seen after a compact block is received. It is defined as a
message containing a serialized `BlockTransactionsRequest` message. Upon receipt
of a properly-formatted `getblocktxn` message, nodes which recently provided the
sender of such a message with a `cmpctblock` message for the block hash
identified in this message must respond with either an appropriate
`blocktxn` message, or a full block message.
A `blocktxn` message response must contain exactly and only each transaction
which is present in the appropriate block at the index specified in the
`getblocktxn` message indexes list, in the order requested.
The structure of `BlockTransactionsRequest` is defined below.
| Bytes | Name | Data Type | Encoding | Description| | Bytes | Name | Data Type | Encoding | Description|
|----------|-----------------|----------------------|----------|------| |----------|-----------------|----------------------|----------|------|
| 32 | blockhash | Binary blob | The output from a double-SHA256 of the block header, as used elsewhere | The blockhash of the block which the transactions being requested are in | 32 | blockhash | Binary blob | The output from a double-SHA256 of the block header, as used elsewhere | The blockhash of the block which the transactions being requested are in
| 1 or 3 | indexes_length | CompactSize | As used to encode array lengths elsewhere | The number of transactions requested | *Varies* | indexes_length | CompactSize uint | As used to encode array lengths elsewhere | The number of transactions requested
| (1 or 3) * `indexes_length` | indexes | List of CompactSizes | Differentially encoded | The indexes of the transactions being requested in the block | *Varies* | indexes | CompactSize uint[] | Differentially encoded | Vector of compactSize containing the indexes of the transactions being requested in the block.
The following annotated hexdump shows a `getblocktxn` message. (The The following annotated hexdump shows a `getblocktxn` message. (The
message header has been omitted.) message header has been omitted.)
@ -1445,7 +1493,32 @@ header has been omitted.)
The `sendcmpct` message tells the receiving peer whether or not to announce new The `sendcmpct` message tells the receiving peer whether or not to announce new
blocks using a `cmpctblock` message. It also sends the compact block protocol blocks using a `cmpctblock` message. It also sends the compact block protocol
version it supports. version it supports. The `sendcmpct` message is defined as a message containing
a 1-byte integer followed by a 8-byte integer. The first integer is interpreted
as a boolean and should have a value of either 1 or 0. The second integer
is be interpreted as a little-endian version number.
Upon receipt of a `sendcmpct` message with the first and second integers
set to 1, the node should announce new blocks by sending a `cmpctblock` message.
Upon receipt of a `sendcmpct` message with the first integer set to 0, the node
shouldn't announce new blocks by sending a `cmpctblock` message, but instead announce
new blocks by sending invs or headers, as defined by [BIP130][].
Upon receipt of a `sendcmpct` message with the second integer set to something
other than 1, nodes should treat the peer as if they had not received the message
(as it indicates the peer will provide an unexpected encoding in `cmpctblock` messages,
and/or other, messages). This allows future versions to send duplicate
`sendcmpct` messages with different versions as a part of a version handshake.
Nodes should check for a protocol version of >= 70209 before sending `sendcmpct`
messages. Nodes shouldn't send a request for a `MSG_CMPCT_BLOCK` object to a peer
before having received a `sendcmpct` message from that peer. Nodes shouldn't
request a `MSG_CMPCT_BLOCK` object before having sent all `sendcmpct` messages
to that peer which they intend to send, as the peer cannot know what protocol
version to use in the response.
The structure of a `sendcmpct` message is defined below.
| Bytes | Name | Data Type | Description | Bytes | Name | Data Type | Description
|----------|---------------|------------------|-------------- |----------|---------------|------------------|--------------

View file

@ -4,8 +4,11 @@ http://opensource.org/licenses/MIT.
{% endcomment %} {% endcomment %}
{% comment %}<!-- Terms; must have tooltip description in "quotes"; alphabetical order -->{% endcomment %} {% comment %}<!-- Terms; must have tooltip description in "quotes"; alphabetical order -->{% endcomment %}
[blocktransactions]: /en/developer-reference#blocktxn "A P2P Networking data structure used to provide some of the transactions in a block as requested"
[blocktransactionsrequest]: /en/developer-reference#getblocktxn "A P2P Networking data structure used to list transaction indexes in a block being requested by a peer"
[coinbase block height]: /en/developer-reference#term-coinbase-block-height "The current block's height encoded into the first bytes of the coinbase field" [coinbase block height]: /en/developer-reference#term-coinbase-block-height "The current block's height encoded into the first bytes of the coinbase field"
[data-pushing opcode]: https://en.bitcoin.it/wiki/Script#Constants "Any opcode from 0x01 to 0x4e which pushes data on to the script evaluation stack" [data-pushing opcode]: https://en.bitcoin.it/wiki/Script#Constants "Any opcode from 0x01 to 0x4e which pushes data on to the script evaluation stack"
[headerandshortids]: /en/developer-reference#cmpctblock "A P2P Networking data structure used to relay a block header, the short transactions IDs used for matching already-available transactions, and a select few transactions which a peer may be missing"
[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 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" [key pair]: /en/developer-guide#term-key-pair "A private key and its derived public key"
<!-- Inventory Messages --> <!-- Inventory Messages -->
@ -29,7 +32,7 @@ http://opensource.org/licenses/MIT.
[msg_governance_object]: /en/developer-reference#term-msg_governance_object "Governance object data type identifier of an inventory on the P2P network" [msg_governance_object]: /en/developer-reference#term-msg_governance_object "Governance object data type identifier of an inventory on the P2P network"
[msg_governance_object_vote]: /en/developer-reference#term-msg_governance_object_vote "Governance object vote data type identifier of an inventory on the P2P network" [msg_governance_object_vote]: /en/developer-reference#term-msg_governance_object_vote "Governance object vote data type identifier of an inventory on the P2P network"
[msg_masternode_verify]: /en/developer-reference#term-msg_masternode_verify "Masternode Verify data type identifier of an inventory on the P2P network" [msg_masternode_verify]: /en/developer-reference#term-msg_masternode_verify "Masternode Verify data type identifier of an inventory on the P2P network"
[msg_cmpct_block]: /en/developer-reference#term-msg_cmpct_block "Compact Block data type identifier of an inventory on the P2P network" [msg_cmpct_block]: /en/developer-reference#term-msg_cmpct_block "An alternative to the block header hash data type identifier of an inventory on the P2P network used to request a compact block"
[network]: /en/developer-guide#term-network "The Dash P2P network which broadcasts transactions and blocks" [network]: /en/developer-guide#term-network "The Dash P2P network which broadcasts transactions and blocks"
[op_checkmultisig]: /en/developer-reference#term-op-checkmultisig "Opcode 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_checkmultisig]: /en/developer-reference#term-op-checkmultisig "Opcode 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)"
@ -42,6 +45,7 @@ http://opensource.org/licenses/MIT.
[op_verify]: /en/developer-reference#term-op-verify "Operation which terminates the script if the entry below it on the stack is non-true (zero)" [op_verify]: /en/developer-reference#term-op-verify "Operation which terminates the script if the entry below it on the stack is non-true (zero)"
[output index]: /en/developer-guide#term-output-index "The sequentially-numbered index of outputs in a single transaction starting from 0" [output index]: /en/developer-guide#term-output-index "The sequentially-numbered index of outputs in a single transaction starting from 0"
[point function]: /en/developer-guide#term-point-function "The ECDSA function used to create a public key from a private key" [point function]: /en/developer-guide#term-point-function "The ECDSA function used to create a public key from a private key"
[prefilledtransaction]: /en/developer-reference#cmpctblock "A P2P Networking data structure used to represent a vector of a few transactions"
[previous block header hash]: /en/developer-reference#term-previous-block-header-hash "A field in the block header which contains the SHA256(SHA256()) hash of the previous block's header" [previous block header hash]: /en/developer-reference#term-previous-block-header-hash "A field in the block header which contains the SHA256(SHA256()) hash of the previous block's header"
[proper money handling]: /en/developer-reference#term-proper-money-handling "Bitcoin amounts need to be correctly processed without introducing rounding errors that could cause monetary loss" [proper money handling]: /en/developer-reference#term-proper-money-handling "Bitcoin amounts need to be correctly processed without introducing rounding errors that could cause monetary loss"
[standard block relay]: /en/developer-guide#term-standard-block-relay "The regular block relay method: announcing a block with an inv message and waiting for a response" [standard block relay]: /en/developer-guide#term-standard-block-relay "The regular block relay method: announcing a block with an inv message and waiting for a response"