transaction: Remove Default implementations

Currently we provide `Default` implementations for a couple of types in
the `transaction` module, the values returned are meaningless and it
seems these impls were added to make writing test code easier. In
hindsight this was the wrong thing to do.

Break the API and remove the `Default` implementations for `OutPoint`
and `TxIn`.

Add an associated const `TxIn::EMPTY_COINBASE` that is, as the name
suggests, an empty transaction input with the prevout set to all
zeros as for the coinbase transaction.
This commit is contained in:
Tobin C. Harding 2024-09-19 13:57:49 +10:00
parent 40ba08f369
commit d0a30096b4
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 15 additions and 32 deletions

View File

@ -127,10 +127,6 @@ impl OutPoint {
pub fn is_null(&self) -> bool { *self == OutPoint::null() }
}
impl Default for OutPoint {
fn default() -> Self { OutPoint::null() }
}
impl fmt::Display for OutPoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}", self.txid, self.vout)
@ -249,6 +245,14 @@ pub struct TxIn {
}
impl TxIn {
/// An empty transaction input with the previous output as for a coinbase transaction.
pub const EMPTY_COINBASE: TxIn = TxIn {
previous_output: OutPoint::COINBASE_PREVOUT,
script_sig: ScriptBuf::new(),
sequence: Sequence::MAX,
witness: Witness::new(),
};
/// Returns the input base weight.
///
/// Base weight excludes the witness and script.
@ -313,17 +317,6 @@ impl TxIn {
pub fn total_size(&self) -> usize { self.base_size() + self.witness.size() }
}
impl Default for TxIn {
fn default() -> TxIn {
TxIn {
previous_output: OutPoint::default(),
script_sig: ScriptBuf::new(),
sequence: Sequence::MAX,
witness: Witness::default(),
}
}
}
/// Bitcoin transaction output.
///
/// Defines new coins to be created as a result of the transaction,
@ -1540,16 +1533,6 @@ mod tests {
assert!(txin.is_ok());
}
#[test]
fn txin_default() {
let txin = TxIn::default();
assert_eq!(txin.previous_output, OutPoint::default());
assert_eq!(txin.script_sig, ScriptBuf::new());
assert_eq!(txin.sequence, Sequence::from_consensus(0xFFFFFFFF));
assert_eq!(txin.previous_output, OutPoint::default());
assert_eq!(txin.witness.len(), 0);
}
#[test]
fn is_coinbase() {
use crate::constants;
@ -2251,7 +2234,7 @@ mod tests {
#[test]
fn outpoint_format() {
let outpoint = OutPoint::default();
let outpoint = OutPoint::COINBASE_PREVOUT;
let debug = "OutPoint { txid: 0000000000000000000000000000000000000000000000000000000000000000, vout: 4294967295 }";
assert_eq!(debug, format!("{:?}", &outpoint));

View File

@ -1487,7 +1487,7 @@ mod tests {
let tx = Transaction {
version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default(), TxIn::default()],
input: vec![TxIn::EMPTY_COINBASE, TxIn::EMPTY_COINBASE],
output: vec![TxOut::NULL],
};
let script = ScriptBuf::new();
@ -1676,7 +1676,7 @@ mod tests {
let dumb_tx = Transaction {
version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default()],
input: vec![TxIn::EMPTY_COINBASE],
output: vec![],
};
let mut c = SighashCache::new(&dumb_tx);

View File

@ -2155,7 +2155,7 @@ mod tests {
vout: 0,
},
sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
..Default::default()
..TxIn::EMPTY_COINBASE
}
],
output: vec![
@ -2186,7 +2186,7 @@ mod tests {
vout: 1,
},
sequence: Sequence::MAX,
..Default::default()
..TxIn::EMPTY_COINBASE
},
TxIn {
previous_output: OutPoint {
@ -2194,7 +2194,7 @@ mod tests {
vout: 1,
},
sequence: Sequence::MAX,
..Default::default()
..TxIn::EMPTY_COINBASE
}
],
output: vec![
@ -2258,7 +2258,7 @@ mod tests {
let unsigned_tx = Transaction {
version: transaction::Version::TWO,
lock_time: absolute::LockTime::ZERO,
input: vec![TxIn::default(), TxIn::default()],
input: vec![TxIn::EMPTY_COINBASE, TxIn::EMPTY_COINBASE],
output: vec![TxOut::NULL],
};
let mut psbt = Psbt::from_unsigned_tx(unsigned_tx).unwrap();