Implement Arbitrary for Transaction
This commit is contained in:
parent
fe2985baf7
commit
5b4e81b379
|
@ -110,6 +110,7 @@ dependencies = [
|
|||
name = "bitcoin-primitives"
|
||||
version = "0.100.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"bitcoin-internals",
|
||||
"bitcoin-io",
|
||||
"bitcoin-units",
|
||||
|
|
|
@ -109,6 +109,7 @@ dependencies = [
|
|||
name = "bitcoin-primitives"
|
||||
version = "0.100.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"bitcoin-internals",
|
||||
"bitcoin-io",
|
||||
"bitcoin-units",
|
||||
|
|
|
@ -22,7 +22,7 @@ rand = ["secp256k1/rand"]
|
|||
serde = ["dep:serde", "hashes/serde", "internals/serde", "primitives/serde", "secp256k1/serde", "units/serde"]
|
||||
secp-lowmemory = ["secp256k1/lowmemory"]
|
||||
secp-recovery = ["secp256k1/recovery"]
|
||||
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
||||
arbitrary = ["dep:arbitrary", "units/arbitrary", "primitives/arbitrary"]
|
||||
|
||||
[dependencies]
|
||||
base58 = { package = "base58ck", version = "0.1.0", default-features = false, features = ["alloc"] }
|
||||
|
|
|
@ -1409,6 +1409,42 @@ impl InputWeightPrediction {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for OutPoint {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
Ok(OutPoint{
|
||||
txid: Txid::arbitrary(u)?,
|
||||
vout: u32::arbitrary(u)?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for TxIn {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
Ok(TxIn{
|
||||
previous_output: OutPoint::arbitrary(u)?,
|
||||
script_sig: ScriptBuf::arbitrary(u)?,
|
||||
sequence: Sequence::arbitrary(u)?,
|
||||
witness: Witness::arbitrary(u)?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Transaction {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
use primitives::absolute::LockTime;
|
||||
|
||||
Ok(Transaction {
|
||||
version: Version::arbitrary(u)?,
|
||||
lock_time: LockTime::arbitrary(u)?,
|
||||
input: Vec::<TxIn>::arbitrary(u)?,
|
||||
output: Vec::<TxOut>::arbitrary(u)?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex::{test_hex_unwrap as hex, FromHex};
|
||||
|
|
|
@ -18,6 +18,8 @@ use crate::prelude::Vec;
|
|||
use crate::script::ScriptExt as _;
|
||||
use crate::taproot::{self, TAPROOT_ANNEX_PREFIX};
|
||||
use crate::{Script, VarInt};
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
|
||||
/// The Witness is the data used to unlock bitcoin since the [segwit upgrade].
|
||||
///
|
||||
|
@ -618,6 +620,14 @@ impl Default for Witness {
|
|||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Witness {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let arbitrary_bytes = Vec::<Vec::<u8>>::arbitrary(u)?;
|
||||
Ok(Witness::from_slice(&arbitrary_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hex::test_hex_unwrap as hex;
|
||||
|
|
|
@ -19,8 +19,10 @@ default = ["std"]
|
|||
std = ["alloc", "hashes/std", "internals/std", "io/std", "units/std"]
|
||||
alloc = ["hashes/alloc", "internals/alloc", "io/alloc", "units/alloc"]
|
||||
serde = ["dep:serde", "hashes/serde", "internals/serde", "units/serde", "alloc"]
|
||||
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
||||
|
||||
[dependencies]
|
||||
arbitrary = { version = "1", optional = true }
|
||||
hashes = { package = "bitcoin_hashes", version = "0.14.0", default-features = false, features = ["bitcoin-io"] }
|
||||
internals = { package = "bitcoin-internals", version = "0.3.0" }
|
||||
io = { package = "bitcoin-io", version = "0.1.1", default-features = false }
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
# shellcheck disable=SC2034
|
||||
|
||||
# Test these features with "std" enabled.
|
||||
FEATURES_WITH_STD="ordered serde"
|
||||
FEATURES_WITH_STD="ordered serde arbitrary"
|
||||
|
||||
# Test these features without "std" enabled.
|
||||
FEATURES_WITHOUT_STD="alloc ordered serde"
|
||||
FEATURES_WITHOUT_STD="alloc ordered serde arbitrary"
|
||||
|
||||
# Run these examples.
|
||||
EXAMPLES=""
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
#[cfg(all(test, mutate))]
|
||||
use mutagen::mutate;
|
||||
use units::parse::{self, PrefixedHexError, UnprefixedHexError};
|
||||
|
@ -395,6 +397,14 @@ impl ordered::ArbitraryOrd for LockTime {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for LockTime {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let l = u32::arbitrary(u)?;
|
||||
Ok(LockTime::from_consensus(l))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -24,6 +24,8 @@ use serde::{Deserialize, Serialize};
|
|||
use units::locktime::relative::TimeOverflowError;
|
||||
#[cfg(feature = "alloc")]
|
||||
use units::parse::{self, PrefixedHexError, UnprefixedHexError};
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::locktime::relative;
|
||||
|
@ -238,3 +240,11 @@ impl fmt::Debug for Sequence {
|
|||
|
||||
#[cfg(feature = "alloc")]
|
||||
units::impl_parse_str_from_int_infallible!(Sequence, u32, from_consensus);
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Sequence {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let s = u32::arbitrary(u)?;
|
||||
Ok(Sequence(s))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
use core::fmt;
|
||||
|
||||
use hashes::sha256d;
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
|
||||
hashes::hash_newtype! {
|
||||
/// A bitcoin transaction hash/transaction ID.
|
||||
|
@ -70,3 +72,20 @@ impl Version {
|
|||
impl fmt::Display for Version {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Version {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let v = i32::arbitrary(u)?;
|
||||
Ok(Version(v))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Txid {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let arbitrary_bytes = u.arbitrary()?;
|
||||
let t = sha256d::Hash::from_byte_array(arbitrary_bytes);
|
||||
Ok(Txid(t))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue