Parse GetBlock messages
This commit is contained in:
parent
7632d5b8cc
commit
b991c413cd
|
@ -9,7 +9,7 @@ use failure::Error;
|
||||||
use tokio::codec::{Decoder, Encoder};
|
use tokio::codec::{Decoder, Encoder};
|
||||||
|
|
||||||
use zebra_chain::{
|
use zebra_chain::{
|
||||||
block::BlockHeader,
|
block::{BlockHeader, BlockHeaderHash},
|
||||||
serialization::{ReadZcashExt, WriteZcashExt, ZcashDeserialize, ZcashSerialize},
|
serialization::{ReadZcashExt, WriteZcashExt, ZcashDeserialize, ZcashSerialize},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
types::{BlockHeight, Sha256dChecksum},
|
types::{BlockHeight, Sha256dChecksum},
|
||||||
|
@ -417,9 +417,24 @@ impl Codec {
|
||||||
bail!("unimplemented message type")
|
bail!("unimplemented message type")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_getblocks<R: Read>(&self, mut _reader: R) -> Result<Message, Error> {
|
fn read_getblocks<R: Read>(&self, mut reader: R) -> Result<Message, Error> {
|
||||||
trace!("getblocks");
|
let version = Version(reader.read_u32::<LittleEndian>()?);
|
||||||
bail!("unimplemented message type")
|
|
||||||
|
let count = reader.read_compactsize()? as usize;
|
||||||
|
let max_count = self.builder.max_len / 32;
|
||||||
|
let mut block_locator_hashes = Vec::with_capacity(std::cmp::min(count, max_count));
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
block_locator_hashes.push(BlockHeaderHash(reader.read_32_bytes()?));
|
||||||
|
}
|
||||||
|
|
||||||
|
let hash_stop = BlockHeaderHash(reader.read_32_bytes()?);
|
||||||
|
|
||||||
|
Ok(Message::GetBlocks {
|
||||||
|
version,
|
||||||
|
block_locator_hashes,
|
||||||
|
hash_stop,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize a `headers` message.
|
/// Deserialize a `headers` message.
|
||||||
|
@ -458,7 +473,7 @@ impl Codec {
|
||||||
) -> Result<Vec<InventoryHash>, Error> {
|
) -> Result<Vec<InventoryHash>, Error> {
|
||||||
let count = reader.read_compactsize()? as usize;
|
let count = reader.read_compactsize()? as usize;
|
||||||
// Preallocate a buffer, performing a single allocation in the honest
|
// Preallocate a buffer, performing a single allocation in the honest
|
||||||
// case. Although the size of the recieved data buffer is bounded by the
|
// case. Although the size of the received data buffer is bounded by the
|
||||||
// codec's max_len field, it's still possible for someone to send a
|
// codec's max_len field, it's still possible for someone to send a
|
||||||
// short message with a large count field, so if we naively trust
|
// short message with a large count field, so if we naively trust
|
||||||
// the count field we could be tricked into preallocating a large
|
// the count field we could be tricked into preallocating a large
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::net;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
|
||||||
use zebra_chain::block::{Block, BlockHeader};
|
use zebra_chain::block::{Block, BlockHeader, BlockHeaderHash};
|
||||||
use zebra_chain::{transaction::Transaction, types::BlockHeight};
|
use zebra_chain::{transaction::Transaction, types::BlockHeight};
|
||||||
|
|
||||||
use crate::meta_addr::MetaAddr;
|
use crate::meta_addr::MetaAddr;
|
||||||
|
@ -144,8 +144,36 @@ pub enum Message {
|
||||||
|
|
||||||
/// A `getblocks` 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.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getblocks)
|
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getblocks)
|
||||||
GetBlocks {/* XXX add fields */},
|
// 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.
|
||||||
|
GetBlocks {
|
||||||
|
/// The protocol version.
|
||||||
|
version: Version,
|
||||||
|
|
||||||
|
/// Block locators, from newest back to genesis block.
|
||||||
|
block_locator_hashes: Vec<BlockHeaderHash>,
|
||||||
|
|
||||||
|
/// `BlockHeaderHash` of the last desired block.
|
||||||
|
///
|
||||||
|
/// Set to zero to get as many blocks as possible (500).
|
||||||
|
hash_stop: BlockHeaderHash,
|
||||||
|
},
|
||||||
|
|
||||||
/// A `headers` message.
|
/// A `headers` message.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue