You've already forked specification
move p2p messages
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"ADDR",
|
||||||
|
"related":["/protocol","/protocol/p2p/getaddr"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
Provide information about other prospective P2P protocol peers. Peers SHOULD not send this message unsolicited, and nodes that receive an unsolicited ADDR message MUST ignore it. This behavior helps prevent eclipse and partitioning attacks by not allowing an attacker to aggressively seed peer connection tables with its own nodes.
|
||||||
|
|
||||||
|
| compact int | 4 bytes | 8 bytes | 16 bytes | 2 bytes |
|
||||||
|
|----------------------------------------|---------|----------|----------|---------|
|
||||||
|
|[vector](/protocol/p2p/vector) size N of| time | services | IP address | port
|
||||||
|
|
||||||
|
*services* is a bit field describing supported functionality, that is also used in the [version](/protocol/p2p/version) message. See [services field](/protocol/p2p/services__field) for bit definitions.
|
||||||
|
|
||||||
|
*time* is a 4 byte unsigned little-endian integer denoting the last time in epoch seconds that this node was known to be "live".
|
||||||
|
|
||||||
|
*IP address* is the IPv4 or IPv6 address of the prospective node.
|
||||||
|
|
||||||
|
*port* is the IP port of the prospective node, serialized as an unsigned 2 byte big-endian value.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"FILTERADD",
|
||||||
|
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
Add an entry into the installed bloom filter.
|
||||||
|
|
||||||
|
| compact int | N bytes |
|
||||||
|
|-------------|---------|
|
||||||
|
|[vector](/protocol/p2p/vector) size N of| data
|
||||||
|
|
||||||
|
*data* is inserted into the bloom filter, exactly as if the [insert](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/bloom.cpp#L116) operation had been called locally before sending the filter.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"FILTERCLEAR",
|
||||||
|
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
Remove the installed bloom filter, and therefore disable bloom filtering.
|
||||||
|
|
||||||
|
This message has no contents.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"INV",
|
||||||
|
"related":["/protocol","/protocol/p2p/filterclear", "/protocol/p2p/inv", "/protocol/p2p/MERKLEBLOCK"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
|
||||||
|
*Inserts a transaction and merkle block filter into the peer*
|
||||||
|
|
||||||
|
| up to 36000 bytes |
|
||||||
|
|-------------------|
|
||||||
|
| [bloom filter](objects/bloom_filter) |
|
||||||
|
|
||||||
|
### Effect on Transactions
|
||||||
|
|
||||||
|
This message installs a bloom filter into the peer. Subsequent INV notifications and MERKLEBLOCK messages only provide transactions that in match this bloom filter in some manner. The following items in a transaction are checked against the bloom filter:
|
||||||
|
|
||||||
|
- The transaction hash
|
||||||
|
- Each data field in every [output script](glossary/output__script) in the transaction
|
||||||
|
- Most importantly, this allows public keys and public key hashes (essentially bitcoin addresses) to be added to the bloom filter, allowing a wallet to detect an incoming transfer.
|
||||||
|
- Each [previous output](glossary/previous__output) in the transaction
|
||||||
|
- This allows a wallet to detect that a different wallet has spent funds that are co-controlled
|
||||||
|
- Each data field in every [input script](glossary/input__script) in the transaction.
|
||||||
|
|
||||||
|
See [CBloomFilter::MatchAndInsertOutputs](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/bloom.cpp#L186), and [CBloomFilter::MatchInputs](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/bloom.cpp#L234)
|
||||||
|
|
||||||
|
### Effect on Merkle Blocks
|
||||||
|
|
||||||
|
If a [filtered block](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/protocol.h#L483) is requested via in [INV](/protocols/p2p/inv) message, the installed bloom filter is used to choose which transactions are included in the response using the same matching algorithm as described above for transaction INVs.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"GETBLOCKS",
|
||||||
|
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/getheaders"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
Request the sequence of blocks that occur after a specific block. If the specified block is on the server's most-work chain, the server responds with a set of up to 500 [INV](/protocol/p2p/inv) messages identifying the next blocks on that chain. If the specified block is not on the most-work chain, the server uses block information in the *locator* structure to determine the fork point and provides [INV](/protocol/p2p/inv) messages from that point.
|
||||||
|
|
||||||
|
| locator | stop at hash |
|
||||||
|
|-----------------------------------------------------------------------------------------------|----------|
|
||||||
|
| [vector](/protocol/p2p/vector) of 32 byte block [hash identifiers](/glossary/hash__identifier)| 32 bytes |
|
||||||
|
|
||||||
|
|
||||||
|
### Locator
|
||||||
|
|
||||||
|
See [GETHEADERS](/protocol/p2p/getheaders) for a detailed description of the Locator object.
|
||||||
|
|
||||||
|
The response will begin at **the child of** the first hash in the locator list that matches a block hash identifier held by the responder. If no hashes match, there will be no INV messages sent.
|
||||||
|
|
||||||
|
*Use an empty locator to get an INV for block 1, and GETHEADERS that block to discover the genesis block hash in the prevBlock field*
|
||||||
|
|
||||||
|
### Stop At Hash
|
||||||
|
|
||||||
|
The sender will stop sending INVs if it encounters this hash. If the hash is never encountered, the sender will stop after 500 INV messages or when it hits the blockchain tip.
|
||||||
|
|
||||||
|
Server Implementations: [Bitcoin Unlimited](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/net_processing.cpp#L1077)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"GETDATA",
|
||||||
|
"related":["/protocol","/protocol/p2p/inv"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
Requests information (generally previously announced via an INV) from a peer.
|
||||||
|
|
||||||
|
A GETDATA request is formatted as a vector of INV data:
|
||||||
|
|
||||||
|
| compact int | 4 bytes | 32 bytes | ... | additional objects |
|
||||||
|
|---------------|-----------|------------|--|------|
|
||||||
|
| [vector](/protocol/p2p/vector) size N elements of | element 1 type | element 1 hash | ... | element N type and hash
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
The type of the desired object. See [INV](/protocol/p2p/inv) for specific values
|
||||||
|
|
||||||
|
### Hash
|
||||||
|
The [hash identifier](glossary/hash__identifier) of the desired object.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<div class="cwikmeta">
|
||||||
|
{
|
||||||
|
"title":"GETHEADERS",
|
||||||
|
"related":["/protocol"]
|
||||||
|
} </div>
|
||||||
|
|
||||||
|
Request a sequence of block hash identifiers
|
||||||
|
|
||||||
|
| locator | stop at hash |
|
||||||
|
|-----------------------------------------------------------------------------------------------|----------|
|
||||||
|
| [vector](/protocol/p2p/vector) of 32 byte block [hash identifiers](/glossary/hash__identifier)| 32 bytes |
|
||||||
|
|
||||||
|
|
||||||
|
### Locator
|
||||||
|
|
||||||
|
The locator is an array of block hash identifiers whose purpose is to communicate a position in a blockchain that may be forked from the blockchain that the receiver sees as having the most work. It does so by providing a series of block hash identifiers ranging from the desired height to the genesis block. The locator solves both major currency forks and minor forks caused by near-simultaneous block discovery.
|
||||||
|
|
||||||
|
The first hash in the locator is the parent of the desired identifiers. Subsequent elements are ancestors of previous elements, chosen by the client. A common strategy is to provide M direct ancestors and then make the M+Nth element the 2^Nth ancestor, finishing with the genesis block. This results in an amount of data that is approximately the log of the length of the chain ([C++](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/chain.cpp#L32)).
|
||||||
|
|
||||||
|
The response will begin at **the child of** the first hash in the locator list that matches a block hash identifier held by the responder. If no hashes match, the response will begin at block height 1 (child of the genesis block).
|
||||||
|
|
||||||
|
If the locator has no entries, the locator is ignored (see Stop At Hash).
|
||||||
|
|
||||||
|
*Use a valid locator whose first element is your chain tip and a zero "Stop At Hash" to request up to 2000 headers that extend your chain tip.*
|
||||||
|
|
||||||
|
### Stop At Hash
|
||||||
|
|
||||||
|
If a non-empty locator is provided, when constructing a response message, the sender will stop at the provided hash. If the hash is never encountered, the sender will stop after 2000 block hash identifiers are included in the reply.
|
||||||
|
|
||||||
|
If the locator is empty, the response includes only the header identified by this field (note it **includes** this hash, which differs from the behavior of the locator). In this case, if this hash is not found in the blockchain, the request is silently ignored.
|
||||||
|
|
||||||
|
*Use an empty locator and a valid block hash identifier to request the header of a specific block.*
|
||||||
|
|
||||||
|
Server Implementations: [Bitcoin Unlimited](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/net_processing.cpp#L1131)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"HEADERS",
|
||||||
|
"related":["/protocol","/protocol/p2p/getheaders"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
*Provides a contiguous set of block headers*
|
||||||
|
|
||||||
|
## HEADERS Message Format
|
||||||
|
|
||||||
|
|Size in bytes|Description|Data type|
|
||||||
|
|-------------|-----------|---------|
|
||||||
|
|1+ | Number of headers | varint|
|
||||||
|
|(81 + (1+)) * count |[Block headers](/protocol/blockchain/block/block-header/) and number of txs in the block|Blockheader + varint|
|
||||||
|
|
||||||
|
No more than 2000 block headers may be sent at one time. Block headers in this array MUST be sequential, ordered by height and without range gaps.
|
||||||
|
|
||||||
|
The number of txs in header is **DEPRECATED** and should be ignored. Nodes are allowed to send 0 regardless of the actual number of transactions in the block.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"INV",
|
||||||
|
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
*Notifies peers about the existence of some information (block or transaction)*
|
||||||
|
Based on selected services in the [VERSION]("/protocol/p2p/version") message, INV messages may not be sent.
|
||||||
|
|
||||||
|
If a bloom filter has been sent to this node via [FILTERLOAD](/protocol/p2p/filterload), transaction INVs will only be sent if they match the bloom filter.
|
||||||
|
|
||||||
|
| compact int | 4 bytes | 32 bytes |... | 4 bytes | 32 bytes |
|
||||||
|
|----------|---------|----------|---|---------|----------|
|
||||||
|
|[vector](/protocol/p2p/vector) size N of| type 1 | hash 1 | | type N | hash N
|
||||||
|
|
||||||
|
NOTE: Since a block header is a relatively small data structure, and block propagation speed is an important network metric, a peer may send HEADER messages in place of INV messages when a block arrives.
|
||||||
|
|
||||||
|
##### Type
|
||||||
|
The type of the object that is available.
|
||||||
|
|
||||||
|
| Type | Value|
|
||||||
|
|------|------|
|
||||||
|
| 1 | Transaction |
|
||||||
|
| 2 | Block |
|
||||||
|
| 3 | Filtered Block (partial block with merkle proof)
|
||||||
|
| 4 | Compact block
|
||||||
|
| 5 | Xthin block (Bitcoin Unlimited)
|
||||||
|
| 6 | Graphene Block (Bitcoin Unlimited)
|
||||||
|
|
||||||
|
Implementations: [C++](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/protocol.h#L477)
|
||||||
|
|
||||||
|
##### Hash
|
||||||
|
The [hash identifier](/glossary/hash__identifier) of the available object.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"MERKLEBLOCK",
|
||||||
|
"related":["/protocol", "/protocol/p2p/filteradd"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
*Provides a block header and partial merkle proof tree to show that selected transaction ids exist in the block.*
|
||||||
|
|
||||||
|
Transactions are selected by honest servers if they match the bloom filter installed by the client. However, note that servers can omit transactions and this cannot be detected except by receiving a MERKLEBLOCK message from an honest server.
|
||||||
|
|
||||||
|
All selected transactions are subsequently sent as separate TX messages. Due to multi-threading on the server, clients should not assume that these TX messages directly follow the MERKLEBLOCK message.
|
||||||
|
|
||||||
|
**MERKLEBLOCK Message Format**
|
||||||
|
|
||||||
|
| ... | 4 bytes | ... | ...|
|
||||||
|
|----|---------------|-----------|------------|
|
||||||
|
| [block header](/protocol/p2p/block__header)| # tx in block | [vector](/protocol/p2p/vector) of 32 byte hashes | [vector](/protocol/p2p/vector) of bytes that define the merkle block traversal
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="cwikmeta" style="visibility:hidden;">
|
||||||
|
{
|
||||||
|
"title":"PING",
|
||||||
|
"related":["/protocol/p2p/pong"]
|
||||||
|
} </div>
|
||||||
|
|
||||||
|
Connection keep-alive, "aliveness" and latency discovery.
|
||||||
|
|
||||||
|
| nonce |
|
||||||
|
|---------|
|
||||||
|
| 8 bytes |
|
||||||
|
|
||||||
|
If a node receives a PING message, it replies as quickly as possible with a [PONG](/protocol/p2p/pong) message with the provided *nonce*.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="cwikmeta" style="visibility:hidden;">
|
||||||
|
{
|
||||||
|
"title":"PONG",
|
||||||
|
"related":["/protocol/p2p/ping"]
|
||||||
|
} </div>
|
||||||
|
|
||||||
|
Connection keep-alive, "aliveness" and latency discovery.
|
||||||
|
|
||||||
|
| nonce |
|
||||||
|
|---------|
|
||||||
|
| 8 bytes |
|
||||||
|
|
||||||
|
This message is sent in response to a [PING](/protocol/p2p/ping) message.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<div class="cwikmeta">{
|
||||||
|
"title":"REJECT",
|
||||||
|
"related":["/protocol"]
|
||||||
|
}</div>
|
||||||
|
|
||||||
|
*Notifies peer that a message is invalid*
|
||||||
|
|
||||||
|
|
||||||
|
| [compact int](/protocol/p2p/compact__int.md) N (max 12) | N bytes | 1 byte | [compact int](/protocol/p2p/compact__int.md) M (max 111) | M bytes |
|
||||||
|
|----------------|---------|-------------|---------------|---------|
|
||||||
|
| command length | command | error code | reason length | reason string |
|
||||||
|
|
||||||
|
*command length* and *command* form a [vector](/protocol/p2p/vector.md) of bytes that identify the type of the problem message. These bytes (less padded nulls) match the *command* field in the protocol [message envelope](/protocol.md).
|
||||||
|
|
||||||
|
*reason length* and *reason string* form a [vector](/protocol/p2p/vector.md) of bytes that is a string providing a human language explanation of the reason the message was rejected. This string is subject to change so client software **SHOULD NOT** use it programatically.
|
||||||
|
|
||||||
|
*error code* provides a succinct machine-interpretable reason why the message was rejected.
|
||||||
|
|
||||||
|
### Reject Error Codes
|
||||||
|
|
||||||
|
| Name | Value | Response To | Description
|
||||||
|
|-------------|-------|---------------|-----------|
|
||||||
|
| REJECT_MALFORMED | 0x01 | any | message cannot be deserialized |
|
||||||
|
| REJECT_INVALID | 0x10 | BLOCK, TX, FILTERSIZEXTHIN | block or transaction is invalid, or xthin filter size is too small |
|
||||||
|
| REJECT_OBSOLETE | 0x11 | VERSION | This node no longer supports your client protocol version |
|
||||||
|
| REJECT_DUPLICATE | 0x12 | unused | |
|
||||||
|
| REJECT_NONSTANDARD | 0x40 | TX | Transaction is [non-standard](/standard__transactions.md), or [not final](/final__transactions.md) as per BIP68 |
|
||||||
|
| REJECT_DUST | 0x41 | TX | Transaction has an output that is too small |
|
||||||
|
| REJECT_INSUFFICIENTFEE | 0x42 | TX | Transaction does not pay enough to be relayed |
|
||||||
|
| REJECT_CHECKPOINT | 0x43 | unused | |
|
||||||
|
| REJECT_WAITING | 0x44 | TX | This transaction is [not final](/final__transactions.md) |
|
||||||
Reference in New Issue
Block a user