diff --git a/zebra-network/src/peer/connection.rs b/zebra-network/src/peer/connection.rs index dec78d3c..9049c522 100644 --- a/zebra-network/src/peer/connection.rs +++ b/zebra-network/src/peer/connection.rs @@ -433,10 +433,7 @@ where }), (AwaitingRequest, FindBlocks { known_blocks, stop }) => self .peer_tx - .send(Message::GetBlocks { - block_locator_hashes: known_blocks, - hash_stop: stop.unwrap_or(block::Hash([0; 32])), - }) + .send(Message::GetBlocks { known_blocks, stop }) .await .map_err(|e| e.into()) .map(|()| AwaitingResponse { diff --git a/zebra-network/src/protocol/external/codec.rs b/zebra-network/src/protocol/external/codec.rs index 5e6e33ad..baa89832 100644 --- a/zebra-network/src/protocol/external/codec.rs +++ b/zebra-network/src/protocol/external/codec.rs @@ -227,21 +227,17 @@ impl Codec { Message::Addr(addrs) => addrs.zcash_serialize(&mut writer)?, Message::GetAddr => { /* Empty payload -- no-op */ } Message::Block(block) => block.zcash_serialize(&mut writer)?, - Message::GetBlocks { - block_locator_hashes, - hash_stop, - } => { + Message::GetBlocks { known_blocks, stop } => { writer.write_u32::(self.builder.version.0)?; - block_locator_hashes.zcash_serialize(&mut writer)?; - hash_stop.zcash_serialize(&mut writer)?; + known_blocks.zcash_serialize(&mut writer)?; + stop.unwrap_or(block::Hash([0; 32])) + .zcash_serialize(&mut writer)?; } - Message::GetHeaders { - block_locator_hashes, - hash_stop, - } => { + Message::GetHeaders { known_blocks, stop } => { writer.write_u32::(self.builder.version.0)?; - block_locator_hashes.zcash_serialize(&mut writer)?; - hash_stop.zcash_serialize(&mut writer)?; + known_blocks.zcash_serialize(&mut writer)?; + stop.unwrap_or(block::Hash([0; 32])) + .zcash_serialize(&mut writer)?; } Message::Headers(headers) => headers.zcash_serialize(&mut writer)?, Message::Inv(hashes) => hashes.zcash_serialize(&mut writer)?, @@ -483,10 +479,14 @@ impl Codec { fn read_getblocks(&self, mut reader: R) -> Result { if self.builder.version == Version(reader.read_u32::()?) { - Ok(Message::GetBlocks { - block_locator_hashes: Vec::zcash_deserialize(&mut reader)?, - hash_stop: block::Hash::zcash_deserialize(&mut reader)?, - }) + let known_blocks = Vec::zcash_deserialize(&mut reader)?; + let stop_hash = block::Hash::zcash_deserialize(&mut reader)?; + let stop = if stop_hash != block::Hash([0; 32]) { + Some(stop_hash) + } else { + None + }; + Ok(Message::GetBlocks { known_blocks, stop }) } else { Err(Error::Parse("getblocks version did not match negotiation")) } @@ -503,10 +503,14 @@ impl Codec { fn read_getheaders(&self, mut reader: R) -> Result { if self.builder.version == Version(reader.read_u32::()?) { - Ok(Message::GetHeaders { - block_locator_hashes: Vec::zcash_deserialize(&mut reader)?, - hash_stop: block::Hash::zcash_deserialize(&mut reader)?, - }) + let known_blocks = Vec::zcash_deserialize(&mut reader)?; + let stop_hash = block::Hash::zcash_deserialize(&mut reader)?; + let stop = if stop_hash != block::Hash([0; 32]) { + Some(stop_hash) + } else { + None + }; + Ok(Message::GetHeaders { known_blocks, stop }) } else { Err(Error::Parse("getblocks version did not match negotiation")) } diff --git a/zebra-network/src/protocol/external/message.rs b/zebra-network/src/protocol/external/message.rs index 24982fb2..1bf051a4 100644 --- a/zebra-network/src/protocol/external/message.rs +++ b/zebra-network/src/protocol/external/message.rs @@ -138,37 +138,21 @@ pub enum Message { /// A `getblocks` message. /// - /// Requests the list of blocks starting right after the last - /// known hash in `block_locator_hashes`, up to `hash_stop` or 500 - /// blocks, whichever comes first. + /// `known_blocks` is a series of known block hashes spaced out along the + /// peer's best chain. The remote peer uses them to compute the intersection + /// of its best chain and determine the blocks following the intersection + /// point. /// - /// You can send in fewer known hashes down to a minimum of just - /// one hash. However, the purpose of the block locator object is - /// to detect a wrong branch in the caller's main chain. If the - /// peer detects that you are off the main chain, it will send in - /// block hashes which are earlier than your last known block. So - /// if you just send in your last known hash and it is off the - /// main chain, the peer starts over at block #1. + /// The peer responds with an `inv` packet with the hashes of subsequent blocks. + /// If supplied, the `stop` parameter specifies the last header to request. + /// Otherwise, an inv packet with the maximum number (500) are sent. /// - /// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getblocks) - // The locator hashes are processed by a node in the order as they - // appear in the message. If a block hash is found in the node's - // main chain, the list of its children is returned back via the - // inv message and the remaining locators are ignored, no matter - // if the requested limit was reached, or not. - // - // The 500 headers number is from the Bitcoin docs, we are not - // certain (yet) that other implementations of Zcash obey this - // restriction, or if they don't, what happens if we send them too - // many results. + /// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getheaders) GetBlocks { - /// Block locators, from newest back to genesis block. - block_locator_hashes: Vec, - - /// `block::Hash` of the last desired block. - /// - /// Set to zero to get as many blocks as possible (500). - hash_stop: block::Hash, + /// Hashes of known blocks, ordered from highest height to lowest height. + known_blocks: Vec, + /// Optionally, the last header to request. + stop: Option, }, /// A `headers` message. @@ -184,31 +168,21 @@ pub enum Message { /// A `getheaders` message. /// - /// Requests a series of block headers starting right after the - /// last known hash in `block_locator_hashes`, up to `hash_stop` - /// or 2000 blocks, whichever comes first. + /// `known_blocks` is a series of known block hashes spaced out along the + /// peer's best chain. The remote peer uses them to compute the intersection + /// of its best chain and determine the blocks following the intersection + /// point. /// - /// You can send in fewer known hashes down to a minimum of just - /// one hash. However, the purpose of the block locator object is - /// to detect a wrong branch in the caller's main chain. If the - /// peer detects that you are off the main chain, it will send in - /// block hashes which are earlier than your last known block. So - /// if you just send in your last known hash and it is off the - /// main chain, the peer starts over at block #1. + /// The peer responds with an `headers` packet with the hashes of subsequent blocks. + /// If supplied, the `stop` parameter specifies the last header to request. + /// Otherwise, the maximum number of block headers (160) are sent. /// /// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getheaders) - // The 2000 headers number is from the Bitcoin docs, we are not - // certain (yet) that other implementations of Zcash obey this - // restriction, or if they don't, what happens if we send them too - // many results. GetHeaders { - /// Block locators, from newest back to genesis block. - block_locator_hashes: Vec, - - /// `block::Hash` of the last desired block header. - /// - /// Set to zero to get as many block headers as possible (2000). - hash_stop: block::Hash, + /// Hashes of known blocks, ordered from highest height to lowest height. + known_blocks: Vec, + /// Optionally, the last header to request. + stop: Option, }, /// An `inv` message.