Support a response message

This commit is contained in:
Deirdre Connolly 2019-10-03 18:28:47 -04:00 committed by Deirdre Connolly
parent 4efceb490d
commit 565dc92afe
2 changed files with 39 additions and 8 deletions

View File

@ -9,6 +9,7 @@ use failure::Error;
use tokio::codec::{Decoder, Encoder};
use zebra_chain::{
block::BlockHeader,
serialization::{ReadZcashExt, WriteZcashExt, ZcashDeserialize, ZcashSerialize},
types::{BlockHeight, Sha256dChecksum},
};
@ -420,9 +421,29 @@ impl Codec {
bail!("unimplemented message type")
}
fn read_headers<R: Read>(&self, mut _reader: R) -> Result<Message, Error> {
trace!("headers");
bail!("unimplemented message type")
/// Deserialize a `headers` message.
///
/// See [Zcash block header] for the enumeration of these fields.
///
/// [Zcash block header](https://zips.z.cash/protocol/protocol.pdf#page=84)
fn read_headers<R: Read>(&self, mut reader: R) -> Result<Message, Error> {
let count = reader.read_compactsize()? as usize;
// Preallocate a buffer, performing a single allocation in the honest
// case. Although the size of the recieved data buffer is bounded by the
// 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
// the count field we could be tricked into preallocating a large
// buffer. Instead, calculate the maximum count for a valid message from
// the codec's max_len using ENCODED_HEADER_SIZE.
const ENCODED_HEADER_SIZE: usize = 4 + 32 + 32 + 32 + 4 + 4 + 32 + 3 + 1344;
let max_count = self.builder.max_len / ENCODED_HEADER_SIZE;
let mut headers = Vec::with_capacity(std::cmp::min(count, max_count));
for _ in 0..count {
headers.push(BlockHeader::zcash_deserialize(&mut reader)?);
}
Ok(Message::Headers(headers))
}
fn read_getheaders<R: Read>(&self, mut _reader: R) -> Result<Message, Error> {

View File

@ -4,7 +4,7 @@ use std::net;
use chrono::{DateTime, Utc};
use zebra_chain::block::Block;
use zebra_chain::block::{Block, BlockHeader};
use zebra_chain::{transaction::Transaction, types::BlockHeight};
use crate::meta_addr::MetaAddr;
@ -149,8 +149,14 @@ pub enum Message {
/// A `headers` message.
///
/// Returns block headers in response to a getheaders packet.
///
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#headers)
Headers {/* XXX add fields */},
// Note that the block headers in this packet include a
// transaction count (a var_int, so there can be more than 81
// bytes per header) as opposed to the block headers that are
// hashed by miners.
Headers(Vec<BlockHeader>),
/// A `getheaders` message.
///
@ -159,6 +165,10 @@ pub enum Message {
/// An `inv` message.
///
/// Allows a node to advertise its knowledge of one or more
/// objects. It can be received unsolicited, or in reply to
/// `getblocks`.
///
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#inv)
// XXX the bitcoin reference above suggests this can be 1.8 MB in bitcoin -- maybe
// larger in Zcash, since Zcash objects could be bigger (?) -- does this tilt towards
@ -167,9 +177,9 @@ pub enum Message {
/// A `getdata` message.
///
/// `getdata` is used in response to `inv`, to retrieve the content of
/// a specific object, and is usually sent after receiving an `inv`
/// packet, after filtering known elements.
/// `getdata` is used in response to `inv`, to retrieve the
/// content of a specific object, and is usually sent after
/// receiving an `inv` packet, after filtering known elements.
///
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#getdata)
GetData(Vec<InventoryHash>),