Skip to content

Use bitcoin-units 1.0 #229

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

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
9 changes: 4 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,22 @@ default = ["json-contract"]
json-contract = ["serde_json"]
"serde" = [
"bitcoin/serde",
"bitcoin/serde",
"bitcoin-units/serde",
"secp256k1-zkp/serde",
"actual-serde",
"dep:serde",
]
base64 = ["bitcoin/base64"]

[dependencies]
bech32 = "0.11.0"
bitcoin = "0.32.2"
bitcoin-units = { version = "1.0.0-rc.0", default-features = false, features = [ "std" ] }
secp256k1-zkp = { version = "0.11.0", features = ["global-context", "hashes"] }

# Used for ContractHash::from_json_contract.
serde_json = { version = "1.0", optional = true }

actual-serde = { package = "serde", version = "1.0.103", features = [
"derive",
], optional = true }
serde = { version = "1.0.103", features = ["derive"], optional = true }


[target.wasm32-unknown-unknown.dev-dependencies]
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/deserialize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ mod tests {
for (idx, c) in hex.as_bytes().iter().enumerate() {
b <<= 4;
match *c {
b'A'...b'F' => b |= c - b'A' + 10,
b'a'...b'f' => b |= c - b'a' + 10,
b'0'...b'9' => b |= c - b'0',
b'A'..=b'F' => b |= c - b'A' + 10,
b'a'..=b'f' => b |= c - b'a' + 10,
b'0'..=b'9' => b |= c - b'0',
_ => panic!("Bad hex"),
}
if (idx & 1) == 1 {
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/deserialize_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ mod tests {
for (idx, c) in hex.as_bytes().iter().enumerate() {
b <<= 4;
match *c {
b'A'...b'F' => b |= c - b'A' + 10,
b'a'...b'f' => b |= c - b'a' + 10,
b'0'...b'9' => b |= c - b'0',
b'A'..=b'F' => b |= c - b'A' + 10,
b'a'..=b'f' => b |= c - b'a' + 10,
b'0'..=b'9' => b |= c - b'0',
_ => panic!("Bad hex"),
}
if (idx & 1) == 1 {
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/deserialize_pset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ mod tests {
for (idx, c) in hex.as_bytes().iter().enumerate() {
b <<= 4;
match *c {
b'A'...b'F' => b |= c - b'A' + 10,
b'a'...b'f' => b |= c - b'a' + 10,
b'0'...b'9' => b |= c - b'0',
b'A'..=b'F' => b |= c - b'A' + 10,
b'a'..=b'f' => b |= c - b'a' + 10,
b'0'..=b'9' => b |= c - b'0',
_ => panic!("Bad hex"),
}
if (idx & 1) == 1 {
Expand Down
10 changes: 5 additions & 5 deletions fuzz/fuzz_targets/deserialize_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn do_test(data: &[u8]) {
let reser = elements::encode::serialize(&tx);
assert_eq!(data, &reser[..]);
let len = reser.len();
let calculated_weight = tx.get_weight();
let calculated_weight = tx.weight();
for input in &mut tx.input {
input.witness = elements::TxInWitness::default();
}
Expand All @@ -18,7 +18,7 @@ fn do_test(data: &[u8]) {
}
assert_eq!(tx.has_witness(), false);
let no_witness_len = elements::encode::serialize(&tx).len();
assert_eq!(no_witness_len * 3 + len, calculated_weight);
assert_eq!(no_witness_len * 3 + len, calculated_weight.to_wu() as usize);

for output in &tx.output {
output.is_null_data();
Expand Down Expand Up @@ -58,9 +58,9 @@ mod tests {
for (idx, c) in hex.as_bytes().iter().enumerate() {
b <<= 4;
match *c {
b'A'...b'F' => b |= c - b'A' + 10,
b'a'...b'f' => b |= c - b'a' + 10,
b'0'...b'9' => b |= c - b'0',
b'A'..=b'F' => b |= c - b'A' + 10,
b'a'..=b'f' => b |= c - b'a' + 10,
b'0'..=b'9' => b |= c - b'0',
_ => panic!("Bad hex"),
}
if (idx & 1) == 1 {
Expand Down
6 changes: 1 addition & 5 deletions src/blind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,7 @@ impl RangeProofMessage {
}

/// Information about Transaction Input Asset
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "actual_serde")
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct TxOutSecrets {
/// Asset
Expand Down
33 changes: 12 additions & 21 deletions src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use crate::dynafed;
use crate::hashes::{Hash, sha256};
use crate::Transaction;
use crate::encode::{self, serialize, Decodable, Encodable, VarInt};
use crate::{BlockHash, Script, TxMerkleNode};
use crate::{BlockHash, Script, TxMerkleNode, Weight};
use crate::Len64 as _;

/// Data related to block signatures
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -365,29 +366,19 @@ impl Block {
}

/// Get the size of the block
#[deprecated(since = "0.19.1", note = "Please use `Block::size` instead.")]
pub fn get_size(&self) -> usize {
self.size()
}

/// Get the size of the block
#[deprecated(since = "0.26.0", note = "use Self::weight or Self::encoded_length instead")]
pub fn size(&self) -> usize {
// The size of the header + the size of the varint with the tx count + the txs themselves
let base_size = serialize(&self.header).len() + VarInt(self.txdata.len() as u64).size();
let txs_size: usize = self.txdata.iter().map(Transaction::size).sum();
let base_size = serialize(&self.header).len() + VarInt(self.txdata.len64()).size();
let txs_size = self.txdata.iter().map(Transaction::encoded_length).sum::<usize>();
base_size + txs_size
}

/// Get the weight of the block
#[deprecated(since = "0.19.1", note = "Please use `Block::weight` instead.")]
pub fn get_weight(&self) -> usize {
self.weight()
}

/// Get the weight of the block
pub fn weight(&self) -> usize {
let base_weight = 4 * (serialize(&self.header).len() + VarInt(self.txdata.len() as u64).size());
let txs_weight: usize = self.txdata.iter().map(Transaction::weight).sum();
pub fn weight(&self) -> Weight {
let base_weight = Weight::from_vb(self.header.encoded_len64() + VarInt(self.txdata.len64()).len64())
.expect("base weight does not overflow the Weight type");
let txs_weight = self.txdata.iter().map(Transaction::weight).sum::<Weight>();
base_weight + txs_weight
}
}
Expand Down Expand Up @@ -466,8 +457,8 @@ mod tests {
assert_eq!(block.header.version, 0x2000_0000);
assert_eq!(block.header.height, 2);
assert_eq!(block.txdata.len(), 1);
assert_eq!(block.size(), serialize(&block).len());
assert_eq!(block.weight(), 1089);
assert_eq!(block.encoded_length(), serialize(&block).len());
assert_eq!(block.weight().to_wu(), 1089);

// Block with 3 transactions ... the rangeproofs are very large :)
let block: Block = hex_deserialize!(
Expand Down Expand Up @@ -678,7 +669,7 @@ mod tests {
assert_eq!(block.header.version, 0x2000_0000);
assert_eq!(block.header.height, 1);
assert_eq!(block.txdata.len(), 3);
assert_eq!(block.size(), serialize(&block).len());
assert_eq!(block.encoded_length(), serialize(&block).len());

// 2-of-3 signed block from Liquid integration tests
let block: Block = hex_deserialize!(
Expand Down
57 changes: 30 additions & 27 deletions src/confidential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,6 @@ impl Value {
Value::Confidential(comm)
}

/// Serialized length, in bytes
pub fn encoded_length(&self) -> usize {
match *self {
Value::Null => 1,
Value::Explicit(..) => 9,
Value::Confidential(..) => 33,
}
}

/// Create from commitment.
pub fn from_commitment(bytes: &[u8]) -> Result<Self, encode::Error> {
Ok(Value::Confidential(PedersenCommitment::from_slice(bytes)?))
Expand Down Expand Up @@ -145,13 +136,23 @@ impl Encodable for Value {
Value::Confidential(commitment) => commitment.consensus_encode(&mut s),
}
}

fn encoded_length(&self) -> usize {
match *self {
Self::Null => 1,
Self::Explicit(..) => 9,
Self::Confidential(..) => 33,
}
}
}

impl Encodable for PedersenCommitment {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
e.write_all(&self.serialize())?;
Ok(33)
}

fn encoded_length(&self) -> usize { 33 }
}

impl Decodable for Value {
Expand Down Expand Up @@ -272,15 +273,6 @@ impl Asset {
))
}

/// Serialized length, in bytes
pub fn encoded_length(&self) -> usize {
match *self {
Asset::Null => 1,
Asset::Explicit(..) => 33,
Asset::Confidential(..) => 33,
}
}

/// Create from commitment.
pub fn from_commitment(bytes: &[u8]) -> Result<Self, encode::Error> {
Ok(Asset::Confidential(Generator::from_slice(bytes)?))
Expand Down Expand Up @@ -367,13 +359,23 @@ impl Encodable for Asset {
Asset::Confidential(generator) => generator.consensus_encode(&mut s)
}
}

fn encoded_length(&self) -> usize {
match *self {
Self::Null => 1,
Self::Explicit(..) => 33,
Self::Confidential(..) => 33,
}
}
}

impl Encodable for Generator {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
e.write_all(&self.serialize())?;
Ok(33)
}

fn encoded_length(&self) -> usize { 33 }
}

impl Decodable for Asset {
Expand Down Expand Up @@ -537,15 +539,6 @@ impl Nonce {
SecretKey::from_slice(&shared_secret[..32]).expect("always has exactly 32 bytes")
}

/// Serialized length, in bytes
pub fn encoded_length(&self) -> usize {
match *self {
Nonce::Null => 1,
Nonce::Explicit(..) => 33,
Nonce::Confidential(..) => 33,
}
}

/// Create from commitment.
pub fn from_commitment(bytes: &[u8]) -> Result<Self, encode::Error> {
Ok(Nonce::Confidential(
Expand Down Expand Up @@ -619,13 +612,23 @@ impl Encodable for Nonce {
Nonce::Confidential(commitment) => commitment.consensus_encode(&mut s),
}
}

fn encoded_length(&self) -> usize {
match *self {
Self::Null => 1,
Self::Explicit(..) => 33,
Self::Confidential(..) => 33,
}
}
}

impl Encodable for PublicKey {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
e.write_all(&self.serialize())?;
Ok(33)
}

fn encoded_length(&self) -> usize { 33 }
}

impl Decodable for Nonce {
Expand Down
21 changes: 19 additions & 2 deletions src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use secp256k1_zkp::{self, RangeProof, SurjectionProof, Tweak};
use crate::hashes::{sha256, Hash};
use crate::pset;
use crate::transaction::{Transaction, TxIn, TxOut};
use crate::Len64 as _;

pub use bitcoin::{self, consensus::encode::MAX_VEC_SIZE};

Expand Down Expand Up @@ -147,6 +148,22 @@ pub trait Encodable {
/// the underlying `Write` errors. Returns the number of bytes written on
/// success
fn consensus_encode<W: io::Write>(&self, e: W) -> Result<usize, Error>;

/// The length of the object, in bytes, when encoded.
#[inline]
fn encoded_length(&self) -> usize {
self.consensus_encode(io::sink()).expect("no errors on sink")
}

/// The length of the object, in bytes, when encoded.
///
/// Convenience function to minimize the amount of explicit casting that
/// users need to do. No object in Bitcoin or Elements will ever approach
/// [`u64::MAX`] in encoded size, regardless of the range of `usize`.
#[inline]
fn encoded_len64(&self) -> u64 {
self.encoded_length() as u64
}
}

/// Data which can be encoded in a consensus-consistent way
Expand Down Expand Up @@ -208,7 +225,7 @@ pub(crate) fn consensus_encode_with_size<S: crate::WriteExt>(
data: &[u8],
mut s: S,
) -> Result<usize, Error> {
let vi_len = VarInt(data.len() as u64).consensus_encode(&mut s)?;
let vi_len = VarInt(data.len64()).consensus_encode(&mut s)?;
s.emit_slice(data)?;
Ok(vi_len + data.len())
}
Expand Down Expand Up @@ -320,7 +337,7 @@ macro_rules! impl_vec {
#[inline]
fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, Error> {
let mut len = 0;
len += VarInt(self.len() as u64).consensus_encode(&mut s)?;
len += VarInt(self.len64()).consensus_encode(&mut s)?;
for c in self.iter() {
len += c.consensus_encode(&mut s)?;
}
Expand Down
Loading