Merge rust-bitcoin/rust-bitcoin#4033: primitives: Add tests to transaction

435750f292 Add a parse_vout test (Jamil Lambert, PhD)
957be3c978 Add OutPoint test (Jamil Lambert, PhD)
a4ef027134 Add tests of transaction functions (Jamil Lambert, PhD)

Pull request description:

  Add tests to kill the mutants in `primitives/src/transaction.rs`

ACKs for top commit:
  tcharding:
    ACK 435750f292

Tree-SHA512: 78baf40ad6ed1cd5b3a33346b4702c3a7efbb03ae6eec9a802d3dea99910373cf4e8053c73e9fdc02ce54852d3ee43253f2ff0c149c86870ecfed2fc909e5bcf
This commit is contained in:
merge-script 2025-02-13 19:00:07 +00:00
commit 7a369aef2b
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 80 additions and 0 deletions

View File

@ -598,3 +598,83 @@ impl<'a> Arbitrary<'a> for Txid {
Ok(Txid(t))
}
}
#[cfg(feature = "alloc")]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn transaction_functions() {
let txin = TxIn {
previous_output: OutPoint {
txid: Txid::from_byte_array([0xAA; 32]), // Arbitrary invalid dummy value.
vout: 0,
},
script_sig: ScriptBuf::new(),
sequence: Sequence::MAX,
witness: Witness::new(),
};
let txout = TxOut {
value: Amount::from_sat(123456789),
script_pubkey: ScriptBuf::new(),
};
let tx_orig = Transaction {
version: Version::ONE,
lock_time: absolute::LockTime::from_consensus(1738968231), // The time this was written
input: vec![txin.clone()],
output: vec![txout.clone()],
};
// Test changing the transaction
let mut tx = tx_orig.clone();
tx.inputs_mut()[0].previous_output.txid = Txid::from_byte_array([0xFF; 32]);
tx.outputs_mut()[0].value = Amount::from_sat(987654321);
assert_eq!(tx.inputs()[0].previous_output.txid.to_byte_array(), [0xFF; 32]);
assert_eq!(tx.outputs()[0].value.to_sat(), 987654321);
// Test uses_segwit_serialization
assert!(!tx.uses_segwit_serialization());
tx.input[0].witness.push(vec![0xAB, 0xCD, 0xEF]);
assert!(tx.uses_segwit_serialization());
// Test partial ord
assert!(tx > tx_orig);
}
#[test]
fn outpoint_from_str() {
// Check format errors
let mut outpoint_str = "0".repeat(64); // No ":"
let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
assert_eq!(outpoint, Err(ParseOutPointError::Format));
outpoint_str.push(':'); // Empty vout
let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
assert_eq!(outpoint, Err(ParseOutPointError::Format));
outpoint_str.push('0'); // Correct format
let outpoint: OutPoint = outpoint_str.parse().unwrap();
assert_eq!(outpoint.txid, Txid::from_byte_array([0; 32]));
assert_eq!(outpoint.vout, 0);
// Check the number of bytes OutPoint contributes to the transaction is equal to SIZE
let outpoint_size = outpoint.txid.as_byte_array().len() + outpoint.vout.to_le_bytes().len();
assert_eq!(outpoint_size, OutPoint::SIZE);
// Check TooLong error
outpoint_str.push_str("0000000000");
let outpoint: Result<OutPoint, ParseOutPointError> = outpoint_str.parse();
assert_eq!(outpoint, Err(ParseOutPointError::TooLong));
}
#[test]
fn canonical_vout() {
assert_eq!(parse_vout("0").unwrap(), 0);
assert_eq!(parse_vout("1").unwrap(), 1);
assert!(parse_vout("01").is_err()); // Leading zero not allowed
assert!(parse_vout("+1").is_err()); // Non digits not allowed
}
}