Add Arbitrary dependency

Implement Arbitrary for a select subset of types.
This commit is contained in:
yancy 2024-08-20 11:07:07 -05:00
parent 5651d8ecc9
commit 3e034d5ede
10 changed files with 69 additions and 4 deletions

View File

@ -8,6 +8,12 @@ version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.7.4" version = "0.7.4"
@ -49,6 +55,7 @@ dependencies = [
name = "bitcoin" name = "bitcoin"
version = "0.32.0-rc1" version = "0.32.0-rc1"
dependencies = [ dependencies = [
"arbitrary",
"base58ck", "base58ck",
"base64", "base64",
"bech32", "bech32",
@ -115,6 +122,7 @@ dependencies = [
name = "bitcoin-units" name = "bitcoin-units"
version = "0.1.1" version = "0.1.1"
dependencies = [ dependencies = [
"arbitrary",
"bitcoin-internals", "bitcoin-internals",
"serde", "serde",
"serde_json", "serde_json",

View File

@ -8,6 +8,12 @@ version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.7.4" version = "0.7.4"
@ -48,6 +54,7 @@ dependencies = [
name = "bitcoin" name = "bitcoin"
version = "0.32.0-rc1" version = "0.32.0-rc1"
dependencies = [ dependencies = [
"arbitrary",
"base58ck", "base58ck",
"base64", "base64",
"bech32", "bech32",
@ -114,6 +121,7 @@ dependencies = [
name = "bitcoin-units" name = "bitcoin-units"
version = "0.1.1" version = "0.1.1"
dependencies = [ dependencies = [
"arbitrary",
"bitcoin-internals", "bitcoin-internals",
"serde", "serde",
"serde_json", "serde_json",

View File

@ -22,6 +22,7 @@ rand = ["secp256k1/rand"]
serde = ["dep:serde", "hashes/serde", "internals/serde", "primitives/serde", "secp256k1/serde", "units/serde"] serde = ["dep:serde", "hashes/serde", "internals/serde", "primitives/serde", "secp256k1/serde", "units/serde"]
secp-lowmemory = ["secp256k1/lowmemory"] secp-lowmemory = ["secp256k1/lowmemory"]
secp-recovery = ["secp256k1/recovery"] secp-recovery = ["secp256k1/recovery"]
arbitrary = ["dep:arbitrary", "units/arbitrary"]
[dependencies] [dependencies]
base58 = { package = "base58ck", version = "0.1.0", default-features = false, features = ["alloc"] } base58 = { package = "base58ck", version = "0.1.0", default-features = false, features = ["alloc"] }
@ -40,6 +41,7 @@ ordered = { version = "0.2.0", optional = true }
bitcoinconsensus = { version = "0.106.0", default-features = false, optional = true } bitcoinconsensus = { version = "0.106.0", default-features = false, optional = true }
serde = { version = "1.0.103", default-features = false, features = [ "derive", "alloc" ], optional = true } serde = { version = "1.0.103", default-features = false, features = [ "derive", "alloc" ], optional = true }
arbitrary = { version = "1", optional = true }
[dev-dependencies] [dev-dependencies]
internals = { package = "bitcoin-internals", version = "0.3.0", features = ["test-serde"] } internals = { package = "bitcoin-internals", version = "0.3.0", features = ["test-serde"] }

View File

@ -5,10 +5,10 @@
# shellcheck disable=SC2034 # shellcheck disable=SC2034
# Test all these features with "std" enabled. # Test all these features with "std" enabled.
FEATURES_WITH_STD="rand-std serde secp-recovery bitcoinconsensus base64 ordered" FEATURES_WITH_STD="rand-std serde secp-recovery bitcoinconsensus base64 ordered arbitrary"
# Test all these features without "std" or "alloc" enabled. # Test all these features without "std" or "alloc" enabled.
FEATURES_WITHOUT_STD="rand serde secp-recovery bitcoinconsensus base64 ordered" FEATURES_WITHOUT_STD="rand serde secp-recovery bitcoinconsensus base64 ordered arbitrary"
# Run these examples. # Run these examples.
EXAMPLES="ecdsa-psbt:std,bitcoinconsensus sign-tx-segwit-v0:rand-std sign-tx-taproot:rand-std taproot-psbt:bitcoinconsensus,rand-std sighash:std" EXAMPLES="ecdsa-psbt:std,bitcoinconsensus sign-tx-segwit-v0:rand-std sign-tx-taproot:rand-std taproot-psbt:bitcoinconsensus,rand-std sighash:std"

View File

@ -11,6 +11,9 @@ use crate::opcodes::all::*;
use crate::opcodes::{self, Opcode}; use crate::opcodes::{self, Opcode};
use crate::prelude::{Box, Vec}; use crate::prelude::{Box, Vec};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
/// An owned, growable script. /// An owned, growable script.
/// ///
/// `ScriptBuf` is the most common script type that has the ownership over the contents of the /// `ScriptBuf` is the most common script type that has the ownership over the contents of the
@ -155,6 +158,14 @@ crate::internal_macros::define_extension_trait! {
} }
} }
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for ScriptBuf {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let v = Vec::<u8>::arbitrary(u)?;
Ok(ScriptBuf(v))
}
}
crate::internal_macros::define_extension_trait! { crate::internal_macros::define_extension_trait! {
pub(crate) trait ScriptBufExtPriv impl for ScriptBuf { pub(crate) trait ScriptBufExtPriv impl for ScriptBuf {
/// Pretends to convert `&mut ScriptBuf` to `&mut Vec<u8>` so that it can be modified. /// Pretends to convert `&mut ScriptBuf` to `&mut Vec<u8>` so that it can be modified.

View File

@ -29,6 +29,9 @@ use crate::sighash::{EcdsaSighashType, TapSighashType};
use crate::witness::Witness; use crate::witness::Witness;
use crate::{Amount, FeeRate, SignedAmount, VarInt}; use crate::{Amount, FeeRate, SignedAmount, VarInt};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
hashes::hash_newtype! { hashes::hash_newtype! {
/// A bitcoin transaction hash/transaction ID. /// A bitcoin transaction hash/transaction ID.
/// ///
@ -399,6 +402,16 @@ impl TxOut {
} }
} }
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for TxOut {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
Ok(TxOut {
value: Amount::arbitrary(u)?,
script_pubkey: ScriptBuf::arbitrary(u)?,
})
}
}
/// Returns the total number of bytes that this script pubkey would contribute to a transaction. /// Returns the total number of bytes that this script pubkey would contribute to a transaction.
fn size_from_script_pubkey(script_pubkey: &Script) -> usize { fn size_from_script_pubkey(script_pubkey: &Script) -> usize {
let len = script_pubkey.len(); let len = script_pubkey.len();

View File

@ -21,6 +21,7 @@ alloc = ["internals/alloc"]
internals = { package = "bitcoin-internals", version = "0.3.0" } internals = { package = "bitcoin-internals", version = "0.3.0" }
serde = { version = "1.0.103", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0.103", default-features = false, features = ["derive"], optional = true }
arbitrary = { version = "1", optional =true }
[dev-dependencies] [dev-dependencies]
internals = { package = "bitcoin-internals", version = "0.3.0", features = ["test-serde"] } internals = { package = "bitcoin-internals", version = "0.3.0", features = ["test-serde"] }

View File

@ -5,10 +5,10 @@
# shellcheck disable=SC2034 # shellcheck disable=SC2034
# Test all these features with "std" enabled. # Test all these features with "std" enabled.
FEATURES_WITH_STD="serde" FEATURES_WITH_STD="serde arbitrary"
# Test all these features without "std" enabled. # Test all these features without "std" enabled.
FEATURES_WITHOUT_STD="alloc serde" FEATURES_WITHOUT_STD="alloc serde arbitrary"
# Run these examples. # Run these examples.
EXAMPLES="" EXAMPLES=""

View File

@ -16,6 +16,9 @@ use ::serde::{Deserialize, Serialize};
use internals::error::InputString; use internals::error::InputString;
use internals::write_err; use internals::write_err;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
/// A set of denominations in which amounts can be expressed. /// A set of denominations in which amounts can be expressed.
/// ///
/// # Accepted Denominations /// # Accepted Denominations
@ -1071,6 +1074,14 @@ impl Amount {
} }
} }
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Amount {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let a = u64::arbitrary(u)?;
Ok(Amount(a))
}
}
impl default::Default for Amount { impl default::Default for Amount {
fn default() -> Self { Amount::ZERO } fn default() -> Self { Amount::ZERO }
} }

View File

@ -11,6 +11,9 @@ use serde::{Deserialize, Serialize};
use crate::amount::Amount; use crate::amount::Amount;
use crate::weight::Weight; use crate::weight::Weight;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
/// Represents fee rate. /// Represents fee rate.
/// ///
/// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection against mixing /// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection against mixing
@ -107,6 +110,14 @@ impl FeeRate {
} }
} }
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for FeeRate {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let f = u64::arbitrary(u)?;
Ok(FeeRate(f))
}
}
/// Alternative will display the unit. /// Alternative will display the unit.
impl fmt::Display for FeeRate { impl fmt::Display for FeeRate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {