Move `p2p` encodings out of `encode`
All of the `Encodable` implementations are defined within `p2p` with the exception of `p2p` types that are a `Vec`. To fully decouple `p2p` from `encode` we can define these in `p2p` like the others. This is the final step in removing anything `p2p` related from the rest of `bitcoin`.
This commit is contained in:
parent
94bcff28b1
commit
20779bdbc8
|
@ -26,11 +26,6 @@ use crate::bip152::{PrefilledTransaction, ShortId};
|
|||
use crate::bip158::{FilterHash, FilterHeader};
|
||||
use crate::block::{self, BlockHash};
|
||||
use crate::merkle_tree::TxMerkleNode;
|
||||
#[cfg(feature = "std")]
|
||||
use crate::p2p::{
|
||||
address::{AddrV2Message, Address},
|
||||
message_blockdata::Inventory,
|
||||
};
|
||||
use crate::prelude::{rc, sync, Box, Cow, String, Vec};
|
||||
use crate::taproot::TapLeafHash;
|
||||
use crate::transaction::{Transaction, TxIn, TxOut};
|
||||
|
@ -552,13 +547,6 @@ impl_vec!(TapLeafHash);
|
|||
impl_vec!(ShortId);
|
||||
impl_vec!(PrefilledTransaction);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl_vec!(Inventory);
|
||||
#[cfg(feature = "std")]
|
||||
impl_vec!((u32, Address));
|
||||
#[cfg(feature = "std")]
|
||||
impl_vec!(AddrV2Message);
|
||||
|
||||
pub(crate) fn consensus_encode_with_size<W: Write + ?Sized>(
|
||||
data: &[u8],
|
||||
w: &mut W,
|
||||
|
@ -765,8 +753,6 @@ mod tests {
|
|||
use core::mem::discriminant;
|
||||
|
||||
use super::*;
|
||||
#[cfg(feature = "std")]
|
||||
use crate::p2p::{message_blockdata::Inventory, Address};
|
||||
|
||||
#[test]
|
||||
fn serialize_int() {
|
||||
|
@ -1049,10 +1035,6 @@ mod tests {
|
|||
test_len_is_max_vec::<TxIn>();
|
||||
test_len_is_max_vec::<Vec<u8>>();
|
||||
test_len_is_max_vec::<u64>();
|
||||
#[cfg(feature = "std")]
|
||||
test_len_is_max_vec::<(u32, Address)>();
|
||||
#[cfg(feature = "std")]
|
||||
test_len_is_max_vec::<Inventory>();
|
||||
}
|
||||
|
||||
fn test_len_is_max_vec<T>()
|
||||
|
|
|
@ -493,7 +493,7 @@ mod test {
|
|||
use hex_lit::hex;
|
||||
|
||||
use super::*;
|
||||
use crate::consensus::encode::{deserialize, serialize};
|
||||
use crate::{consensus::encode::{deserialize, serialize}, p2p::message::AddrV2Payload};
|
||||
|
||||
#[test]
|
||||
fn serialize_address() {
|
||||
|
@ -706,10 +706,10 @@ mod test {
|
|||
#[test]
|
||||
fn addrv2message() {
|
||||
let raw = hex!("0261bc6649019902abab208d79627683fd4804010409090909208d");
|
||||
let addresses: Vec<AddrV2Message> = deserialize(&raw).unwrap();
|
||||
let addresses: AddrV2Payload = deserialize(&raw).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
addresses,
|
||||
addresses.0,
|
||||
vec![
|
||||
AddrV2Message {
|
||||
services: ServiceFlags::NETWORK,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
macro_rules! impl_vec_wrapper {
|
||||
($wrapper: ident, $type: ty) => {
|
||||
impl crate::consensus::encode::Encodable for $wrapper {
|
||||
#[inline]
|
||||
fn consensus_encode<W: io::Write + ?Sized>(
|
||||
&self,
|
||||
w: &mut W,
|
||||
) -> core::result::Result<usize, io::Error> {
|
||||
let mut len = 0;
|
||||
len += w.emit_compact_size(self.0.len())?;
|
||||
for c in self.0.iter() {
|
||||
len += c.consensus_encode(w)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::consensus::encode::Decodable for $wrapper {
|
||||
#[inline]
|
||||
fn consensus_decode_from_finite_reader<R: io::BufRead + ?Sized>(
|
||||
r: &mut R,
|
||||
) -> core::result::Result<$wrapper, crate::consensus::encode::Error> {
|
||||
let len = r.read_compact_size()?;
|
||||
// Do not allocate upfront more items than if the sequence of type
|
||||
// occupied roughly quarter a block. This should never be the case
|
||||
// for normal data, but even if that's not true - `push` will just
|
||||
// reallocate.
|
||||
// Note: OOM protection relies on reader eventually running out of
|
||||
// data to feed us.
|
||||
let max_capacity = crate::consensus::encode::MAX_VEC_SIZE / 4 / core::mem::size_of::<$type>();
|
||||
let mut ret = Vec::with_capacity(core::cmp::min(len as usize, max_capacity));
|
||||
for _ in 0..len {
|
||||
ret.push(Decodable::consensus_decode_from_finite_reader(r)?);
|
||||
}
|
||||
Ok($wrapper(ret))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use impl_vec_wrapper;
|
|
@ -19,6 +19,7 @@ use crate::p2p::{
|
|||
Magic,
|
||||
};
|
||||
use crate::prelude::{Box, Cow, String, ToOwned, Vec};
|
||||
use crate::p2p::deser::impl_vec_wrapper;
|
||||
use crate::{block, consensus, transaction};
|
||||
|
||||
/// The maximum number of [super::message_blockdata::Inventory] items in an `inv` message.
|
||||
|
@ -175,6 +176,10 @@ pub struct AddrPayload(pub Vec<(u32, Address)>);
|
|||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct AddrV2Payload(pub Vec<AddrV2Message>);
|
||||
|
||||
impl_vec_wrapper!(InventoryPayload, message_blockdata::Inventory);
|
||||
impl_vec_wrapper!(AddrPayload, (u32, Address));
|
||||
impl_vec_wrapper!(AddrV2Payload, AddrV2Message);
|
||||
|
||||
/// A Network message payload. Proper documentation is available on at
|
||||
/// [Bitcoin Wiki: Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification)
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -184,13 +189,13 @@ pub enum NetworkMessage {
|
|||
/// `verack`
|
||||
Verack,
|
||||
/// `addr`
|
||||
Addr(Vec<(u32, Address)>),
|
||||
Addr(AddrPayload),
|
||||
/// `inv`
|
||||
Inv(Vec<message_blockdata::Inventory>),
|
||||
Inv(InventoryPayload),
|
||||
/// `getdata`
|
||||
GetData(Vec<message_blockdata::Inventory>),
|
||||
GetData(InventoryPayload),
|
||||
/// `notfound`
|
||||
NotFound(Vec<message_blockdata::Inventory>),
|
||||
NotFound(InventoryPayload),
|
||||
/// `getblocks`
|
||||
GetBlocks(message_blockdata::GetBlocksMessage),
|
||||
/// `getheaders`
|
||||
|
@ -248,7 +253,7 @@ pub enum NetworkMessage {
|
|||
/// `wtxidrelay`
|
||||
WtxidRelay,
|
||||
/// `addrv2`
|
||||
AddrV2(Vec<AddrV2Message>),
|
||||
AddrV2(AddrV2Payload),
|
||||
/// `sendaddrv2`
|
||||
SendAddrV2,
|
||||
|
||||
|
@ -746,17 +751,17 @@ mod test {
|
|||
let msgs = [
|
||||
NetworkMessage::Version(version_msg),
|
||||
NetworkMessage::Verack,
|
||||
NetworkMessage::Addr(vec![(
|
||||
NetworkMessage::Addr(AddrPayload(vec![(
|
||||
45,
|
||||
Address::new(&([123, 255, 000, 100], 833).into(), ServiceFlags::NETWORK),
|
||||
)]),
|
||||
NetworkMessage::Inv(vec![Inventory::Block(BlockHash::from_byte_array(
|
||||
)])),
|
||||
NetworkMessage::Inv(InventoryPayload(vec![Inventory::Block(BlockHash::from_byte_array(
|
||||
hash([8u8; 32]).to_byte_array(),
|
||||
))]),
|
||||
NetworkMessage::GetData(vec![Inventory::Transaction(Txid::from_byte_array(
|
||||
))])),
|
||||
NetworkMessage::GetData(InventoryPayload(vec![Inventory::Transaction(Txid::from_byte_array(
|
||||
hash([45u8; 32]).to_byte_array(),
|
||||
))]),
|
||||
NetworkMessage::NotFound(vec![Inventory::Error([0u8; 32])]),
|
||||
))])),
|
||||
NetworkMessage::NotFound(InventoryPayload(vec![Inventory::Error([0u8; 32])])),
|
||||
NetworkMessage::GetBlocks(GetBlocksMessage::new(
|
||||
vec![
|
||||
BlockHash::from_byte_array(hash([1u8; 32]).to_byte_array()),
|
||||
|
@ -838,12 +843,12 @@ mod test {
|
|||
}),
|
||||
NetworkMessage::FeeFilter(1000),
|
||||
NetworkMessage::WtxidRelay,
|
||||
NetworkMessage::AddrV2(vec![AddrV2Message {
|
||||
NetworkMessage::AddrV2(AddrV2Payload(vec![AddrV2Message {
|
||||
addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||
port: 0,
|
||||
services: ServiceFlags::NONE,
|
||||
time: 0,
|
||||
}]),
|
||||
}])),
|
||||
NetworkMessage::SendAddrV2,
|
||||
NetworkMessage::CmpctBlock(cmptblock),
|
||||
NetworkMessage::GetBlockTxn(GetBlockTxn {
|
||||
|
|
|
@ -19,6 +19,8 @@ pub mod message_compact_blocks;
|
|||
pub mod message_filter;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod message_network;
|
||||
#[cfg(feature = "std")]
|
||||
mod deser;
|
||||
|
||||
use core::str::FromStr;
|
||||
use core::{fmt, ops};
|
||||
|
|
Loading…
Reference in New Issue