diff --git a/bitcoin/tests/data/serde/README.md b/bitcoin/tests/data/serde/README.md new file mode 100644 index 00000000..a12793ba --- /dev/null +++ b/bitcoin/tests/data/serde/README.md @@ -0,0 +1,12 @@ +Serialization input/output +========================== + +Files here contain hex strings and binary data representing types used for +regression testing. + +- *_hex: consensus encoded types represented as hex strings +- *_ser: consensus encoded types represented as binary data +- *_bincode: types serialized with serde as bincode + +We consensus deserialize, serde serialize, then check against the expected data +to verify no serde regressions have been introduced. diff --git a/bitcoin/tests/data/serde/absolute_lock_time_blocks_bincode b/bitcoin/tests/data/serde/absolute_lock_time_blocks_bincode new file mode 100644 index 00000000..5e969601 Binary files /dev/null and b/bitcoin/tests/data/serde/absolute_lock_time_blocks_bincode differ diff --git a/bitcoin/tests/data/serde/absolute_lock_time_seconds_bincode b/bitcoin/tests/data/serde/absolute_lock_time_seconds_bincode new file mode 100644 index 00000000..dc0370f5 Binary files /dev/null and b/bitcoin/tests/data/serde/absolute_lock_time_seconds_bincode differ diff --git a/bitcoin/tests/data/serde/address_bincode b/bitcoin/tests/data/serde/address_bincode new file mode 100644 index 00000000..5a1c100d Binary files /dev/null and b/bitcoin/tests/data/serde/address_bincode differ diff --git a/bitcoin/tests/data/serde/block_bincode b/bitcoin/tests/data/serde/block_bincode new file mode 100644 index 00000000..0bd56c8d Binary files /dev/null and b/bitcoin/tests/data/serde/block_bincode differ diff --git a/bitcoin/tests/data/serde/child_number_bincode b/bitcoin/tests/data/serde/child_number_bincode new file mode 100644 index 00000000..c9902e4a --- /dev/null +++ b/bitcoin/tests/data/serde/child_number_bincode @@ -0,0 +1 @@ +ï¾­Þ \ No newline at end of file diff --git a/bitcoin/tests/data/serde/control_block_bincode b/bitcoin/tests/data/serde/control_block_bincode new file mode 100644 index 00000000..02f9b8ca Binary files /dev/null and b/bitcoin/tests/data/serde/control_block_bincode differ diff --git a/bitcoin/tests/data/serde/control_block_hex b/bitcoin/tests/data/serde/control_block_hex new file mode 100644 index 00000000..b1ddcda5 --- /dev/null +++ b/bitcoin/tests/data/serde/control_block_hex @@ -0,0 +1 @@ +c1a9d6f66cd4b25004f526bfa873e56942f98e8e492bd79ed6532b966104817c2bda584e7d32612381cf88edc1c02e28a296e807c16ad22f591ee113946e48a71e0641e660d1e5392fb79d64838c2b84faf04b7f5f283c9d8bf83e39e177b64372a0cd22eeab7e093873e851e247714eff762d8a30be699ba4456cfe6491b282e193a071350ae099005a5950d74f73ba13077a57bc478007fb0e4d1099ce9cf3d4 diff --git a/bitcoin/tests/data/serde/ecdsa_sig_bincode b/bitcoin/tests/data/serde/ecdsa_sig_bincode new file mode 100644 index 00000000..3136dc70 Binary files /dev/null and b/bitcoin/tests/data/serde/ecdsa_sig_bincode differ diff --git a/bitcoin/tests/data/serde/ecdsa_sig_hex b/bitcoin/tests/data/serde/ecdsa_sig_hex new file mode 100644 index 00000000..a435e3df --- /dev/null +++ b/bitcoin/tests/data/serde/ecdsa_sig_hex @@ -0,0 +1 @@ +3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45 diff --git a/bitcoin/tests/data/serde/extended_priv_key b/bitcoin/tests/data/serde/extended_priv_key new file mode 100644 index 00000000..7e84345f --- /dev/null +++ b/bitcoin/tests/data/serde/extended_priv_key @@ -0,0 +1 @@ +xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi diff --git a/bitcoin/tests/data/serde/extended_priv_key_bincode b/bitcoin/tests/data/serde/extended_priv_key_bincode new file mode 100644 index 00000000..a4331025 Binary files /dev/null and b/bitcoin/tests/data/serde/extended_priv_key_bincode differ diff --git a/bitcoin/tests/data/serde/extended_pub_key b/bitcoin/tests/data/serde/extended_pub_key new file mode 100644 index 00000000..da226876 --- /dev/null +++ b/bitcoin/tests/data/serde/extended_pub_key @@ -0,0 +1 @@ +xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8 diff --git a/bitcoin/tests/data/serde/extended_pub_key_bincode b/bitcoin/tests/data/serde/extended_pub_key_bincode new file mode 100644 index 00000000..096623fd Binary files /dev/null and b/bitcoin/tests/data/serde/extended_pub_key_bincode differ diff --git a/bitcoin/tests/data/serde/private_key_bincode b/bitcoin/tests/data/serde/private_key_bincode new file mode 100644 index 00000000..827f5d7f Binary files /dev/null and b/bitcoin/tests/data/serde/private_key_bincode differ diff --git a/bitcoin/tests/data/serde/proprietary_key_bincode b/bitcoin/tests/data/serde/proprietary_key_bincode new file mode 100644 index 00000000..24310775 Binary files /dev/null and b/bitcoin/tests/data/serde/proprietary_key_bincode differ diff --git a/bitcoin/tests/data/serde/psbt_bincode b/bitcoin/tests/data/serde/psbt_bincode new file mode 100644 index 00000000..e7293c1a Binary files /dev/null and b/bitcoin/tests/data/serde/psbt_bincode differ diff --git a/bitcoin/tests/data/serde/public_key_bincode b/bitcoin/tests/data/serde/public_key_bincode new file mode 100644 index 00000000..472a282c Binary files /dev/null and b/bitcoin/tests/data/serde/public_key_bincode differ diff --git a/bitcoin/tests/data/serde/public_key_hex b/bitcoin/tests/data/serde/public_key_hex new file mode 100644 index 00000000..4c6541bc --- /dev/null +++ b/bitcoin/tests/data/serde/public_key_hex @@ -0,0 +1 @@ +042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133 diff --git a/bitcoin/tests/data/serde/raw_pair_bincode b/bitcoin/tests/data/serde/raw_pair_bincode new file mode 100644 index 00000000..415afa7d Binary files /dev/null and b/bitcoin/tests/data/serde/raw_pair_bincode differ diff --git a/bitcoin/tests/data/serde/relative_lock_time_blocks_bincode b/bitcoin/tests/data/serde/relative_lock_time_blocks_bincode new file mode 100644 index 00000000..4eb84bb4 Binary files /dev/null and b/bitcoin/tests/data/serde/relative_lock_time_blocks_bincode differ diff --git a/bitcoin/tests/data/serde/relative_lock_time_seconds_bincode b/bitcoin/tests/data/serde/relative_lock_time_seconds_bincode new file mode 100644 index 00000000..b6ed9a62 Binary files /dev/null and b/bitcoin/tests/data/serde/relative_lock_time_seconds_bincode differ diff --git a/bitcoin/tests/data/serde/schnorr_sig_bincode b/bitcoin/tests/data/serde/schnorr_sig_bincode new file mode 100644 index 00000000..01f28cee Binary files /dev/null and b/bitcoin/tests/data/serde/schnorr_sig_bincode differ diff --git a/bitcoin/tests/data/serde/schnorr_sig_hex b/bitcoin/tests/data/serde/schnorr_sig_hex new file mode 100644 index 00000000..9ab24dd5 --- /dev/null +++ b/bitcoin/tests/data/serde/schnorr_sig_hex @@ -0,0 +1 @@ +6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8 diff --git a/bitcoin/tests/data/serde/script_bincode b/bitcoin/tests/data/serde/script_bincode new file mode 100644 index 00000000..5bf932f6 Binary files /dev/null and b/bitcoin/tests/data/serde/script_bincode differ diff --git a/bitcoin/tests/data/serde/taproot_builder_bincode b/bitcoin/tests/data/serde/taproot_builder_bincode new file mode 100644 index 00000000..91f3aff7 Binary files /dev/null and b/bitcoin/tests/data/serde/taproot_builder_bincode differ diff --git a/bitcoin/tests/data/serde/taproot_spend_info_bincode b/bitcoin/tests/data/serde/taproot_spend_info_bincode new file mode 100644 index 00000000..4ef6c982 Binary files /dev/null and b/bitcoin/tests/data/serde/taproot_spend_info_bincode differ diff --git a/bitcoin/tests/data/serde/transaction_bincode b/bitcoin/tests/data/serde/transaction_bincode new file mode 100644 index 00000000..82ffd66a Binary files /dev/null and b/bitcoin/tests/data/serde/transaction_bincode differ diff --git a/bitcoin/tests/data/serde/transaction_ser b/bitcoin/tests/data/serde/transaction_ser new file mode 100644 index 00000000..b3112cd1 Binary files /dev/null and b/bitcoin/tests/data/serde/transaction_ser differ diff --git a/bitcoin/tests/data/serde/txin_bincode b/bitcoin/tests/data/serde/txin_bincode new file mode 100644 index 00000000..92a61a1a Binary files /dev/null and b/bitcoin/tests/data/serde/txin_bincode differ diff --git a/bitcoin/tests/data/serde/txin_ser b/bitcoin/tests/data/serde/txin_ser new file mode 100644 index 00000000..f2c5f3a6 Binary files /dev/null and b/bitcoin/tests/data/serde/txin_ser differ diff --git a/bitcoin/tests/data/serde/txout_bincode b/bitcoin/tests/data/serde/txout_bincode new file mode 100644 index 00000000..2c3d2077 Binary files /dev/null and b/bitcoin/tests/data/serde/txout_bincode differ diff --git a/bitcoin/tests/data/serde/u256_bincode b/bitcoin/tests/data/serde/u256_bincode new file mode 100644 index 00000000..e91e8a92 Binary files /dev/null and b/bitcoin/tests/data/serde/u256_bincode differ diff --git a/bitcoin/tests/data/serde/uint128_bincode b/bitcoin/tests/data/serde/uint128_bincode new file mode 100644 index 00000000..24087dd3 Binary files /dev/null and b/bitcoin/tests/data/serde/uint128_bincode differ diff --git a/bitcoin/tests/data/serde/uint256_bincode b/bitcoin/tests/data/serde/uint256_bincode new file mode 100644 index 00000000..6fe1e032 Binary files /dev/null and b/bitcoin/tests/data/serde/uint256_bincode differ diff --git a/bitcoin/tests/data/serde/witness_bincode b/bitcoin/tests/data/serde/witness_bincode new file mode 100644 index 00000000..e7d43be0 Binary files /dev/null and b/bitcoin/tests/data/serde/witness_bincode differ diff --git a/bitcoin/tests/serde.rs b/bitcoin/tests/serde.rs new file mode 100644 index 00000000..b7402626 --- /dev/null +++ b/bitcoin/tests/serde.rs @@ -0,0 +1,418 @@ +//! Regression tests for _most_ types that implement `serde::Serialize`. +//! +//! For remaining types see: ./serde_opcodes.rs +//! +//! If you find a type defined in `rust-bitcoin` that implements `Serialize` and does _not_ have a +//! regression test please add it. +//! +//! Types/tests were found using, and are ordered by, the output of: `git grep -l Serialize`. +//! + +// In tests below `deserialize` is consensus deserialize while `serialize` is serde serialize, that +// is why we have two different serialized data files for tests that use binary serialized input. +// +// To create a file with the expected serialized data do something like: +// +// use std::fs::File; +// use std::io::Write; +// let script = Script::from(vec![0u8, 1u8, 2u8]); +// let got = serialize(&script).unwrap(); +// let mut file = File::create("/tmp/script_bincode").unwrap(); +// file.write_all(&got).unwrap(); + +#![cfg(feature = "serde")] + +use std::collections::BTreeMap; +use std::str::FromStr; + +use bincode::serialize; +use bitcoin::blockdata::locktime::{absolute, relative}; +use bitcoin::blockdata::witness::Witness; +use bitcoin::consensus::encode::deserialize; +use bitcoin::hashes::hex::FromHex; +use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; +use bitcoin::sighash::{EcdsaSighashType, SchnorrSighashType}; +use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource}; +use bitcoin::util::psbt::raw::{self, Key, Pair, ProprietaryKey}; +use bitcoin::util::psbt::{Input, Output, Psbt, PsbtSighashType}; +use bitcoin::util::schnorr::UntweakedPublicKey; +use bitcoin::util::taproot::{ControlBlock, LeafVersion, TaprootBuilder, TaprootSpendInfo}; +use bitcoin::{ + Address, Block, EcdsaSig, Network, OutPoint, PrivateKey, PublicKey, SchnorrSig, Script, + Sequence, Target, Transaction, TxIn, TxOut, Txid, Work, +}; +use secp256k1::Secp256k1; + +/// Implicitly does regression test for `BlockHeader` also. +#[test] +fn serde_regression_block() { + let segwit = include_bytes!( + "data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw" + ); + let block: Block = deserialize(segwit).unwrap(); + let got = serialize(&block).unwrap(); + // The cast is required because Rust 1.41.1 throws the following error without it: + // the trait `std::array::LengthAtMost32` is not implemented for `[u8; 5123]` + let want = include_bytes!("data/serde/block_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_absolute_lock_time_height() { + let t = absolute::LockTime::from_height(741521).expect("valid height"); + let got = serialize(&t).unwrap(); + let want = include_bytes!("data/serde/absolute_lock_time_blocks_bincode") as &[_]; + assert_eq!(got, want); +} + +#[test] +fn serde_regression_absolute_lock_time_time() { + let seconds: u32 = 1653195600; // May 22nd, 5am UTC. + let t = absolute::LockTime::from_time(seconds).expect("valid time"); + let got = serialize(&t).unwrap(); + + let want = include_bytes!("data/serde/absolute_lock_time_seconds_bincode") as &[_]; + assert_eq!(got, want); +} + +#[test] +fn serde_regression_relative_lock_time_height() { + let t = relative::LockTime::from(relative::Height::from(0xCAFE_u16)); + let got = serialize(&t).unwrap(); + + let want = include_bytes!("data/serde/relative_lock_time_blocks_bincode") as &[_]; + assert_eq!(got, want); +} + +#[test] +fn serde_regression_relative_lock_time_time() { + let t = relative::LockTime::from(relative::Time::from_512_second_intervals(0xFACE_u16)); + let got = serialize(&t).unwrap(); + + let want = include_bytes!("data/serde/relative_lock_time_seconds_bincode") as &[_]; + assert_eq!(got, want); +} + +#[test] +fn serde_regression_script() { + let script = Script::from(vec![0u8, 1u8, 2u8]); + let got = serialize(&script).unwrap(); + let want = include_bytes!("data/serde/script_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_txin() { + let ser = include_bytes!("data/serde/txin_ser"); + let txin: TxIn = deserialize(ser).unwrap(); + + let got = serialize(&txin).unwrap(); + let want = include_bytes!("data/serde/txin_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_txout() { + let txout = + TxOut { value: 0xDEADBEEFCAFEBABE, script_pubkey: Script::from(vec![0u8, 1u8, 2u8]) }; + let got = serialize(&txout).unwrap(); + let want = include_bytes!("data/serde/txout_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_transaction() { + let ser = include_bytes!("data/serde/transaction_ser"); + let tx: Transaction = deserialize(ser).unwrap(); + let got = serialize(&tx).unwrap(); + let want = include_bytes!("data/serde/transaction_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_witness() { + let w0 = Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105") + .unwrap(); + let w1 = Vec::from_hex("000000").unwrap(); + let vec = vec![w0, w1]; + let witness = Witness::from_vec(vec); + + let got = serialize(&witness).unwrap(); + let want = include_bytes!("data/serde/witness_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_address() { + let s = include_str!("data/serde/public_key_hex"); + let pk = PublicKey::from_str(s.trim()).unwrap(); + let addr = Address::p2pkh(&pk, Network::Bitcoin); + + let got = serialize(&addr).unwrap(); + let want = include_bytes!("data/serde/address_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_extended_priv_key() { + let s = include_str!("data/serde/extended_priv_key"); + let key = ExtendedPrivKey::from_str(s.trim()).unwrap(); + let got = serialize(&key).unwrap(); + let want = include_bytes!("data/serde/extended_priv_key_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_extended_pub_key() { + let s = include_str!("data/serde/extended_pub_key"); + let key = ExtendedPubKey::from_str(s.trim()).unwrap(); + let got = serialize(&key).unwrap(); + let want = include_bytes!("data/serde/extended_pub_key_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_ecdsa_sig() { + let s = include_str!("data/serde/ecdsa_sig_hex"); + let sig = EcdsaSig { + sig: secp256k1::ecdsa::Signature::from_str(s.trim()).unwrap(), + hash_ty: EcdsaSighashType::All, + }; + + let got = serialize(&sig).unwrap(); + let want = include_bytes!("data/serde/ecdsa_sig_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_control_block() { + let s = include_str!("data/serde/control_block_hex"); + let block = ControlBlock::from_slice(&Vec::::from_hex(s.trim()).unwrap()).unwrap(); + let got = serialize(&block).unwrap(); + + let want = include_bytes!("data/serde/control_block_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_child_number() { + let num = ChildNumber::Normal { index: 0xDEADBEEF }; + let got = serialize(&num).unwrap(); + let want = include_bytes!("data/serde/child_number_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_private_key() { + let sk = PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); + let got = serialize(&sk).unwrap(); + let want = include_bytes!("data/serde/private_key_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_public_key() { + let s = include_str!("data/serde/public_key_hex"); + let pk = PublicKey::from_str(s.trim()).unwrap(); + let got = serialize(&pk).unwrap(); + let want = include_bytes!("data/serde/public_key_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_psbt() { + let tx = Transaction { + version: 1, + lock_time: absolute::PackedLockTime::ZERO, + input: vec![TxIn { + previous_output: OutPoint { + txid: Txid::from_hex( + "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389", + ) + .unwrap(), + vout: 1, + }, + script_sig: Script::from_str("160014be18d152a9b012039daf3da7de4f53349eecb985").unwrap(), + sequence: Sequence::from_consensus(4294967295), + witness: Witness::from_vec(vec![Vec::from_hex( + "03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105", + ) + .unwrap()]), + }], + output: vec![TxOut { + value: 190303501938, + script_pubkey: Script::from_str("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587") + .unwrap(), + }], + }; + let unknown: BTreeMap> = + vec![(raw::Key { type_value: 1, key: vec![0, 1] }, vec![3, 4, 5])].into_iter().collect(); + let key_source = ("deadbeef".parse().unwrap(), "m/0'/1".parse().unwrap()); + let keypaths: BTreeMap = vec![( + "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(), + key_source.clone(), + )] + .into_iter() + .collect(); + + let proprietary: BTreeMap> = vec![( + raw::ProprietaryKey { + prefix: "prefx".as_bytes().to_vec(), + subtype: 42, + key: "test_key".as_bytes().to_vec(), + }, + vec![5, 6, 7], + )] + .into_iter() + .collect(); + + let psbt = Psbt { + version: 0, + xpub: { + let s = include_str!("data/serde/extended_pub_key"); + let xpub = ExtendedPubKey::from_str(s.trim()).unwrap(); + vec![(xpub, key_source)].into_iter().collect() + }, + unsigned_tx: { + let mut unsigned = tx.clone(); + unsigned.input[0].script_sig = Script::new(); + unsigned.input[0].witness = Witness::default(); + unsigned + }, + proprietary: proprietary.clone(), + unknown: unknown.clone(), + + inputs: vec![Input { + non_witness_utxo: Some(tx), + witness_utxo: Some(TxOut { + value: 190303501938, + script_pubkey: Script::from_str("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(), + }), + sighash_type: Some(PsbtSighashType::from(EcdsaSighashType::from_str("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY").unwrap())), + redeem_script: Some(vec![0x51].into()), + witness_script: None, + partial_sigs: vec![( + "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(), + "304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe701".parse().unwrap(), + )].into_iter().collect(), + bip32_derivation: keypaths.clone().into_iter().collect(), + final_script_witness: Some(Witness::from_vec(vec![vec![1, 3], vec![5]])), + ripemd160_preimages: vec![(ripemd160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), + sha256_preimages: vec![(sha256::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), + hash160_preimages: vec![(hash160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), + hash256_preimages: vec![(sha256d::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), + proprietary: proprietary.clone(), + unknown: unknown.clone(), + ..Default::default() + }], + outputs: vec![Output { + bip32_derivation: keypaths.into_iter().collect(), + proprietary, + unknown, + ..Default::default() + }], + }; + + let got = serialize(&psbt).unwrap(); + let want = include_bytes!("data/serde/psbt_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_raw_pair() { + let pair = Pair { + key: Key { type_value: 1u8, key: vec![0u8, 1u8, 2u8, 3u8] }, + value: vec![0u8, 1u8, 2u8, 3u8], + }; + let got = serialize(&pair).unwrap(); + let want = include_bytes!("data/serde/raw_pair_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_proprietary_key() { + let key = ProprietaryKey { + prefix: vec![0u8, 1u8, 2u8, 3u8], + subtype: 1u8, + key: vec![0u8, 1u8, 2u8, 3u8], + }; + let got = serialize(&key).unwrap(); + let want = include_bytes!("data/serde/proprietary_key_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_schnorr_sig() { + let s = include_str!("data/serde/schnorr_sig_hex"); + let sig = SchnorrSig { + sig: secp256k1::schnorr::Signature::from_str(s.trim()).unwrap(), + hash_ty: SchnorrSighashType::All, + }; + + let got = serialize(&sig).unwrap(); + let want = include_bytes!("data/serde/schnorr_sig_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_taproot_builder() { + let ver = LeafVersion::from_consensus(0).unwrap(); + let script = Script::from(vec![0u8, 1u8, 2u8]); + let builder = TaprootBuilder::new().add_leaf_with_ver(1, script, ver).unwrap(); + + let got = serialize(&builder).unwrap(); + let want = include_bytes!("data/serde/taproot_builder_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_taproot_spend_info() { + let secp = Secp256k1::verification_only(); + let internal_key = UntweakedPublicKey::from_str( + "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51", + ) + .unwrap(); + + let script_weights = vec![ + (10, Script::from_hex("51").unwrap()), // semantics of script don't matter for this test + (20, Script::from_hex("52").unwrap()), + (20, Script::from_hex("53").unwrap()), + (30, Script::from_hex("54").unwrap()), + (19, Script::from_hex("55").unwrap()), + ]; + let tree_info = + TaprootSpendInfo::with_huffman_tree(&secp, internal_key, script_weights).unwrap(); + + let got = serialize(&tree_info).unwrap(); + let want = include_bytes!("data/serde/taproot_spend_info_bincode") as &[_]; + assert_eq!(got, want) +} + +// Used to get a 256 bit integer as a byte array. +fn le_bytes() -> [u8; 32] { + let x: u128 = 0xDEAD_BEEF_CAFE_BABE_DEAD_BEEF_CAFE_BABE; + let y: u128 = 0xCAFE_DEAD_BABE_BEEF_CAFE_DEAD_BABE_BEEF; + + let mut bytes = [0_u8; 32]; + + bytes[..16].copy_from_slice(&x.to_le_bytes()); + bytes[16..].copy_from_slice(&y.to_le_bytes()); + + bytes +} + +#[test] +fn serde_regression_work() { + let work = Work::from_le_bytes(le_bytes()); + let got = serialize(&work).unwrap(); + let want = include_bytes!("data/serde/u256_bincode") as &[_]; + assert_eq!(got, want) +} + +#[test] +fn serde_regression_target() { + let target = Target::from_le_bytes(le_bytes()); + let got = serialize(&target).unwrap(); + let want = include_bytes!("data/serde/u256_bincode") as &[_]; + assert_eq!(got, want) +} diff --git a/bitcoin/tests/serde_opcodes.rs b/bitcoin/tests/serde_opcodes.rs new file mode 100644 index 00000000..3d73a84c --- /dev/null +++ b/bitcoin/tests/serde_opcodes.rs @@ -0,0 +1,280 @@ +//! serde regression tests for blockdata::opcodes module. +//! + +#![cfg(feature = "serde")] + +extern crate bitcoin; +extern crate serde_json; + +macro_rules! test_opcodes { + ($($op:ident),* $(,)+) => { + $( + let op = bitcoin::blockdata::opcodes::all::$op; + let want = concat!("\"", stringify!($op), "\""); + let got = ::serde_json::to_string(&op).unwrap(); + assert_eq!(got, want); + )* + } +} + +#[test] +fn serde_regression_opcodes() { + test_opcodes! { + OP_PUSHBYTES_0, + OP_PUSHBYTES_1, + OP_PUSHBYTES_2, + OP_PUSHBYTES_3, + OP_PUSHBYTES_4, + OP_PUSHBYTES_5, + OP_PUSHBYTES_6, + OP_PUSHBYTES_7, + OP_PUSHBYTES_8, + OP_PUSHBYTES_9, + OP_PUSHBYTES_10, + OP_PUSHBYTES_11, + OP_PUSHBYTES_12, + OP_PUSHBYTES_13, + OP_PUSHBYTES_14, + OP_PUSHBYTES_15, + OP_PUSHBYTES_16, + OP_PUSHBYTES_17, + OP_PUSHBYTES_18, + OP_PUSHBYTES_19, + OP_PUSHBYTES_20, + OP_PUSHBYTES_21, + OP_PUSHBYTES_22, + OP_PUSHBYTES_23, + OP_PUSHBYTES_24, + OP_PUSHBYTES_25, + OP_PUSHBYTES_26, + OP_PUSHBYTES_27, + OP_PUSHBYTES_28, + OP_PUSHBYTES_29, + OP_PUSHBYTES_30, + OP_PUSHBYTES_31, + OP_PUSHBYTES_32, + OP_PUSHBYTES_33, + OP_PUSHBYTES_34, + OP_PUSHBYTES_35, + OP_PUSHBYTES_36, + OP_PUSHBYTES_37, + OP_PUSHBYTES_38, + OP_PUSHBYTES_39, + OP_PUSHBYTES_40, + OP_PUSHBYTES_41, + OP_PUSHBYTES_42, + OP_PUSHBYTES_43, + OP_PUSHBYTES_44, + OP_PUSHBYTES_45, + OP_PUSHBYTES_46, + OP_PUSHBYTES_47, + OP_PUSHBYTES_48, + OP_PUSHBYTES_49, + OP_PUSHBYTES_50, + OP_PUSHBYTES_51, + OP_PUSHBYTES_52, + OP_PUSHBYTES_53, + OP_PUSHBYTES_54, + OP_PUSHBYTES_55, + OP_PUSHBYTES_56, + OP_PUSHBYTES_57, + OP_PUSHBYTES_58, + OP_PUSHBYTES_59, + OP_PUSHBYTES_60, + OP_PUSHBYTES_61, + OP_PUSHBYTES_62, + OP_PUSHBYTES_63, + OP_PUSHBYTES_64, + OP_PUSHBYTES_65, + OP_PUSHBYTES_66, + OP_PUSHBYTES_67, + OP_PUSHBYTES_68, + OP_PUSHBYTES_69, + OP_PUSHBYTES_70, + OP_PUSHBYTES_71, + OP_PUSHBYTES_72, + OP_PUSHBYTES_73, + OP_PUSHBYTES_74, + OP_PUSHBYTES_75, + OP_PUSHDATA1, + OP_PUSHDATA2, + OP_PUSHDATA4, + OP_PUSHNUM_NEG1, + OP_RESERVED, + OP_PUSHNUM_1, + OP_PUSHNUM_2, + OP_PUSHNUM_3, + OP_PUSHNUM_4, + OP_PUSHNUM_5, + OP_PUSHNUM_6, + OP_PUSHNUM_7, + OP_PUSHNUM_8, + OP_PUSHNUM_9, + OP_PUSHNUM_10, + OP_PUSHNUM_11, + OP_PUSHNUM_12, + OP_PUSHNUM_13, + OP_PUSHNUM_14, + OP_PUSHNUM_15, + OP_PUSHNUM_16, + OP_NOP, + OP_VER, + OP_IF, + OP_NOTIF, + OP_VERIF, + OP_VERNOTIF, + OP_ELSE, + OP_ENDIF, + OP_VERIFY, + OP_RETURN, + OP_TOALTSTACK, + OP_FROMALTSTACK, + OP_2DROP, + OP_2DUP, + OP_3DUP, + OP_2OVER, + OP_2ROT, + OP_2SWAP, + OP_IFDUP, + OP_DEPTH, + OP_DROP, + OP_DUP, + OP_NIP, + OP_OVER, + OP_PICK, + OP_ROLL, + OP_ROT, + OP_SWAP, + OP_TUCK, + OP_CAT, + OP_SUBSTR, + OP_LEFT, + OP_RIGHT, + OP_SIZE, + OP_INVERT, + OP_AND, + OP_OR, + OP_XOR, + OP_EQUAL, + OP_EQUALVERIFY, + OP_RESERVED1, + OP_RESERVED2, + OP_1ADD, + OP_1SUB, + OP_2MUL, + OP_2DIV, + OP_NEGATE, + OP_ABS, + OP_NOT, + OP_0NOTEQUAL, + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_LSHIFT, + OP_RSHIFT, + OP_BOOLAND, + OP_BOOLOR, + OP_NUMEQUAL, + OP_NUMEQUALVERIFY, + OP_NUMNOTEQUAL, + OP_LESSTHAN , + OP_GREATERTHAN , + OP_LESSTHANOREQUAL , + OP_GREATERTHANOREQUAL , + OP_MIN, + OP_MAX, + OP_WITHIN, + OP_RIPEMD160, + OP_SHA1, + OP_SHA256, + OP_HASH160, + OP_HASH256, + OP_CODESEPARATOR, + OP_CHECKSIG, + OP_CHECKSIGVERIFY, + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + OP_NOP1, + OP_CLTV, + OP_CSV, + OP_NOP4, + OP_NOP5, + OP_NOP6, + OP_NOP7, + OP_NOP8, + OP_NOP9, + OP_NOP10, + OP_CHECKSIGADD, + OP_RETURN_187, + OP_RETURN_188, + OP_RETURN_189, + OP_RETURN_190, + OP_RETURN_191, + OP_RETURN_192, + OP_RETURN_193, + OP_RETURN_194, + OP_RETURN_195, + OP_RETURN_196, + OP_RETURN_197, + OP_RETURN_198, + OP_RETURN_199, + OP_RETURN_200, + OP_RETURN_201, + OP_RETURN_202, + OP_RETURN_203, + OP_RETURN_204, + OP_RETURN_205, + OP_RETURN_206, + OP_RETURN_207, + OP_RETURN_208, + OP_RETURN_209, + OP_RETURN_210, + OP_RETURN_211, + OP_RETURN_212, + OP_RETURN_213, + OP_RETURN_214, + OP_RETURN_215, + OP_RETURN_216, + OP_RETURN_217, + OP_RETURN_218, + OP_RETURN_219, + OP_RETURN_220, + OP_RETURN_221, + OP_RETURN_222, + OP_RETURN_223, + OP_RETURN_224, + OP_RETURN_225, + OP_RETURN_226, + OP_RETURN_227, + OP_RETURN_228, + OP_RETURN_229, + OP_RETURN_230, + OP_RETURN_231, + OP_RETURN_232, + OP_RETURN_233, + OP_RETURN_234, + OP_RETURN_235, + OP_RETURN_236, + OP_RETURN_237, + OP_RETURN_238, + OP_RETURN_239, + OP_RETURN_240, + OP_RETURN_241, + OP_RETURN_242, + OP_RETURN_243, + OP_RETURN_244, + OP_RETURN_245, + OP_RETURN_246, + OP_RETURN_247, + OP_RETURN_248, + OP_RETURN_249, + OP_RETURN_250, + OP_RETURN_251, + OP_RETURN_252, + OP_RETURN_253, + OP_RETURN_254, + OP_INVALIDOPCODE, + } +}