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

PIBD segment p2p messages #3496

Merged
merged 7 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
6 changes: 6 additions & 0 deletions chain/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ pub enum ErrorKind {
/// PIBD segment related error
#[fail(display = "Segment error")]
SegmentError(segment::SegmentError),
/// The segmenter is associated to a different block header
#[fail(display = "Segmenter header mismatch")]
SegmenterHeaderMismatch,
/// Segment height not within allowed range
#[fail(display = "Invalid segment height")]
InvalidSegmentHeight,
}

impl Display for Error {
Expand Down
8 changes: 8 additions & 0 deletions p2p/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ fn decode_message(
Type::PeerAddrs => Message::PeerAddrs(msg.body()?),
Type::TxHashSetRequest => Message::TxHashSetRequest(msg.body()?),
Type::TxHashSetArchive => Message::TxHashSetArchive(msg.body()?),
Type::GetOutputBitmapSegment => Message::GetOutputBitmapSegment(msg.body()?),
Type::OutputBitmapSegment => Message::OutputBitmapSegment(msg.body()?),
Type::GetOutputSegment => Message::GetOutputSegment(msg.body()?),
Type::OutputSegment => Message::OutputSegment(msg.body()?),
Type::GetRangeProofSegment => Message::GetRangeProofSegment(msg.body()?),
Type::RangeProofSegment => Message::RangeProofSegment(msg.body()?),
Type::GetKernelSegment => Message::GetKernelSegment(msg.body()?),
Type::KernelSegment => Message::KernelSegment(msg.body()?),
Type::Error | Type::Hand | Type::Shake | Type::Headers => {
return Err(Error::UnexpectedMessage)
}
Expand Down
147 changes: 146 additions & 1 deletion p2p/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@

//! Message types that transit over the network and related serialization code.

use crate::chain::txhashset::BitmapSegment;
use crate::conn::Tracker;
use crate::core::core::hash::Hash;
use crate::core::core::transaction::{OutputIdentifier, TxKernel};
use crate::core::core::{
BlockHeader, Transaction, UntrustedBlock, UntrustedBlockHeader, UntrustedCompactBlock,
BlockHeader, Segment, SegmentIdentifier, Transaction, UntrustedBlock, UntrustedBlockHeader,
UntrustedCompactBlock,
};
use crate::core::pow::Difficulty;
use crate::core::ser::{
Expand All @@ -28,6 +31,7 @@ use crate::types::{
AttachmentMeta, AttachmentUpdate, Capabilities, Error, PeerAddr, ReasonForBan,
MAX_BLOCK_HEADERS, MAX_LOCATORS, MAX_PEER_ADDRS,
};
use crate::util::secp::pedersen::RangeProof;
use bytes::Bytes;
use num::FromPrimitive;
use std::fmt;
Expand Down Expand Up @@ -70,6 +74,14 @@ enum_from_primitive! {
BanReason = 18,
GetTransaction = 19,
TransactionKernel = 20,
GetOutputBitmapSegment = 21,
OutputBitmapSegment = 22,
GetOutputSegment = 23,
OutputSegment = 24,
GetRangeProofSegment = 25,
RangeProofSegment = 26,
GetKernelSegment = 27,
KernelSegment = 28,
}
}

Expand Down Expand Up @@ -107,6 +119,14 @@ fn max_msg_size(msg_type: Type) -> u64 {
Type::BanReason => 64,
Type::GetTransaction => 32,
Type::TransactionKernel => 32,
Type::GetOutputBitmapSegment => 41,
Type::OutputBitmapSegment => 2 * max_block_size(),
Type::GetOutputSegment => 41,
Type::OutputSegment => 2 * max_block_size(),
Type::GetRangeProofSegment => 41,
Type::RangeProofSegment => 2 * max_block_size(),
Type::GetKernelSegment => 41,
Type::KernelSegment => 2 * max_block_size(),
}
}

Expand Down Expand Up @@ -710,6 +730,115 @@ impl Readable for TxHashSetArchive {
}
}

/// Request to get a segment of a (P)MMR at a particular block.
pub struct SegmentRequest {
/// The hash of the block the MMR is associated with
pub block_hash: Hash,
/// The identifier of the requested segment
pub identifier: SegmentIdentifier,
}

impl Readable for SegmentRequest {
fn read<R: Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let block_hash = Readable::read(reader)?;
let identifier = Readable::read(reader)?;
Ok(Self {
block_hash,
identifier,
})
}
}

impl Writeable for SegmentRequest {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
Writeable::write(&self.block_hash, writer)?;
Writeable::write(&self.identifier, writer)
}
}

/// Response to a (P)MMR segment request.
pub struct SegmentResponse<T> {
/// The hash of the block the MMR is associated with
pub block_hash: Hash,
/// The MMR segment
pub segment: Segment<T>,
}

impl<T: Readable> Readable for SegmentResponse<T> {
fn read<R: Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let block_hash = Readable::read(reader)?;
let segment = Readable::read(reader)?;
Ok(Self {
block_hash,
segment,
})
}
}

impl<T: Writeable> Writeable for SegmentResponse<T> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
Writeable::write(&self.block_hash, writer)?;
Writeable::write(&self.segment, writer)
}
}

/// Response to an output PMMR segment request.
pub struct OutputSegmentResponse {
/// The segment response
pub response: SegmentResponse<OutputIdentifier>,
/// The root hash of the output bitmap MMR
pub output_bitmap_root: Hash,
}

impl Readable for OutputSegmentResponse {
fn read<R: Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let response = Readable::read(reader)?;
let output_bitmap_root = Readable::read(reader)?;
Ok(Self {
response,
output_bitmap_root,
})
}
}

impl Writeable for OutputSegmentResponse {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
Writeable::write(&self.response, writer)?;
Writeable::write(&self.output_bitmap_root, writer)
}
}

/// Response to an output bitmap MMR segment request.
pub struct OutputBitmapSegmentResponse {
/// The hash of the block the MMR is associated with
pub block_hash: Hash,
/// The MMR segment
pub segment: BitmapSegment,
/// The root hash of the output PMMR
pub output_root: Hash,
}

impl Readable for OutputBitmapSegmentResponse {
fn read<R: Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let block_hash = Readable::read(reader)?;
let segment = Readable::read(reader)?;
let output_root = Readable::read(reader)?;
Ok(Self {
block_hash,
segment,
output_root,
})
}
}

impl Writeable for OutputBitmapSegmentResponse {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
Writeable::write(&self.block_hash, writer)?;
Writeable::write(&self.segment, writer)?;
Writeable::write(&self.output_root, writer)
}
}

pub enum Message {
Unknown(u8),
Ping(Ping),
Expand All @@ -731,6 +860,14 @@ pub enum Message {
TxHashSetRequest(TxHashSetRequest),
TxHashSetArchive(TxHashSetArchive),
Attachment(AttachmentUpdate, Option<Bytes>),
GetOutputBitmapSegment(SegmentRequest),
OutputBitmapSegment(OutputBitmapSegmentResponse),
GetOutputSegment(SegmentRequest),
OutputSegment(OutputSegmentResponse),
GetRangeProofSegment(SegmentRequest),
RangeProofSegment(SegmentResponse<RangeProof>),
GetKernelSegment(SegmentRequest),
KernelSegment(SegmentResponse<TxKernel>),
}

impl fmt::Display for Message {
Expand All @@ -756,6 +893,14 @@ impl fmt::Display for Message {
Message::TxHashSetRequest(_) => write!(f, "tx hash set request"),
Message::TxHashSetArchive(_) => write!(f, "tx hash set"),
Message::Attachment(_, _) => write!(f, "attachment"),
Message::GetOutputBitmapSegment(_) => write!(f, "get output bitmap segment"),
Message::OutputBitmapSegment(_) => write!(f, "output bitmap segment"),
Message::GetOutputSegment(_) => write!(f, "get output segment"),
Message::OutputSegment(_) => write!(f, "output segment"),
Message::GetRangeProofSegment(_) => write!(f, "get range proof segment"),
Message::RangeProofSegment(_) => write!(f, "range proof segment"),
Message::GetKernelSegment(_) => write!(f, "get kernel segment"),
Message::KernelSegment(_) => write!(f, "kernel segment"),
}
}
}
Expand Down
35 changes: 35 additions & 0 deletions p2p/src/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ use std::sync::Arc;
use lru_cache::LruCache;

