Add transaction::Version data type
BIP-68 activated a fair while ago (circa 2019) and since then only transaction versions 1 and 2 have been considered standard. Currently in our `Transaction` struct we use an `i32`, this means users can construct a non-standard transaction if they do not first look up what the value should be. We can help folk out here by abstracting over the version number. Since the version number only governs standardness elect to make the inner `i32` public (ie., not an invariant). The aim of the type is to make life easy not restrict what versions are used. Add transaction::Version data type that simply provides two consts `ONE` and `TWO`. Add a `Default` impl on `Version` that returns `Version::TWO`. In tests that used version 0, instead use `Version::default` because the test obviously does not care.
This commit is contained in:
parent
a2a4efbe6a
commit
c950ef4bbd
|
@ -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 },
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -585,7 +585,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
|
||||||
|
@ -835,6 +835,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 {
|
||||||
|
@ -921,7 +965,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() {
|
||||||
|
@ -1374,7 +1418,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.
|
||||||
|
@ -1415,7 +1459,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.
|
||||||
|
@ -1487,13 +1531,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]
|
||||||
|
@ -1781,7 +1825,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![],
|
||||||
|
|
|
@ -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![],
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue