Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inbound FindBlocks and FindHeaders #1347

Merged
merged 29 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
680d270
implement inbound `FindBlocks`
oxarbitrage Nov 20, 2020
88cd84b
Apply suggestions from code review
yaahc Nov 24, 2020
aed0170
Apply some suggestions from code review
oxarbitrage Nov 24, 2020
e81b823
fix build after suggestions
oxarbitrage Nov 24, 2020
33ee423
remove non needed iterator
oxarbitrage Nov 24, 2020
5f8c93c
fix stop parameter
oxarbitrage Nov 24, 2020
b3c7f9e
handle empty response
oxarbitrage Nov 24, 2020
20bc94d
remove redundant call in
yaahc Nov 24, 2020
e967c97
Update zebra-state/src/service.rs
oxarbitrage Nov 24, 2020
24904ce
Merge branch 'main' into issue1306
oxarbitrage Nov 24, 2020
9124315
rustfmt
oxarbitrage Nov 25, 2020
7a74fc1
Apply suggestions from code review
oxarbitrage Nov 25, 2020
187534d
handle request before having any chain tip
oxarbitrage Nov 25, 2020
b8ee598
fix known blocks matching with our chain
oxarbitrage Nov 25, 2020
190d7cf
remove known blocks empty check
oxarbitrage Nov 25, 2020
d5c126a
clippy
oxarbitrage Nov 25, 2020
973a85c
Split state height functions into "any chain" and "best chain"
teor2345 Nov 26, 2020
92940f4
Split `find_chain_hashes` into smaller functions
teor2345 Nov 26, 2020
c43c255
Refactor - use more iterator methods
teor2345 Nov 26, 2020
266278f
Rename `hash()` to `best_hash()`
teor2345 Nov 26, 2020
5d3723c
Document the only remaining use of an "any chain" method
teor2345 Nov 26, 2020
cd061fd
Rename the best chain block method to `best_block`
teor2345 Nov 26, 2020
76070a5
Improve some logs and comments
teor2345 Nov 26, 2020
a50ebfa
Handle inbound peer FindHeaders requests
teor2345 Nov 26, 2020
2813c1c
Move fmt utilities to zebra_chain::fmt
teor2345 Nov 26, 2020
6174d23
Summarise Debug for some Message variants
teor2345 Nov 26, 2020
adaf13f
Fix some comments
teor2345 Nov 26, 2020
8d96d43
Refactor to avoid an unwrap
teor2345 Nov 30, 2020
4d8bbd5
Clean up the rest of the expanded `derive(Debug)`
teor2345 Nov 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions zebra-chain/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use root_hash::RootHash;

use serde::{Deserialize, Serialize};

use crate::{parameters::Network, transaction::Transaction, transparent};
use crate::{fmt::DisplayToDebug, parameters::Network, transaction::Transaction, transparent};

/// A Zcash block, containing a header and a list of transactions.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
Expand All @@ -46,17 +46,6 @@ impl fmt::Display for Block {
}
}

struct DisplayToDebug<T>(T);

impl<T> fmt::Debug for DisplayToDebug<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}

impl Block {
/// Return the block height reported in the coinbase transaction, if any.
pub fn coinbase_height(&self) -> Option<Height> {
Expand Down
28 changes: 28 additions & 0 deletions zebra-chain/src/fmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Format wrappers for Zebra

use std::fmt;

pub struct DisplayToDebug<T>(pub T);

impl<T> fmt::Debug for DisplayToDebug<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}

pub struct SummaryDebug<T>(pub T);

impl<T> fmt::Debug for SummaryDebug<Vec<T>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}, len={}", std::any::type_name::<T>(), self.0.len())
}
}

impl<T> fmt::Debug for SummaryDebug<&Vec<T>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}, len={}", std::any::type_name::<T>(), self.0.len())
}
}
1 change: 1 addition & 0 deletions zebra-chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern crate serde;

pub mod amount;
pub mod block;
pub mod fmt;
pub mod parameters;
pub mod primitives;
pub mod sapling;
Expand Down
95 changes: 93 additions & 2 deletions zebra-network/src/protocol/external/message.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! Definitions of network messages.

use std::error::Error;
use std::{net, sync::Arc};
use std::{fmt, net, sync::Arc};

use chrono::{DateTime, Utc};

use zebra_chain::{
block::{self, Block},
fmt::{DisplayToDebug, SummaryDebug},
transaction::Transaction,
};

Expand All @@ -30,7 +31,7 @@ use crate::meta_addr::MetaAddr;
/// during serialization).
///
/// [btc_wiki_protocol]: https://en.bitcoin.it/wiki/Protocol_documentation
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Eq, PartialEq)]
pub enum Message {
/// A `version` message.
///
Expand Down Expand Up @@ -307,3 +308,93 @@ pub enum RejectReason {
Checkpoint = 0x43,
Other = 0x50,
}

/// Summarise `Vec`s when debugging messages
impl fmt::Debug for Message {
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Message::Version {
version,
services,
timestamp,
address_recv,
address_from,
nonce,
user_agent,
start_height,
relay,
} => f
.debug_struct("Version")
.field("version", version)
.field("services", services)
.field("timestamp", timestamp)
.field("address_recv", address_recv)
.field("address_from", address_from)
.field("nonce", nonce)
.field("user_agent", user_agent)
.field("start_height", start_height)
.field("relay", relay)
.finish(),
Message::Verack => f.debug_tuple("Verack").finish(),
Message::Ping(nonce) => f.debug_tuple("Ping").field(nonce).finish(),
Message::Pong(nonce) => f.debug_tuple("Pong").field(nonce).finish(),
Message::Reject {
message,
ccode,
reason,
data,
} => f
.debug_struct("Reject")
.field("message", message)
.field("ccode", ccode)
.field("reason", reason)
.field("data", data)
.finish(),
Message::GetAddr => f.debug_tuple("GetAddr").finish(),
Message::Addr(addr) => f.debug_tuple("Addr").field(&SummaryDebug(addr)).finish(),
Message::GetBlocks { known_blocks, stop } => f
.debug_struct("GetBlocks")
.field("known_blocks", &SummaryDebug(known_blocks))
.field("stop", stop)
.finish(),
Message::Inv(inv) => f.debug_tuple("Inv").field(&SummaryDebug(inv)).finish(),
Message::GetHeaders { known_blocks, stop } => f
.debug_struct("GetHeaders")
.field("known_blocks", &SummaryDebug(known_blocks))
.field("stop", stop)
.finish(),
Message::Headers(headers) => f
.debug_tuple("Headers")
.field(&SummaryDebug(headers))
.finish(),
Message::GetData(data) => f.debug_tuple("GetData").field(&SummaryDebug(data)).finish(),
Message::Block(block) => f
.debug_tuple("Block")
.field(&DisplayToDebug(block))
.finish(),
Message::Tx(tx) => f.debug_tuple("Tx").field(&tx).finish(),
Message::NotFound(not_found) => f
.debug_tuple("NotFound")
.field(&SummaryDebug(not_found))
.finish(),
Message::Mempool => f.debug_tuple("Mempool").finish(),
Message::FilterLoad {
filter,
hash_functions_count,
tweak,
flags,
} => f
.debug_struct("FilterLoad")
.field("filter", filter)
.field("hash_functions_count", hash_functions_count)
.field("tweak", tweak)
.field("flags", flags)
.finish(),
Message::FilterAdd { data } => f
.debug_struct("FilterAdd")
.field("data", &SummaryDebug(data))
.finish(),
Message::FilterClear => f.debug_tuple("FilterClear").finish(),
}
}
}
46 changes: 46 additions & 0 deletions zebra-state/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,50 @@ pub enum Request {
/// Code making this request should apply a timeout layer to the service to
/// handle missing UTXOs.
AwaitUtxo(transparent::OutPoint),

/// Finds the first hash that's in the peer's `known_blocks` and the local best chain.
/// Returns a list of hashes that follow that intersection, from the best chain.
///
/// If there is no matching hash in the best chain, starts from the genesis hash.
///
/// Stops the list of hashes after:
/// * adding the best tip,
/// * adding the `stop` hash to the list, if it is in the best chain, or
/// * adding 500 hashes to the list.
///
/// Returns an empty list if the state is empty.
///
/// Returns
///
/// [`Response::BlockHashes(Vec<block::Hash>)`](Response::BlockHashes).
/// See https://en.bitcoin.it/wiki/Protocol_documentation#getblocks
FindBlockHashes {
/// Hashes of known blocks, ordered from highest height to lowest height.
known_blocks: Vec<block::Hash>,
/// Optionally, the last block hash to request.
stop: Option<block::Hash>,
},

/// Finds the first hash that's in the peer's `known_blocks` and the local best chain.
/// Returns a list of headers that follow that intersection, from the best chain.
///
/// If there is no matching hash in the best chain, starts from the genesis header.
///
/// Stops the list of headers after:
/// * adding the best tip,
/// * adding the header matching the `stop` hash to the list, if it is in the best chain, or
/// * adding 160 headers to the list.
///
/// Returns an empty list if the state is empty.
///
/// Returns
///
/// [`Response::BlockHeaders(Vec<block::Header>)`](Response::BlockHeaders).
/// See https://en.bitcoin.it/wiki/Protocol_documentation#getheaders
FindBlockHeaders {
/// Hashes of known blocks, ordered from highest height to lowest height.
known_blocks: Vec<block::Hash>,
/// Optionally, the hash of the last header to request.
stop: Option<block::Hash>,
},
}
8 changes: 7 additions & 1 deletion zebra-state/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ pub enum Response {
/// Response to [`Request::Block`] with the specified block.
Block(Option<Arc<Block>>),

/// The response to a `AwaitUtxo` request
/// The response to a `AwaitUtxo` request.
Utxo(Utxo),

/// The response to a `FindBlockHashes` request.
BlockHashes(Vec<block::Hash>),

/// The response to a `FindBlockHeaders` request.
BlockHeaders(Vec<block::Header>),
}
Loading