Skip to content

Commit

Permalink
Impl push-based consensus decoding for a few types
Browse files Browse the repository at this point in the history
This implements `bitcoin_consensus_encoding::Decode` for `Transaction`
and the types used inside it to demonstrate how `push_decode` can be
used to abstract over the byte source (sync/async, std/no-std). The
change is designed to be incremental so the exisitng code continues to
use old traits, we're just adding new capabilities that may later
replace the current encoding approach.
  • Loading branch information
Kixunil committed Jan 17, 2024
1 parent cb74b90 commit c2f9b99
Show file tree
Hide file tree
Showing 18 changed files with 533 additions and 214 deletions.
110 changes: 64 additions & 46 deletions Cargo-recent.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ version = 3

[[package]]
name = "anyhow"
version = "1.0.71"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"

[[package]]
name = "base64"
version = "0.21.3"
version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"

[[package]]
name = "bech32"
Expand All @@ -22,10 +22,11 @@ checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea"

[[package]]
name = "bincode"
version = "1.3.3"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
dependencies = [
"byteorder",
"serde",
]

Expand All @@ -36,6 +37,7 @@ dependencies = [
"base64",
"bech32",
"bincode",
"bitcoin-consensus-encoding",
"bitcoin-internals",
"bitcoin-io",
"bitcoin-units",
Expand Down Expand Up @@ -114,27 +116,33 @@ dependencies = [

[[package]]
name = "byteorder"
version = "1.4.3"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
checksum = "60f0b0d4c0a382d2734228fd12b5a6b5dac185c60e938026fd31b265b94f9bd2"

[[package]]
name = "cc"
version = "1.0.79"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
checksum = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"

[[package]]
name = "cfg-if"
version = "1.0.0"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
checksum = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"

[[package]]
name = "dyn-clone"
version = "1.0.11"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da518043f6481364cd454be81dfe096cfd3f82daa1466f4946d24ea325b0941"

[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"

[[package]]
name = "either"
Expand All @@ -144,9 +152,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"

[[package]]
name = "getrandom"
version = "0.2.9"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
dependencies = [
"cfg-if",
"libc",
Expand Down Expand Up @@ -184,9 +192,9 @@ dependencies = [

[[package]]
name = "itoa"
version = "1.0.6"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"

[[package]]
name = "json"
Expand All @@ -202,9 +210,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"

[[package]]
name = "libc"
version = "0.2.142"
version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"

[[package]]
name = "memmap2"
Expand Down Expand Up @@ -256,15 +264,15 @@ checksum = "7f0642533dea0bb58bd5cae31bafc1872429f0f12ac8c61fe2b4ba44f80b959b"

[[package]]
name = "ppv-lite86"
version = "0.2.17"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"

[[package]]
name = "proc-macro2"
version = "1.0.63"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
Expand All @@ -280,43 +288,53 @@ dependencies = [

[[package]]
name = "quote"
version = "1.0.26"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]

[[package]]
name = "rand"
version = "0.8.5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]

[[package]]
name = "rand_chacha"
version = "0.3.1"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core",
]

[[package]]
name = "rand_core"
version = "0.6.4"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
"getrandom",
]

[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core",
]

[[package]]
name = "rustc_version"
version = "0.4.0"
Expand All @@ -328,15 +346,15 @@ dependencies = [

[[package]]
name = "ryu"
version = "1.0.13"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
checksum = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"

[[package]]
name = "schemars"
version = "0.8.12"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f"
checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78"
dependencies = [
"dyn-clone",
"serde",
Expand Down Expand Up @@ -372,9 +390,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"

[[package]]
name = "serde"
version = "1.0.156"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
dependencies = [
"serde_derive",
]
Expand All @@ -392,9 +410,9 @@ dependencies = [

[[package]]
name = "serde_derive"
version = "1.0.156"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
dependencies = [
"proc-macro2",
"quote",
Expand All @@ -403,9 +421,9 @@ dependencies = [

[[package]]
name = "serde_json"
version = "1.0.96"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
dependencies = [
"itoa",
"ryu",
Expand All @@ -414,9 +432,9 @@ dependencies = [

[[package]]
name = "serde_test"
version = "1.0.160"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c95a500e3923258f7fc3a16bf29934e403aef5ca1096e184d85e3b1926675e8"
checksum = "482765e11e55174e2d74a611674d09ed96712c00e0777e305a0c416dfef5fa40"
dependencies = [
"serde",
]
Expand All @@ -440,6 +458,6 @@ checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"

[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1 change: 1 addition & 0 deletions bitcoin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
bech32 = { version = "0.10.0-beta", default-features = false, features = ["alloc"] }
consensus-encoding = { package = "bitcoin-consensus-encoding", path = "../consensus-encoding", features = ["hashes"] }
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false, features = ["alloc", "io"] }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }
hex_lit = "0.1.1"
Expand Down
5 changes: 5 additions & 0 deletions bitcoin/src/bip158.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ hashes::hash_newtype! {
impl_hashencode!(FilterHash);
impl_hashencode!(FilterHeader);

consensus_encoding::hash_decoder! {
FilterHash => pub FilterHashDecoder;
FilterHeader => pub FilterHeaderDecoder;
}

/// 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 @@ -36,6 +36,12 @@ impl_hashencode!(BlockHash);
impl_hashencode!(TxMerkleNode);
impl_hashencode!(WitnessMerkleNode);

consensus_encoding::hash_decoder! {
BlockHash => pub BlockHashDecoder;
TxMerkleNode => pub TxMerkleNodeDecoder;
WitnessMerkleNode => pub WitnessMerkleNodeDecoder;
}

impl From<Txid> for TxMerkleNode {
fn from(txid: Txid) -> Self { Self::from_byte_array(txid.to_byte_array()) }
}
Expand Down
13 changes: 6 additions & 7 deletions bitcoin/src/blockdata/locktime/absolute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use core::cmp::{Ordering, PartialOrd};
use core::{fmt, mem};

use internals::write_err;
use io::{BufRead, Write};
use io::Write;
#[cfg(all(test, mutate))]
use mutagen::mutate;

#[cfg(doc)]
use crate::absolute;
use crate::consensus::encode::{self, Decodable, Encodable};
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 @@ -343,11 +343,10 @@ impl Encodable for LockTime {
}
}

impl Decodable for LockTime {
#[inline]
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
u32::consensus_decode(r).map(LockTime::from_consensus)
}
crate::impl_decodable_using_decode!(LockTime);

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

#[cfg(feature = "serde")]
Expand Down
26 changes: 18 additions & 8 deletions bitcoin/src/blockdata/script/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,17 @@ use core::cmp::Ordering;
use core::fmt;
use core::ops::{Deref, DerefMut};

use consensus_encoding::mapped_decoder;
use consensus_encoding::push_decode::decoders::{ByteVecDecoder, combinators::Then};
use crate::consensus::encode::VarIntDecoder;
use hashes::{hash160, sha256};
use io::{BufRead, Write};
use io::Write;
#[cfg(feature = "serde")]
use serde;

use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self, Opcode};
use crate::consensus::{encode, Decodable, Encodable};
use crate::consensus::Encodable;
use crate::internal_macros::impl_asref_push_bytes;
use crate::prelude::*;
use crate::{io, OutPoint};
Expand Down Expand Up @@ -592,12 +595,19 @@ impl Encodable for ScriptBuf {
}
}

impl Decodable for ScriptBuf {
#[inline]
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
r: &mut R,
) -> Result<Self, encode::Error> {
Ok(ScriptBuf(Decodable::consensus_decode_from_finite_reader(r)?))
crate::impl_decodable_using_decode!(ScriptBuf);

mapped_decoder! {
ScriptBuf => pub struct ScriptDecoder(Then<VarIntDecoder, ByteVecDecoder, fn(u64) -> ByteVecDecoder>) using ScriptBuf::from;
}

impl Default for ScriptDecoder {
fn default() -> Self {
use consensus_encoding::Decoder;

ScriptDecoder(VarIntDecoder::default().then(|len| {
ByteVecDecoder::new(len as usize)
}))
}
}

Expand Down
Loading

0 comments on commit c2f9b99

Please sign in to comment.