Merge pull request #2006 from tcharding/08-18-tx-version

Add transaction::Version data type
This commit is contained in:
Clark Moody 2023-09-23 13:13:52 -05:00 committed by GitHub
commit 72a7280d7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 88 additions and 41 deletions

View File

@ -39,8 +39,8 @@ use bitcoin::locktime::absolute;
use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType}; use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
use bitcoin::secp256k1::{Secp256k1, Signing, Verification}; use bitcoin::secp256k1::{Secp256k1, Signing, Verification};
use bitcoin::{ use bitcoin::{
Address, Amount, Network, OutPoint, PublicKey, ScriptBuf, Sequence, Transaction, TxIn, TxOut, transaction, Address, Amount, Network, OutPoint, PublicKey, ScriptBuf, Sequence, Transaction,
Witness, TxIn, TxOut, Witness,
}; };
type Result<T> = std::result::Result<T, Error>; type Result<T> = std::result::Result<T, Error>;
@ -177,7 +177,7 @@ impl WatchOnly {
let change_amount = Amount::from_str(CHANGE_AMOUNT_BTC)?; let change_amount = Amount::from_str(CHANGE_AMOUNT_BTC)?;
let tx = Transaction { let tx = Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { txid: INPUT_UTXO_TXID.parse()?, vout: INPUT_UTXO_VOUT }, previous_output: OutPoint { txid: INPUT_UTXO_TXID.parse()?, vout: INPUT_UTXO_VOUT },

View File

@ -88,8 +88,8 @@ use bitcoin::secp256k1::Secp256k1;
use bitcoin::sighash::{self, SighashCache, TapSighash, TapSighashType}; use bitcoin::sighash::{self, SighashCache, TapSighash, TapSighashType};
use bitcoin::taproot::{self, LeafVersion, TapLeafHash, TaprootBuilder, TaprootSpendInfo}; use bitcoin::taproot::{self, LeafVersion, TapLeafHash, TaprootBuilder, TaprootSpendInfo};
use bitcoin::{ use bitcoin::{
absolute, script, Address, Amount, Network, OutPoint, ScriptBuf, Transaction, TxIn, TxOut, absolute, script, transaction, Address, Amount, Network, OutPoint, ScriptBuf, Transaction,
Witness, TxIn, TxOut, Witness,
}; };
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -229,7 +229,7 @@ fn generate_bip86_key_spend_tx(
// CREATOR + UPDATER // CREATOR + UPDATER
let tx1 = Transaction { let tx1 = Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { txid: input_utxo.txid.parse()?, vout: input_utxo.vout }, previous_output: OutPoint { txid: input_utxo.txid.parse()?, vout: input_utxo.vout },
@ -414,7 +414,7 @@ impl BenefactorWallet {
// CREATOR + UPDATER // CREATOR + UPDATER
let next_tx = Transaction { let next_tx = Transaction {
version: 2, version: transaction::Version::TWO,
lock_time, lock_time,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { txid: tx.txid(), vout: 0 }, previous_output: OutPoint { txid: tx.txid(), vout: 0 },
@ -560,7 +560,7 @@ impl BenefactorWallet {
.expect("failed to verify transaction"); .expect("failed to verify transaction");
let next_tx = Transaction { let next_tx = Transaction {
version: 2, version: transaction::Version::TWO,
lock_time, lock_time,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { txid: tx.txid(), vout: 0 }, previous_output: OutPoint { txid: tx.txid(), vout: 0 },

View File

@ -371,6 +371,7 @@ mod test {
use super::*; use super::*;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::transaction;
use crate::consensus::encode::{deserialize, serialize}; use crate::consensus::encode::{deserialize, serialize};
use crate::hash_types::TxMerkleNode; use crate::hash_types::TxMerkleNode;
use crate::{ use crate::{
@ -380,7 +381,7 @@ mod test {
fn dummy_tx(nonce: &[u8]) -> Transaction { fn dummy_tx(nonce: &[u8]) -> Transaction {
Transaction { Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::from_consensus(2), lock_time: absolute::LockTime::from_consensus(2),
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint::new(Txid::hash(nonce), 0), previous_output: OutPoint::new(Txid::hash(nonce), 0),

View File

@ -17,7 +17,7 @@ use crate::blockdata::block::{self, Block};
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::script; use crate::blockdata::script;
use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::internal_macros::impl_bytes_newtype; use crate::internal_macros::impl_bytes_newtype;
use crate::network::Network; use crate::network::Network;
@ -64,7 +64,7 @@ pub const COINBASE_MATURITY: u32 = 100;
fn bitcoin_genesis_tx() -> Transaction { fn bitcoin_genesis_tx() -> Transaction {
// Base // Base
let mut ret = Transaction { let mut ret = Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![], input: vec![],
output: vec![], output: vec![],
@ -196,6 +196,7 @@ mod test {
use super::*; use super::*;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::transaction;
use crate::consensus::encode::serialize; use crate::consensus::encode::serialize;
use crate::internal_macros::hex; use crate::internal_macros::hex;
use crate::network::Network; use crate::network::Network;
@ -204,7 +205,7 @@ mod test {
fn bitcoin_genesis_first_transaction() { fn bitcoin_genesis_first_transaction() {
let gen = bitcoin_genesis_tx(); let gen = bitcoin_genesis_tx();
assert_eq!(gen.version, 1); assert_eq!(gen.version, transaction::Version::ONE);
assert_eq!(gen.input.len(), 1); assert_eq!(gen.input.len(), 1);
assert_eq!(gen.input[0].previous_output.txid, Hash::all_zeros()); assert_eq!(gen.input[0].previous_output.txid, Hash::all_zeros());
assert_eq!(gen.input[0].previous_output.vout, 0xFFFFFFFF); assert_eq!(gen.input[0].previous_output.vout, 0xFFFFFFFF);

View File

@ -96,9 +96,9 @@ impl FeeRate {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # use bitcoin::{absolute, FeeRate, Transaction}; /// # use bitcoin::{absolute, transaction, FeeRate, Transaction};
/// # // Dummy transaction. /// # // Dummy transaction.
/// # let tx = Transaction { version: 1, lock_time: absolute::LockTime::ZERO, input: vec![], output: vec![] }; /// # let tx = Transaction { version: transaction::Version::ONE, lock_time: absolute::LockTime::ZERO, input: vec![], output: vec![] };
/// ///
/// let rate = FeeRate::from_sat_per_vb(1).expect("1 sat/vbyte is valid"); /// let rate = FeeRate::from_sat_per_vb(1).expect("1 sat/vbyte is valid");
/// let fee = rate.fee_wu(tx.weight()); /// let fee = rate.fee_wu(tx.weight());

View File

@ -586,7 +586,7 @@ impl TxOut {
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
pub struct Transaction { pub struct Transaction {
/// The protocol version, is currently expected to be 1 or 2 (BIP 68). /// The protocol version, is currently expected to be 1 or 2 (BIP 68).
pub version: i32, pub version: Version,
/// Block height or timestamp. Transaction cannot be included in a block until this height/time. /// Block height or timestamp. Transaction cannot be included in a block until this height/time.
/// ///
/// ### Relevant BIPs /// ### Relevant BIPs
@ -952,6 +952,50 @@ impl Transaction {
} }
} }
/// The transaction version.
///
/// Currently, as specified by [BIP-68], only version 1 and 2 are considered standard.
///
/// Standardness of the inner `i32` is not an invariant because you are free to create transactions
/// of any version, transactions with non-standard version numbers will not be relayed by the
/// Bitcoin network.
///
/// [BIP-68]: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
pub struct Version(pub i32);
impl Version {
/// The original Bitcoin transaction version (pre-BIP-68).
pub const ONE: Self = Self(1);
/// The second Bitcoin transaction version (post-BIP-68).
pub const TWO: Self = Self(2);
/// Creates a non-standard transaction version.
pub fn non_standard(version: i32) -> Version { Self(version) }
/// Returns true if this transaction version number is considered standard.
pub fn is_standard(&self) -> bool { *self == Version::ONE || *self == Version::TWO }
}
impl Default for Version {
fn default() -> Version { Version::TWO }
}
impl Encodable for Version {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.0.consensus_encode(w)
}
}
impl Decodable for Version {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Decodable::consensus_decode(r).map(Version)
}
}
impl_consensus_encoding!(TxOut, value, script_pubkey); impl_consensus_encoding!(TxOut, value, script_pubkey);
impl Encodable for OutPoint { impl Encodable for OutPoint {
@ -1038,7 +1082,7 @@ impl Decodable for Transaction {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>( fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(
r: &mut R, r: &mut R,
) -> Result<Self, encode::Error> { ) -> Result<Self, encode::Error> {
let version = i32::consensus_decode_from_finite_reader(r)?; let version = Version::consensus_decode_from_finite_reader(r)?;
let input = Vec::<TxIn>::consensus_decode_from_finite_reader(r)?; let input = Vec::<TxIn>::consensus_decode_from_finite_reader(r)?;
// segwit // segwit
if input.is_empty() { if input.is_empty() {
@ -1491,7 +1535,7 @@ mod tests {
let realtx = tx.unwrap(); let realtx = tx.unwrap();
// All these tests aren't really needed because if they fail, the hash check at the end // All these tests aren't really needed because if they fail, the hash check at the end
// will also fail. But these will show you where the failure is so I'll leave them in. // will also fail. But these will show you where the failure is so I'll leave them in.
assert_eq!(realtx.version, 1); assert_eq!(realtx.version, Version::ONE);
assert_eq!(realtx.input.len(), 1); assert_eq!(realtx.input.len(), 1);
// In particular this one is easy to get backward -- in bitcoin hashes are encoded // In particular this one is easy to get backward -- in bitcoin hashes are encoded
// as little-endian 256-bit numbers rather than as data strings. // as little-endian 256-bit numbers rather than as data strings.
@ -1532,7 +1576,7 @@ mod tests {
let realtx = tx.unwrap(); let realtx = tx.unwrap();
// All these tests aren't really needed because if they fail, the hash check at the end // All these tests aren't really needed because if they fail, the hash check at the end
// will also fail. But these will show you where the failure is so I'll leave them in. // will also fail. But these will show you where the failure is so I'll leave them in.
assert_eq!(realtx.version, 2); assert_eq!(realtx.version, Version::TWO);
assert_eq!(realtx.input.len(), 1); assert_eq!(realtx.input.len(), 1);
// In particular this one is easy to get backward -- in bitcoin hashes are encoded // In particular this one is easy to get backward -- in bitcoin hashes are encoded
// as little-endian 256-bit numbers rather than as data strings. // as little-endian 256-bit numbers rather than as data strings.
@ -1604,13 +1648,13 @@ mod tests {
let tx: Result<Transaction, _> = deserialize(&tx_bytes); let tx: Result<Transaction, _> = deserialize(&tx_bytes);
assert!(tx.is_ok()); assert!(tx.is_ok());
let realtx = tx.unwrap(); let realtx = tx.unwrap();
assert_eq!(realtx.version, 2147483647); assert_eq!(realtx.version, Version::non_standard(2147483647));
let tx2_bytes = hex!("000000800100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"); let tx2_bytes = hex!("000000800100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000");
let tx2: Result<Transaction, _> = deserialize(&tx2_bytes); let tx2: Result<Transaction, _> = deserialize(&tx2_bytes);
assert!(tx2.is_ok()); assert!(tx2.is_ok());
let realtx2 = tx2.unwrap(); let realtx2 = tx2.unwrap();
assert_eq!(realtx2.version, -2147483648); assert_eq!(realtx2.version, Version::non_standard(-2147483648));
} }
#[test] #[test]
@ -1898,7 +1942,7 @@ mod tests {
]; ];
let empty_transaction_weight = Transaction { let empty_transaction_weight = Transaction {
version: 0, version: Version::default(),
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![], input: vec![],
output: vec![], output: vec![],

View File

@ -1136,10 +1136,10 @@ impl<R: BorrowMut<Transaction>> SighashCache<R> {
/// ///
/// This allows in-line signing such as /// This allows in-line signing such as
/// ``` /// ```
/// use bitcoin::{absolute, Amount, Transaction, Script}; /// use bitcoin::{absolute, transaction, Amount, Transaction, Script};
/// use bitcoin::sighash::{EcdsaSighashType, SighashCache}; /// use bitcoin::sighash::{EcdsaSighashType, SighashCache};
/// ///
/// let mut tx_to_sign = Transaction { version: 2, lock_time: absolute::LockTime::ZERO, input: Vec::new(), output: Vec::new() }; /// let mut tx_to_sign = Transaction { version: transaction::Version::TWO, lock_time: absolute::LockTime::ZERO, input: Vec::new(), output: Vec::new() };
/// let input_count = tx_to_sign.input.len(); /// let input_count = tx_to_sign.input.len();
/// ///
/// let mut sig_hasher = SighashCache::new(&mut tx_to_sign); /// let mut sig_hasher = SighashCache::new(&mut tx_to_sign);
@ -1262,6 +1262,7 @@ mod tests {
use super::*; use super::*;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::transaction;
use crate::consensus::deserialize; use crate::consensus::deserialize;
use crate::crypto::sighash::{LegacySighash, TapSighash}; use crate::crypto::sighash::{LegacySighash, TapSighash};
use crate::internal_macros::hex; use crate::internal_macros::hex;
@ -1275,7 +1276,7 @@ mod tests {
// We need a tx with more inputs than outputs. // We need a tx with more inputs than outputs.
let tx = Transaction { let tx = Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default(), TxIn::default()], input: vec![TxIn::default(), TxIn::default()],
output: vec![TxOut::NULL], output: vec![TxOut::NULL],
@ -1462,7 +1463,7 @@ mod tests {
#[rustfmt::skip] // Allow long function call `taproot_signature_hash`. #[rustfmt::skip] // Allow long function call `taproot_signature_hash`.
fn test_sighash_errors() { fn test_sighash_errors() {
let dumb_tx = Transaction { let dumb_tx = Transaction {
version: 0, version: transaction::Version::default(),
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default()], input: vec![TxIn::default()],
output: vec![], output: vec![],

View File

@ -887,7 +887,7 @@ mod tests {
use crate::bip32::{ChildNumber, KeySource, Xpriv, Xpub}; use crate::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::script::ScriptBuf; use crate::blockdata::script::ScriptBuf;
use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::internal_macros::hex; use crate::internal_macros::hex;
use crate::network::Network::Bitcoin; use crate::network::Network::Bitcoin;
@ -899,7 +899,7 @@ mod tests {
fn trivial_psbt() { fn trivial_psbt() {
let psbt = Psbt { let psbt = Psbt {
unsigned_tx: Transaction { unsigned_tx: Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![], input: vec![],
output: vec![], output: vec![],
@ -972,7 +972,7 @@ mod tests {
fn serialize_then_deserialize_global() { fn serialize_then_deserialize_global() {
let expected = Psbt { let expected = Psbt {
unsigned_tx: Transaction { unsigned_tx: Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::from_consensus(1257139), lock_time: absolute::LockTime::from_consensus(1257139),
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { previous_output: OutPoint {
@ -1043,7 +1043,7 @@ mod tests {
// create some values to use in the PSBT // create some values to use in the PSBT
let tx = Transaction { let tx = Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { previous_output: OutPoint {
@ -1240,7 +1240,7 @@ mod tests {
fn valid_vector_1() { fn valid_vector_1() {
let unserialized = Psbt { let unserialized = Psbt {
unsigned_tx: Transaction { unsigned_tx: Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::from_consensus(1257139), lock_time: absolute::LockTime::from_consensus(1257139),
input: vec![ input: vec![
TxIn { TxIn {
@ -1272,7 +1272,7 @@ mod tests {
inputs: vec![ inputs: vec![
Input { Input {
non_witness_utxo: Some(Transaction { non_witness_utxo: Some(Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![ input: vec![
TxIn { TxIn {
@ -1572,7 +1572,7 @@ mod tests {
// same vector as valid_vector_1 from BIPs with added // same vector as valid_vector_1 from BIPs with added
let mut unserialized = Psbt { let mut unserialized = Psbt {
unsigned_tx: Transaction { unsigned_tx: Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::from_consensus(1257139), lock_time: absolute::LockTime::from_consensus(1257139),
input: vec![ input: vec![
TxIn { TxIn {
@ -1604,7 +1604,7 @@ mod tests {
inputs: vec![ inputs: vec![
Input { Input {
non_witness_utxo: Some(Transaction { non_witness_utxo: Some(Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![ input: vec![
TxIn { TxIn {
@ -1741,7 +1741,7 @@ mod tests {
let mut t = Psbt { let mut t = Psbt {
unsigned_tx: Transaction { unsigned_tx: Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::from_consensus(1257139), lock_time: absolute::LockTime::from_consensus(1257139),
input: vec![ input: vec![
TxIn { TxIn {
@ -1772,7 +1772,7 @@ mod tests {
inputs: vec![ inputs: vec![
Input { Input {
non_witness_utxo: Some(Transaction { non_witness_utxo: Some(Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![ input: vec![
TxIn { TxIn {
@ -1850,7 +1850,7 @@ mod tests {
use crate::{WPubkeyHash, WitnessProgram}; use crate::{WPubkeyHash, WitnessProgram};
let unsigned_tx = Transaction { let unsigned_tx = Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default(), TxIn::default()], input: vec![TxIn::default(), TxIn::default()],
output: vec![TxOut::NULL], output: vec![TxOut::NULL],

View File

@ -7,7 +7,7 @@ use std::str::FromStr;
use bitcoin::bip32::{Fingerprint, IntoDerivationPath, KeySource, Xpriv, Xpub}; use bitcoin::bip32::{Fingerprint, IntoDerivationPath, KeySource, Xpriv, Xpub};
use bitcoin::blockdata::opcodes::OP_0; use bitcoin::blockdata::opcodes::OP_0;
use bitcoin::blockdata::script; use bitcoin::blockdata::{script, transaction};
use bitcoin::consensus::encode::{deserialize, serialize_hex}; use bitcoin::consensus::encode::{deserialize, serialize_hex};
use bitcoin::hex::FromHex; use bitcoin::hex::FromHex;
use bitcoin::psbt::{Psbt, PsbtSighashType}; use bitcoin::psbt::{Psbt, PsbtSighashType};
@ -163,7 +163,7 @@ fn create_transaction() -> Transaction {
} }
Transaction { Transaction {
version: 2, version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![ input: vec![
TxIn { TxIn {

View File

@ -38,8 +38,8 @@ use bitcoin::psbt::{Input, Output, Psbt, PsbtSighashType};
use bitcoin::sighash::{EcdsaSighashType, TapSighashType}; use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
use bitcoin::taproot::{self, ControlBlock, LeafVersion, TapTree, TaprootBuilder}; use bitcoin::taproot::{self, ControlBlock, LeafVersion, TapTree, TaprootBuilder};
use bitcoin::{ use bitcoin::{
ecdsa, Address, Amount, Block, Network, OutPoint, PrivateKey, PublicKey, ScriptBuf, Sequence, ecdsa, transaction, Address, Amount, Block, Network, OutPoint, PrivateKey, PublicKey,
Target, Transaction, TxIn, TxOut, Txid, Work, ScriptBuf, Sequence, Target, Transaction, TxIn, TxOut, Txid, Work,
}; };
/// Implicitly does regression test for `BlockHeader` also. /// Implicitly does regression test for `BlockHeader` also.
@ -221,7 +221,7 @@ fn serde_regression_public_key() {
#[test] #[test]
fn serde_regression_psbt() { fn serde_regression_psbt() {
let tx = Transaction { let tx = Transaction {
version: 1, version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO, lock_time: absolute::LockTime::ZERO,
input: vec![TxIn { input: vec![TxIn {
previous_output: OutPoint { previous_output: OutPoint {