Skip to content

Commit

Permalink
Implemented pull encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
Kixunil committed Jan 19, 2024
1 parent 048c6c5 commit 804193f
Show file tree
Hide file tree
Showing 13 changed files with 961 additions and 122 deletions.
5 changes: 5 additions & 0 deletions bitcoin/src/bip158.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ consensus_encoding::hash_decoder! {
FilterHeader => pub FilterHeaderDecoder;
}

consensus_encoding::hash_encoder! {
FilterHash;
FilterHeader;
}

/// Errors for blockfilter.
#[derive(Debug)]
#[non_exhaustive]
Expand Down
6 changes: 6 additions & 0 deletions bitcoin/src/blockdata/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ consensus_encoding::hash_decoder! {
WitnessMerkleNode => pub WitnessMerkleNodeDecoder;
}

consensus_encoding::hash_encoder! {
BlockHash;
TxMerkleNode;
WitnessMerkleNode;
}

impl From<Txid> for TxMerkleNode {
fn from(txid: Txid) -> Self { Self::from_byte_array(txid.to_byte_array()) }
}
Expand Down
15 changes: 6 additions & 9 deletions bitcoin/src/blockdata/locktime/absolute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! whether `LockTime < LOCKTIME_THRESHOLD`.
//!

use consensus_encoding::encoder_newtype;
use core::cmp::{Ordering, PartialOrd};
use core::{fmt, mem};

Expand All @@ -16,7 +17,6 @@ use mutagen::mutate;

#[cfg(doc)]
use crate::absolute;
use crate::consensus::encode::Encodable;
use crate::error::ParseIntError;
use crate::parse::{impl_parse_str_from_int_fallible, impl_parse_str_from_int_infallible};
use crate::prelude::*;
Expand Down Expand Up @@ -335,20 +335,17 @@ impl FromHexStr for LockTime {
}
}

impl Encodable for LockTime {
#[inline]
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let v = self.to_consensus_u32();
v.consensus_encode(w)
}
}

crate::impl_decodable_using_decode!(LockTime);
crate::impl_encodable_using_encode!(LockTime);

consensus_encoding::mapped_decoder! {
LockTime => #[derive(Default)] pub struct LockTimeDecoder(<u32 as consensus_encoding::Decode>::Decoder) using LockTime::from_consensus;
}

encoder_newtype! {
LockTime => pub struct LockTimeEncoder(consensus_encoding::push_decode::encoders::IntEncoder<u32>) map u32 as |lock_time: &LockTime| lock_time.to_consensus_u32();
}

#[cfg(feature = "serde")]
impl serde::Serialize for LockTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Expand Down
42 changes: 42 additions & 0 deletions bitcoin/src/blockdata/script/borrowed.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: CC0-1.0

use consensus_encoding::{EncodeTc, VarIntEncoder};
use core::convert::{TryFrom, TryInto};
use core::fmt;
use core::ops::{
Expand Down Expand Up @@ -619,6 +620,47 @@ impl Script {
}
}

impl<'a> EncodeTc<'a> for Script {
type Encoder = ScriptEncoder<'a>;
}

impl consensus_encoding::Encode for Script {
const MIN_ENCODED_LEN: usize = 1;
const IS_KNOWN_LEN: bool = false;

fn encoder(&self) -> <Self as EncodeTc<'_>>::Encoder {
ScriptEncoder {
len: Some(VarIntEncoder::new(self.len() as u64)),
script: self,
}
}

fn dyn_encoded_len(&self, max_steps: usize) -> (usize, usize) {
if max_steps == 0 { return (0, 0); }
let (len, max_steps) = VarIntEncoder::dyn_encoded_len(self.len() as u64, max_steps - 1);
(len + self.len(), max_steps)
}
}

/// Encoder of [`Script`]
pub struct ScriptEncoder<'a> {
len: Option<VarIntEncoder>,
script: &'a Script,
}

impl consensus_encoding::Encoder for ScriptEncoder<'_> {
fn encoded_chunk(&self) -> &[u8] {
match &self.len {
Some(len) => len.encoded_chunk(),
None => self.script.as_bytes(),
}
}

fn next(&mut self) -> bool {
self.len.take().is_some() && !self.script.is_empty()
}
}

/// Iterator over bytes of a script
pub struct Bytes<'a>(core::iter::Copied<core::slice::Iter<'a, u8>>);

Expand Down
36 changes: 20 additions & 16 deletions bitcoin/src/blockdata/script/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use core::cmp::Ordering;
use core::fmt;
use core::ops::{Deref, DerefMut};

use consensus_encoding::mapped_decoder;
use consensus_encoding::{mapped_decoder, EncodeTc};
use consensus_encoding::push_decode::decoders::{ByteVecDecoder, combinators::Then};
use crate::consensus::encode::{VarIntDecoder, MAX_VEC_SIZE};
use hashes::{hash160, sha256};
Expand All @@ -75,7 +75,6 @@ use serde;

use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self, Opcode};
use crate::consensus::Encodable;
use crate::internal_macros::impl_asref_push_bytes;
use crate::prelude::*;
use crate::{io, OutPoint};
Expand Down Expand Up @@ -581,20 +580,8 @@ impl<'de> serde::Deserialize<'de> for ScriptBuf {
}
}

impl Encodable for Script {
#[inline]
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
crate::consensus::encode::consensus_encode_with_size(&self.0, w)
}
}

impl Encodable for ScriptBuf {
#[inline]
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.0.consensus_encode(w)
}
}

crate::impl_encodable_using_encode!(Script);
crate::impl_encodable_using_encode!(ScriptBuf);
crate::impl_decodable_using_decode!(ScriptBuf);

mapped_decoder! {
Expand All @@ -611,6 +598,23 @@ impl Default for ScriptDecoder {
}
}

impl<'a> EncodeTc<'a> for ScriptBuf {
type Encoder = <Script as EncodeTc<'a>>::Encoder;
}

impl consensus_encoding::Encode for ScriptBuf {
const MIN_ENCODED_LEN: usize = Script::MIN_ENCODED_LEN;
const IS_KNOWN_LEN: bool = Script::IS_KNOWN_LEN;

fn encoder(&self) -> <Self as EncodeTc<'_>>::Encoder {
(**self).encoder()
}

fn dyn_encoded_len(&self, max_steps: usize) -> (usize, usize) {
(**self).dyn_encoded_len(max_steps)
}
}

/// Writes the assembly decoding of the script bytes to the formatter.
pub(super) fn bytes_to_asm_fmt(script: &[u8], f: &mut dyn fmt::Write) -> fmt::Result {
// This has to be a macro because it needs to break the loop
Expand Down
Loading

0 comments on commit 804193f

Please sign in to comment.