make consensus_encode return the encoded length
This commit is contained in:
parent
abb9210c04
commit
b734d6488a
|
@ -24,8 +24,6 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use consensus::{encode, Decodable, Encodable, ReadExt, WriteExt};
|
|
||||||
|
|
||||||
// Note: I am deliberately not implementing PartialOrd or Ord on the
|
// Note: I am deliberately not implementing PartialOrd or Ord on the
|
||||||
// opcode enum. If you want to check ranges of opcodes, etc.,
|
// opcode enum. If you want to check ranges of opcodes, etc.,
|
||||||
// write an #[inline] helper function which casts to u8s.
|
// write an #[inline] helper function which casts to u8s.
|
||||||
|
@ -714,20 +712,6 @@ impl From<u8> for All {
|
||||||
|
|
||||||
display_from_debug!(All);
|
display_from_debug!(All);
|
||||||
|
|
||||||
impl<D: ReadExt> Decodable<D> for All {
|
|
||||||
#[inline]
|
|
||||||
fn consensus_decode(d: &mut D) -> Result<All, encode::Error> {
|
|
||||||
Ok(All::from(d.read_u8()?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for All {
|
|
||||||
#[inline]
|
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
|
||||||
s.emit_u8(self.code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
impl serde::Serialize for All {
|
impl serde::Serialize for All {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -834,7 +818,6 @@ impl Ordinary {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use consensus::encode::{serialize, deserialize};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
macro_rules! roundtrip {
|
macro_rules! roundtrip {
|
||||||
|
@ -846,9 +829,6 @@ mod tests {
|
||||||
assert_eq!(s1, s2);
|
assert_eq!(s1, s2);
|
||||||
assert_eq!(s1, stringify!($op));
|
assert_eq!(s1, stringify!($op));
|
||||||
assert!($unique.insert(s1));
|
assert!($unique.insert(s1));
|
||||||
|
|
||||||
let enc = serialize(&all::$op);
|
|
||||||
assert_eq!(all::$op, deserialize(&enc).unwrap());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -727,7 +727,7 @@ impl serde::Serialize for Script {
|
||||||
// Network serialization
|
// Network serialization
|
||||||
impl<S: WriteExt> Encodable<S> for Script {
|
impl<S: WriteExt> Encodable<S> for Script {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
self.0.consensus_encode(s)
|
self.0.consensus_encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,9 +440,9 @@ impl BitcoinHash for Transaction {
|
||||||
impl_consensus_encoding!(TxOut, value, script_pubkey);
|
impl_consensus_encoding!(TxOut, value, script_pubkey);
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for OutPoint {
|
impl<S: WriteExt> Encodable<S> for OutPoint {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result <(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result <usize, encode::Error> {
|
||||||
self.txid.consensus_encode(s)?;
|
let len = self.txid.consensus_encode(s)?;
|
||||||
self.vout.consensus_encode(s)
|
Ok(len + self.vout.consensus_encode(s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<D: ReadExt> Decodable<D> for OutPoint {
|
impl<D: ReadExt> Decodable<D> for OutPoint {
|
||||||
|
@ -455,10 +455,12 @@ impl<D: ReadExt> Decodable<D> for OutPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for TxIn {
|
impl<S: WriteExt> Encodable<S> for TxIn {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result <(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result <usize, encode::Error> {
|
||||||
self.previous_output.consensus_encode(s)?;
|
let mut len = 0;
|
||||||
self.script_sig.consensus_encode(s)?;
|
len += self.previous_output.consensus_encode(s)?;
|
||||||
self.sequence.consensus_encode(s)
|
len += self.script_sig.consensus_encode(s)?;
|
||||||
|
len += self.sequence.consensus_encode(s)?;
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<D: ReadExt> Decodable<D> for TxIn {
|
impl<D: ReadExt> Decodable<D> for TxIn {
|
||||||
|
@ -473,8 +475,9 @@ impl<D: ReadExt> Decodable<D> for TxIn {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Transaction {
|
impl<S: WriteExt> Encodable<S> for Transaction {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result <(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result <usize, encode::Error> {
|
||||||
self.version.consensus_encode(s)?;
|
let mut len = 0;
|
||||||
|
len += self.version.consensus_encode(s)?;
|
||||||
let mut have_witness = self.input.is_empty();
|
let mut have_witness = self.input.is_empty();
|
||||||
for input in &self.input {
|
for input in &self.input {
|
||||||
if !input.witness.is_empty() {
|
if !input.witness.is_empty() {
|
||||||
|
@ -483,18 +486,19 @@ impl<S: WriteExt> Encodable<S> for Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !have_witness {
|
if !have_witness {
|
||||||
self.input.consensus_encode(s)?;
|
len += self.input.consensus_encode(s)?;
|
||||||
self.output.consensus_encode(s)?;
|
len += self.output.consensus_encode(s)?;
|
||||||
} else {
|
} else {
|
||||||
0u8.consensus_encode(s)?;
|
len += 0u8.consensus_encode(s)?;
|
||||||
1u8.consensus_encode(s)?;
|
len += 1u8.consensus_encode(s)?;
|
||||||
self.input.consensus_encode(s)?;
|
len += self.input.consensus_encode(s)?;
|
||||||
self.output.consensus_encode(s)?;
|
len += self.output.consensus_encode(s)?;
|
||||||
for input in &self.input {
|
for input in &self.input {
|
||||||
input.witness.consensus_encode(s)?;
|
len += input.witness.consensus_encode(s)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lock_time.consensus_encode(s)
|
len += self.lock_time.consensus_encode(s)?;
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,8 +372,9 @@ pub const MAX_VEC_SIZE: usize = 32 * 1024 * 1024;
|
||||||
/// Data which can be encoded in a consensus-consistent way
|
/// Data which can be encoded in a consensus-consistent way
|
||||||
pub trait Encodable<S: WriteExt> {
|
pub trait Encodable<S: WriteExt> {
|
||||||
/// Encode an object with a well-defined format, should only ever error if
|
/// Encode an object with a well-defined format, should only ever error if
|
||||||
/// the underlying WriteExt errors.
|
/// the underlying WriteExt errors. Returns the number of bytes written on
|
||||||
fn consensus_encode(&self, e: &mut S) -> Result<(), self::Error>;
|
/// success
|
||||||
|
fn consensus_encode(&self, e: &mut S) -> Result<usize, self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data which can be encoded in a consensus-consistent way
|
/// Data which can be encoded in a consensus-consistent way
|
||||||
|
@ -400,7 +401,10 @@ macro_rules! impl_int_encodable{
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for $ty {
|
impl<S: WriteExt> Encodable<S> for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> { s.$meth_enc(self.to_le()) }
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
|
s.$meth_enc(self.to_le())?;
|
||||||
|
Ok(mem::size_of::<$ty>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -431,12 +435,12 @@ impl VarInt {
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for VarInt {
|
impl<S: WriteExt> Encodable<S> for VarInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
0...0xFC => { (self.0 as u8).consensus_encode(s) }
|
0...0xFC => { (self.0 as u8).consensus_encode(s)?; Ok(1) }
|
||||||
0xFD...0xFFFF => { s.emit_u8(0xFD)?; (self.0 as u16).consensus_encode(s) }
|
0xFD...0xFFFF => { s.emit_u8(0xFD)?; (self.0 as u16).consensus_encode(s)?; Ok(3) }
|
||||||
0x10000...0xFFFFFFFF => { s.emit_u8(0xFE)?; (self.0 as u32).consensus_encode(s) }
|
0x10000...0xFFFFFFFF => { s.emit_u8(0xFE)?; (self.0 as u32).consensus_encode(s)?; Ok(5) }
|
||||||
_ => { s.emit_u8(0xFF)?; (self.0 as u64).consensus_encode(s) }
|
_ => { s.emit_u8(0xFF)?; (self.0 as u64).consensus_encode(s)?; Ok(9) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,7 +483,10 @@ impl<D: ReadExt> Decodable<D> for VarInt {
|
||||||
// Booleans
|
// Booleans
|
||||||
impl<S: WriteExt> Encodable<S> for bool {
|
impl<S: WriteExt> Encodable<S> for bool {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> { s.emit_u8(if *self {1} else {0}) }
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
|
s.emit_u8(if *self {1} else {0})?;
|
||||||
|
Ok(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: ReadExt> Decodable<D> for bool {
|
impl<D: ReadExt> Decodable<D> for bool {
|
||||||
|
@ -490,10 +497,11 @@ impl<D: ReadExt> Decodable<D> for bool {
|
||||||
// Strings
|
// Strings
|
||||||
impl<S: WriteExt> Encodable<S> for String {
|
impl<S: WriteExt> Encodable<S> for String {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
let b = self.as_bytes();
|
let b = self.as_bytes();
|
||||||
VarInt(b.len() as u64).consensus_encode(s)?;
|
let vi_len = VarInt(b.len() as u64).consensus_encode(s)?;
|
||||||
s.emit_slice(&b)
|
s.emit_slice(&b)?;
|
||||||
|
Ok(vi_len + b.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,8 +519,9 @@ macro_rules! impl_array {
|
||||||
( $size:expr ) => (
|
( $size:expr ) => (
|
||||||
impl<S: WriteExt> Encodable<S> for [u8; $size] {
|
impl<S: WriteExt> Encodable<S> for [u8; $size] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
s.emit_slice(&self[..])
|
s.emit_slice(&self[..])?;
|
||||||
|
Ok(self.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,9 +557,9 @@ impl<D: ReadExt> Decodable<D> for [u16; 8] {
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for [u16; 8] {
|
impl<S: WriteExt> Encodable<S> for [u16; 8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
for c in self.iter() { c.consensus_encode(s)?; }
|
for c in self.iter() { c.consensus_encode(s)?; }
|
||||||
Ok(())
|
Ok(16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,10 +568,13 @@ macro_rules! impl_vec {
|
||||||
($type: ty) => {
|
($type: ty) => {
|
||||||
impl<S: WriteExt> Encodable<S> for Vec<$type> {
|
impl<S: WriteExt> Encodable<S> for Vec<$type> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
VarInt(self.len() as u64).consensus_encode(s)?;
|
let mut len = 0;
|
||||||
for c in self.iter() { c.consensus_encode(s)?; }
|
len += VarInt(self.len() as u64).consensus_encode(s)?;
|
||||||
Ok(())
|
for c in self.iter() {
|
||||||
|
len += c.consensus_encode(s)?;
|
||||||
|
}
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,9 +606,10 @@ impl_vec!(u64);
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Vec<u8> {
|
impl<S: WriteExt> Encodable<S> for Vec<u8> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
VarInt(self.len() as u64).consensus_encode(s)?;
|
let vi_len = VarInt(self.len() as u64).consensus_encode(s)?;
|
||||||
s.emit_slice(&self)
|
s.emit_slice(&self)?;
|
||||||
|
Ok(vi_len + self.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,9 +630,10 @@ impl<D: ReadExt> Decodable<D> for Vec<u8> {
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Box<[u8]> {
|
impl<S: WriteExt> Encodable<S> for Box<[u8]> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
VarInt(self.len() as u64).consensus_encode(s)?;
|
let vi_len = VarInt(self.len() as u64).consensus_encode(s)?;
|
||||||
s.emit_slice(&self)
|
s.emit_slice(&self)?;
|
||||||
|
Ok(vi_len + self.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,10 +662,11 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
|
||||||
// Checked data
|
// Checked data
|
||||||
impl<S: WriteExt> Encodable<S> for CheckedData {
|
impl<S: WriteExt> Encodable<S> for CheckedData {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
(self.0.len() as u32).consensus_encode(s)?;
|
(self.0.len() as u32).consensus_encode(s)?;
|
||||||
sha2_checksum(&self.0).consensus_encode(s)?;
|
sha2_checksum(&self.0).consensus_encode(s)?;
|
||||||
s.emit_slice(&self.0)
|
s.emit_slice(&self.0)?;
|
||||||
|
Ok(8 + self.0.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,10 +702,11 @@ macro_rules! tuple_encode {
|
||||||
impl <S: WriteExt, $($x: Encodable<S>),*> Encodable<S> for ($($x),*) {
|
impl <S: WriteExt, $($x: Encodable<S>),*> Encodable<S> for ($($x),*) {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
let &($(ref $x),*) = self;
|
let &($(ref $x),*) = self;
|
||||||
$( $x.consensus_encode(s)?; )*
|
let mut len = 0;
|
||||||
Ok(())
|
$(len += $x.consensus_encode(s)?;)*
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +726,7 @@ tuple_encode!(T0, T1, T2, T3, T4, T5);
|
||||||
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
|
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for sha256d::Hash {
|
impl<S: WriteExt> Encodable<S> for sha256d::Hash {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, self::Error> {
|
||||||
self.into_inner().consensus_encode(s)
|
self.into_inner().consensus_encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,10 @@ macro_rules! impl_consensus_encoding {
|
||||||
($thing:ident, $($field:ident),+) => (
|
($thing:ident, $($field:ident),+) => (
|
||||||
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $thing {
|
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $thing {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), ::consensus::encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, ::consensus::encode::Error> {
|
||||||
$( self.$field.consensus_encode(s)?; )+
|
let mut len = 0;
|
||||||
Ok(())
|
$(len += self.$field.consensus_encode(s)?;)+
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,12 @@ fn addr_to_be(addr: [u16; 8]) -> [u16; 8] {
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Address {
|
impl<S: WriteExt> Encodable<S> for Address {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
self.services.consensus_encode(s)?;
|
let mut len = 0;
|
||||||
addr_to_be(self.address).consensus_encode(s)?;
|
len += self.services.consensus_encode(s)?;
|
||||||
self.port.to_be().consensus_encode(s)
|
len += addr_to_be(self.address).consensus_encode(s)?;
|
||||||
|
len += self.port.to_be().consensus_encode(s)?;
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,11 @@
|
||||||
//! use bitcoin::consensus::encode::serialize;
|
//! use bitcoin::consensus::encode::serialize;
|
||||||
//!
|
//!
|
||||||
//! let network = Network::Bitcoin;
|
//! let network = Network::Bitcoin;
|
||||||
//! let bytes = serialize(&network);
|
//! let bytes = serialize(&network.magic());
|
||||||
//!
|
//!
|
||||||
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
|
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use consensus::{encode, Decodable, Encodable, ReadExt, WriteExt};
|
|
||||||
|
|
||||||
/// Version of the protocol as appearing in network message headers
|
/// Version of the protocol as appearing in network message headers
|
||||||
pub const PROTOCOL_VERSION: u32 = 70001;
|
pub const PROTOCOL_VERSION: u32 = 70001;
|
||||||
/// Bitfield of services provided by this node
|
/// Bitfield of services provided by this node
|
||||||
|
@ -101,44 +99,39 @@ impl Network {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Network {
|
|
||||||
/// Encodes the magic bytes of `Network`.
|
|
||||||
#[inline]
|
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
|
||||||
self.magic().consensus_encode(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: ReadExt> Decodable<D> for Network {
|
|
||||||
/// Decodes the magic bytes of `Network`.
|
|
||||||
#[inline]
|
|
||||||
fn consensus_decode(d: &mut D) -> Result<Network, encode::Error> {
|
|
||||||
u32::consensus_decode(d)
|
|
||||||
.and_then(|m| {
|
|
||||||
Network::from_magic(m)
|
|
||||||
.ok_or(encode::Error::UnknownNetworkMagic(m))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Network;
|
use super::Network;
|
||||||
use consensus::encode::{deserialize, serialize};
|
use consensus::encode::{deserialize, serialize};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_test() {
|
fn serialize_test() {
|
||||||
assert_eq!(serialize(&Network::Bitcoin), vec![0xf9, 0xbe, 0xb4, 0xd9]);
|
assert_eq!(
|
||||||
assert_eq!(serialize(&Network::Testnet), vec![0x0b, 0x11, 0x09, 0x07]);
|
serialize(&Network::Bitcoin.magic()),
|
||||||
assert_eq!(serialize(&Network::Regtest), vec![0xfa, 0xbf, 0xb5, 0xda]);
|
&[0xf9, 0xbe, 0xb4, 0xd9]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serialize(&Network::Testnet.magic()),
|
||||||
|
&[0x0b, 0x11, 0x09, 0x07]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serialize(&Network::Regtest.magic()),
|
||||||
|
&[0xfa, 0xbf, 0xb5, 0xda]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin));
|
assert_eq!(
|
||||||
assert_eq!(deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(), Some(Network::Testnet));
|
deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(),
|
||||||
assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest));
|
Some(Network::Bitcoin.magic())
|
||||||
|
);
|
||||||
let bad: Result<Network, _> = deserialize("fakenet".as_bytes());
|
assert_eq!(
|
||||||
assert!(bad.is_err());
|
deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(),
|
||||||
}
|
Some(Network::Testnet.magic())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(),
|
||||||
|
Some(Network::Regtest.magic())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn string_test() {
|
fn string_test() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct CommandString(pub String);
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for CommandString {
|
impl<S: WriteExt> Encodable<S> for CommandString {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
let &CommandString(ref inner_str) = self;
|
let &CommandString(ref inner_str) = self;
|
||||||
let mut rawbytes = [0u8; 12];
|
let mut rawbytes = [0u8; 12];
|
||||||
let strbytes = inner_str.as_bytes();
|
let strbytes = inner_str.as_bytes();
|
||||||
|
@ -162,21 +162,23 @@ impl RawNetworkMessage {
|
||||||
struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
|
struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
|
||||||
impl <'a, S: WriteExt> Encodable<S> for HeaderSerializationWrapper<'a> {
|
impl <'a, S: WriteExt> Encodable<S> for HeaderSerializationWrapper<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
VarInt(self.0.len() as u64).consensus_encode(s)?;
|
let mut len = 0;
|
||||||
|
len += VarInt(self.0.len() as u64).consensus_encode(s)?;
|
||||||
for header in self.0.iter() {
|
for header in self.0.iter() {
|
||||||
header.consensus_encode(s)?;
|
len += header.consensus_encode(s)?;
|
||||||
0u8.consensus_encode(s)?;
|
len += 0u8.consensus_encode(s)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for RawNetworkMessage {
|
impl<S: WriteExt> Encodable<S> for RawNetworkMessage {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
self.magic.consensus_encode(s)?;
|
let mut len = 0;
|
||||||
CommandString(self.command()).consensus_encode(s)?;
|
len += self.magic.consensus_encode(s)?;
|
||||||
CheckedData(match self.payload {
|
len += CommandString(self.command()).consensus_encode(s)?;
|
||||||
|
len += CheckedData(match self.payload {
|
||||||
NetworkMessage::Version(ref dat) => serialize(dat),
|
NetworkMessage::Version(ref dat) => serialize(dat),
|
||||||
NetworkMessage::Addr(ref dat) => serialize(dat),
|
NetworkMessage::Addr(ref dat) => serialize(dat),
|
||||||
NetworkMessage::Inv(ref dat) => serialize(dat),
|
NetworkMessage::Inv(ref dat) => serialize(dat),
|
||||||
|
@ -200,7 +202,8 @@ impl<S: WriteExt> Encodable<S> for RawNetworkMessage {
|
||||||
| NetworkMessage::SendHeaders
|
| NetworkMessage::SendHeaders
|
||||||
| NetworkMessage::MemPool
|
| NetworkMessage::MemPool
|
||||||
| NetworkMessage::GetAddr => vec![],
|
| NetworkMessage::GetAddr => vec![],
|
||||||
}).consensus_encode(s)
|
}).consensus_encode(s)?;
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,15 +103,15 @@ impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Inventory {
|
impl<S: WriteExt> Encodable<S> for Inventory {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
match self.inv_type {
|
let inv_len = match self.inv_type {
|
||||||
InvType::Error => 0u32,
|
InvType::Error => 0u32,
|
||||||
InvType::Transaction => 1,
|
InvType::Transaction => 1,
|
||||||
InvType::Block => 2,
|
InvType::Block => 2,
|
||||||
InvType::WitnessBlock => 0x40000002,
|
InvType::WitnessBlock => 0x40000002,
|
||||||
InvType::WitnessTransaction => 0x40000001
|
InvType::WitnessTransaction => 0x40000001
|
||||||
}.consensus_encode(s)?;
|
}.consensus_encode(s)?;
|
||||||
self.hash.consensus_encode(s)
|
Ok(inv_len + self.hash.consensus_encode(s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,14 +354,14 @@ impl PartialMerkleTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for PartialMerkleTree {
|
impl<S: WriteExt> Encodable<S> for PartialMerkleTree {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, Error> {
|
||||||
self.num_transactions.consensus_encode(s)?;
|
let ret = self.num_transactions.consensus_encode(s)?
|
||||||
self.hashes.consensus_encode(s)?;
|
+ self.hashes.consensus_encode(s)?;
|
||||||
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
|
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
|
||||||
for p in 0..self.bits.len() {
|
for p in 0..self.bits.len() {
|
||||||
bytes[p / 8] |= (self.bits[p] as u8) << (p % 8) as u8;
|
bytes[p / 8] |= (self.bits[p] as u8) << (p % 8) as u8;
|
||||||
}
|
}
|
||||||
bytes.consensus_encode(s)
|
Ok(ret + bytes.consensus_encode(s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,9 +472,8 @@ impl MerkleBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for MerkleBlock {
|
impl<S: WriteExt> Encodable<S> for MerkleBlock {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, Error> {
|
||||||
self.header.consensus_encode(s)?;
|
Ok(self.header.consensus_encode(s)? + self.txn.consensus_encode(s)?)
|
||||||
self.txn.consensus_encode(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,13 @@ macro_rules! impl_psbt_serialize {
|
||||||
macro_rules! impl_psbtmap_consensus_encoding {
|
macro_rules! impl_psbtmap_consensus_encoding {
|
||||||
($thing:ty) => {
|
($thing:ty) => {
|
||||||
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $thing {
|
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $thing {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), ::consensus::encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, ::consensus::encode::Error> {
|
||||||
|
let mut len = 0;
|
||||||
for pair in ::util::psbt::Map::get_pairs(self)? {
|
for pair in ::util::psbt::Map::get_pairs(self)? {
|
||||||
::consensus::Encodable::consensus_encode(&pair, s)?
|
len += ::consensus::Encodable::consensus_encode(&pair, s)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
::consensus::Encodable::consensus_encode(&0x00_u8, s)
|
Ok(len + ::consensus::Encodable::consensus_encode(&0x00_u8, s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,22 +89,23 @@ impl PartiallySignedTransaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for PartiallySignedTransaction {
|
impl<S: WriteExt> Encodable<S> for PartiallySignedTransaction {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
b"psbt".consensus_encode(s)?;
|
let mut len = 0;
|
||||||
|
len += b"psbt".consensus_encode(s)?;
|
||||||
|
|
||||||
0xff_u8.consensus_encode(s)?;
|
len += 0xff_u8.consensus_encode(s)?;
|
||||||
|
|
||||||
self.global.consensus_encode(s)?;
|
len += self.global.consensus_encode(s)?;
|
||||||
|
|
||||||
for i in &self.inputs {
|
for i in &self.inputs {
|
||||||
i.consensus_encode(s)?;
|
len += i.consensus_encode(s)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in &self.outputs {
|
for i in &self.outputs {
|
||||||
i.consensus_encode(s)?;
|
len += i.consensus_encode(s)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,23 +81,24 @@ impl<D: ReadExt> Decodable<D> for Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Key {
|
impl<S: WriteExt> Encodable<S> for Key {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
VarInt((self.key.len() + 1) as u64).consensus_encode(s)?;
|
let mut len = 0;
|
||||||
|
len += VarInt((self.key.len() + 1) as u64).consensus_encode(s)?;
|
||||||
|
|
||||||
self.type_value.consensus_encode(s)?;
|
len += self.type_value.consensus_encode(s)?;
|
||||||
|
|
||||||
for key in &self.key {
|
for key in &self.key {
|
||||||
key.consensus_encode(s)?
|
len += key.consensus_encode(s)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: WriteExt> Encodable<S> for Pair {
|
impl<S: WriteExt> Encodable<S> for Pair {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
self.key.consensus_encode(s)?;
|
let len = self.key.consensus_encode(s)?;
|
||||||
self.value.consensus_encode(s)
|
Ok(len + self.value.consensus_encode(s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,10 +338,13 @@ macro_rules! construct_uint {
|
||||||
|
|
||||||
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $name {
|
impl<S: ::consensus::WriteExt> ::consensus::Encodable<S> for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<usize, encode::Error> {
|
||||||
let &$name(ref data) = self;
|
let &$name(ref data) = self;
|
||||||
for word in data.iter() { word.consensus_encode(s)?; }
|
let mut len = 0;
|
||||||
Ok(())
|
for word in data.iter() {
|
||||||
|
len += word.consensus_encode(s)?;
|
||||||
|
}
|
||||||
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue