Peer Protocol
This protocol is a bidirectional protocol for communication between full nodes in the Chia system. The sender is the full node sending the message, and the recipient is the full node that is receiving the message.
new_peak
Sent to peers whenever our node's peak weight advances (whenever the blockchain moves forward). The fork point allows peers to detect how deep of a reorg happened, and fetch the correct blocks. The unfinished reward block hash allows the receiving peer to use their cache for unfinished blocks, since they most likely already have the unfinished version of the same block, and therefore don't need to re-request the block transactions generator.
Usually, during normal operation, peers will ask for just the latest block, or ignore this message if they have already received it from another peer. If we are a few blocks behind, blocks are fetched one by one in reverse order up to the fork.
If we are far behind this peak, we will start a batch sync (download a few tens of blocks in batches) or a long sync, where we download a weight proof and then download many blocks in batches.
class NewPeak(Streamable):
header_hash: bytes32 # header_hash of new block
height: uint32 # height of new block
weight: uint128 # weight of new block
fork_point_with_previous_peak: uint32
unfinished_reward_block_hash: bytes32
new_transaction
Sent to peers when a new spend bundle has been added to the mempool. The receiving peer can then choose to ignore it, or request the whole transaction.
class NewTransaction(Streamable):
transaction_id: bytes32 # hash of the spend bundle
cost: uint64 # cost of the transaction, used to see if fees are sufficient for mempool inclusion
fees: uint64 # fees in mojo of transaction, used to see if fees are sufficient for mempool inclusion
request_transaction
Request for a full transaction (spend bundle) from a peer by its id. If a peer does not respond, other peers are contacted for the same transaction.
class RequestTransaction(Streamable):
transaction_id: bytes32 # hash of the spendbundle
respond_transaction
Response for a request_transaction
message. Sends a spend bundle to a peer. To see the contents of a SpendBundle
, see the Spend Bundles page.
class RespondTransaction(Streamable):
transaction: SpendBundle
request_proof_of_weight
Request a weight proof from a peer. This is done right before starting a long sync. The weight proof allows our node to validate whether a new_peak
that we received from a peer corresponds to an actual valid blockchain. It is proof that a certain amount of "weight", or space and time, has been used on that blockchain.
class RequestProofOfWeight(Streamable):
total_number_of_blocks: uint32 # Height of the peak block
tip: bytes32 # The header_hash of the peak block
respond_proof_of_weight
Response to a request_proof_of_weight
message. Note that weight proofs can be quite large, in the tens of MB range. If the chain VDFs are compressed (aka blueboxed), then they weight proofs will be smaller. This is the V1 version of weight proofs, more efficient versions might be added in the future.
class RespondProofOfWeight(Streamable):
wp: WeightProof
tip: bytes32
request_block
Request for a block at a certain height from a peer. Called after receiving a new_peak
message.
class RequestBlock(Streamable):
height: uint32 # Height of the block to request
include_transaction_block: bool # Whether to include transaction data
respond_block
Response to a request_block
message.
class RespondBlock(Streamable):
block: FullBlock
reject_block
Rejection to a request_block
message.
class RejectBlock(Streamable):
height: uint32
request_blocks
Request multiple blocks at once from a peer.
class RequestBlocks(Streamable):
start_height: uint32
end_height: uint32 # Inclusive
include_transaction_block: bool # Whether to include transaction data
respond_blocks
Response to a request_blocks
message.
class RespondBlocks(Streamable):
start_height: uint32
end_height: uint32
blocks: List[FullBlock]
reject_blocks
Rejection to a request_blocks
message.
class RejectBlocks(Streamable):
start_height: uint32
end_height: uint32
new_unfinished_block
Notification to another peer that a new unfinished block was added to the cache. These unfinished blocks are kept around temporarily, until the infusion point VDF is released, and the block can be "finished" and added to the blockchain.
class NewUnfinishedBlock(Streamable):
unfinished_reward_hash: bytes32
request_unfinished_block
Request for an unfinished block from a peer.
class RequestUnfinishedBlock(Streamable):
unfinished_reward_hash: bytes32
respond_unfinished_block
Response to a request_unfinished_block
message.
class RespondUnfinishedBlock(Streamable):
unfinished_block: UnfinishedBlock
new_signage_point_or_end_of_sub_slot
Sent when the node adds a new signage point or a new end of sub slot to the full node store. The receiver can choose to request the object, or potentially request the previous sub slot, if they are far behind. For example, recently synced up to the peak of the blockchain.
class NewSignagePointOrEndOfSubSlot(Streamable):
prev_challenge_hash: Optional[bytes32] # Challenge hash at the start of the previous sub slot, if present
challenge_hash: bytes32 # Challenge hash at the start of the sub slot
index_from_challenge: uint8 # Index from the start, 0 for end of sub slot
last_rc_infusion: bytes32 # Last reward chain infusion hash
request_signage_point_or_end_of_sub_slot
Request for a signage point or end of slot.
class RequestSignagePointOrEndOfSubSlot(Streamable):
challenge_hash: bytes32
index_from_challenge: uint8
last_rc_infusion: bytes32
respond_signage_point
Response for request_signage_point_or_end_of_sub_slot
. After receiving this message, the recipient will check that all VDFs are correct, and forward it to other full nodes and potentially farmers.
class RespondSignagePoint(Streamable):
index_from_challenge: uint8 # Which index out of the 64 signage points, cannot be 0 since that is the EOS
challenge_chain_vdf: VDFInfo
challenge_chain_proof: VDFProof
reward_chain_vdf: VDFInfo
reward_chain_proof: VDFProof
respond_end_of_sub_slot
Another response for request_signage_point_or_end_of_sub_slot
in the case where index_from_challenge
is zero. This is also verified and forwarded by the full node, similar to signage points.
class RespondEndOfSubSlot(Streamable):
end_of_slot_bundle: EndOfSubSlotBundle
request_mempool_transactions
This is a request for transactions in the mempool. The filter corresponds to a BIP158 Compact Block Filter, which allows the recipient to see what transactions the sender already has (with some small chance for false positives), without sending all transaction IDs. The recipient can then respond using respond_transaction
directly, but should not send a very large number of transactions, to not overwhelm the original sending peer.
class RequestMempoolTransactions(Streamable):
filter: bytes
new_compact_vdf
A notification to a peer that a new compact VDF has been added to the blockchain. Compact VDFs are smaller versions of VDF proofs present in blocks. They do not change the block itself, they just compress the block data to keep the DB smaller and sync time lower. The actual proof
class NewCompactVDF(Streamable):
height: uint32 # Height of the block which has a new VDF
header_hash: bytes32 # Header hash of that block
field_vdf: uint8 # Which VDF in that block was updated (blocks have multiple VDFs)
vdf_info: VDFInfo # Info of the VDF that was updated
request_compact_vdf
A request to a peer for a compact VDf.
class RequestCompactVDF(Streamable):
height: uint32
header_hash: bytes32
field_vdf: uint8
vdf_info: VDFInfo
respond_compact_vdf
A response to a peer that requested a compact VDF.
class RespondCompactVDF(Streamable):
height: uint32
header_hash: bytes32
field_vdf: uint8
vdf_info: VDFInfo
vdf_proof: VDFProof
request_peers
Request a list of peers. There is no body in this message. This is usually sent when connecting to a peer.
class RequestPeers(Streamable):
"""
Return full list of peers
"""
respond_peers
A response to request_peers
, containing a list of ip and port for each peer. Must be no larger than 1000. The timestamp corresponds to the last time this peer's record was updated, based on the peer DB update rules.
class RespondPeers(Streamable):
peer_list: List[TimestampedPeerInfo]