use crate::chain;
use crate::chain::txhashset::BitmapChunk;
use crate::conn;
use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::{OutputIdentifier, Segment, SegmentIdentifier, TxKernel};
use crate::core::pow::Difficulty;
use crate::core::ser::Writeable;
use crate::core::{core, global};
Expand All @@ -35,6 +37,7 @@ use crate::types::{
Capabilities, ChainAdapter, Error, NetAdapter, P2PConfig, PeerAddr, PeerInfo, ReasonForBan,
TxHashSetRead,
};
use crate::util::secp::pedersen::RangeProof;
use chrono::prelude::{DateTime, Utc};

const MAX_TRACK_SIZE: usize = 30;
Expand Down Expand Up @@ -565,6 +568,38 @@ impl ChainAdapter for TrackingAdapter {
fn get_tmpfile_pathname(&self, tmpfile_name: String) -> PathBuf {
self.adapter.get_tmpfile_pathname(tmpfile_name)
}

fn get_kernel_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<Segment<TxKernel>, chain::Error> {
self.adapter.get_kernel_segment(hash, id)
}

fn get_bitmap_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<(Segment<BitmapChunk>, Hash), chain::Error> {
self.adapter.get_bitmap_segment(hash, id)
}

fn get_output_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<(Segment<OutputIdentifier>, Hash), chain::Error> {
self.adapter.get_output_segment(hash, id)
}

fn get_rangeproof_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<Segment<RangeProof>, chain::Error> {
self.adapter.get_rangeproof_segment(hash, id)
}
}

impl NetAdapter for TrackingAdapter {
Expand Down
35 changes: 35 additions & 0 deletions p2p/src/peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ use std::sync::Arc;
use rand::prelude::*;

use crate::chain;
use crate::chain::txhashset::BitmapChunk;
use crate::core::core;
use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::{OutputIdentifier, Segment, SegmentIdentifier, TxKernel};
use crate::core::global;
use crate::core::pow::Difficulty;
use crate::peer::Peer;
Expand All @@ -31,6 +33,7 @@ use crate::types::{
Capabilities, ChainAdapter, Error, NetAdapter, P2PConfig, PeerAddr, PeerInfo, ReasonForBan,
TxHashSetRead, MAX_PEER_ADDRS,
};
use crate::util::secp::pedersen::RangeProof;
use chrono::prelude::*;
use chrono::Duration;

Expand Down Expand Up @@ -625,6 +628,38 @@ impl ChainAdapter for Peers {
fn get_tmpfile_pathname(&self, tmpfile_name: String) -> PathBuf {
self.adapter.get_tmpfile_pathname(tmpfile_name)
}

fn get_kernel_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<Segment<TxKernel>, chain::Error> {
self.adapter.get_kernel_segment(hash, id)
}

fn get_bitmap_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<(Segment<BitmapChunk>, Hash), chain::Error> {
self.adapter.get_bitmap_segment(hash, id)
}

fn get_output_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<(Segment<OutputIdentifier>, Hash), chain::Error> {
self.adapter.get_output_segment(hash, id)
}

fn get_rangeproof_segment(
&self,
hash: Hash,
id: SegmentIdentifier,
) -> Result<Segment<RangeProof>, chain::Error> {
self.adapter.get_rangeproof_segment(hash, id)
}
}

impl NetAdapter for Peers {
Expand Down
Loading