Move the locktime module to absolute

In preparation for adding a relative lock time type move the `locktime`
module to a new module called `absolute`. Use qualified path for
locktime types (e.g. `absolute::PackedLockTime`) to improve readability.
This commit is contained in:
Tobin C. Harding 2022-08-16 11:24:56 +10:00
parent 720ea29865
commit 9f7d934f5d
10 changed files with 56 additions and 45 deletions

View File

@ -34,6 +34,7 @@ use std::str::FromStr;
use bitcoin::consensus::encode;
use bitcoin::hashes::hex::{self, FromHex};
use bitcoin::locktime::absolute;
use bitcoin::secp256k1::{Secp256k1, Signing, Verification};
use bitcoin::util::amount::ParseAmountError;
use bitcoin::util::bip32::{
@ -42,7 +43,7 @@ use bitcoin::util::bip32::{
};
use bitcoin::util::psbt::{self, Input, Psbt, PsbtSighashType};
use bitcoin::{
address, Address, Amount, Network, OutPoint, PackedLockTime, PrivateKey, PublicKey, Script,
address, Address, Amount, Network, OutPoint, PrivateKey, PublicKey, Script,
Sequence, Transaction, TxIn, TxOut, Txid, Witness,
};
@ -206,7 +207,7 @@ impl WatchOnly {
let tx = Transaction {
version: 2,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(INPUT_UTXO_TXID)?,

View File

@ -16,7 +16,7 @@ use crate::hashes::hex::{self, HexIterator};
use crate::hashes::{Hash, sha256d};
use crate::blockdata::opcodes;
use crate::blockdata::script;
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
use crate::blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn, Sequence};
use crate::blockdata::block::{Block, BlockHeader};
use crate::blockdata::witness::Witness;
@ -72,7 +72,7 @@ fn bitcoin_genesis_tx() -> Transaction {
// Base
let mut ret = Transaction {
version: 1,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![],
output: vec![],
};
@ -200,7 +200,7 @@ mod test {
use crate::hashes::hex::{ToHex, FromHex};
use crate::network::constants::Network;
use crate::consensus::encode::serialize;
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
#[test]
fn bitcoin_genesis_first_transaction() {
@ -218,7 +218,7 @@ mod test {
assert_eq!(serialize(&gen.output[0].script_pubkey),
Vec::from_hex("434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac").unwrap());
assert_eq!(gen.output[0].value, 50 * COIN_VALUE);
assert_eq!(gen.lock_time, PackedLockTime::ZERO);
assert_eq!(gen.lock_time, absolute::PackedLockTime::ZERO);
assert_eq!(gen.wtxid().to_hex(), "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
}

View File

@ -47,7 +47,8 @@ pub const LOCK_TIME_THRESHOLD: u32 = 500_000_000;
///
/// # Examples
/// ```
/// # use bitcoin::{Amount, PackedLockTime, LockTime};
/// # use bitcoin::Amount;
/// # use bitcoin::absolute::{PackedLockTime, LockTime};
/// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
/// struct S {
/// lock_time: PackedLockTime,
@ -152,7 +153,7 @@ impl fmt::UpperHex for PackedLockTime {
///
/// # Examples
/// ```
/// # use bitcoin::{LockTime, LockTime::*};
/// # use bitcoin::absolute::{LockTime, LockTime::*};
/// # let n = LockTime::from_consensus(100); // n OP_CHECKLOCKTIMEVERIFY
/// # let lock_time = LockTime::from_consensus(100); // nLockTime
/// // To compare lock times there are various `is_satisfied_*` methods, you may also use:
@ -171,7 +172,7 @@ pub enum LockTime {
///
/// # Examples
/// ```rust
/// use bitcoin::LockTime;
/// use bitcoin::absolute::LockTime;
///
/// let block: u32 = 741521;
/// let n = LockTime::from_height(block).expect("valid height");
@ -183,7 +184,7 @@ pub enum LockTime {
///
/// # Examples
/// ```rust
/// use bitcoin::LockTime;
/// use bitcoin::absolute::LockTime;
///
/// let seconds: u32 = 1653195600; // May 22nd, 5am UTC.
/// let n = LockTime::from_time(seconds).expect("valid time");
@ -203,7 +204,7 @@ impl LockTime {
/// # Examples
///
/// ```rust
/// # use bitcoin::LockTime;
/// # use bitcoin::absolute::LockTime;
/// # let n = LockTime::from_consensus(741521); // n OP_CHECKLOCKTIMEVERIFY
///
/// // `from_consensus` roundtrips as expected with `to_consensus_u32`.
@ -225,7 +226,7 @@ impl LockTime {
///
/// # Examples
/// ```rust
/// # use bitcoin::LockTime;
/// # use bitcoin::absolute::LockTime;
/// assert!(LockTime::from_height(741521).is_ok());
/// assert!(LockTime::from_height(1653195600).is_err());
/// ```
@ -241,7 +242,7 @@ impl LockTime {
///
/// # Examples
/// ```rust
/// # use bitcoin::LockTime;
/// # use bitcoin::absolute::LockTime;
/// assert!(LockTime::from_time(1653195600).is_ok());
/// assert!(LockTime::from_time(741521).is_err());
/// ```
@ -283,7 +284,7 @@ impl LockTime {
///
/// # Examples
/// ```no_run
/// # use bitcoin::locktime::{LockTime, Height, Time};
/// # use bitcoin::absolute::{LockTime, Height, Time};
/// // Can be implemented if block chain data is available.
/// fn get_height() -> Height { todo!("return the current block height") }
/// fn get_time() -> Time { todo!("return the current block time") }
@ -314,7 +315,7 @@ impl LockTime {
/// # Examples
///
/// ```rust
/// # use bitcoin::{LockTime, LockTime::*};
/// # use bitcoin::absolute::{LockTime, LockTime::*};
/// # let n = LockTime::from_consensus(100); // n OP_CHECKLOCKTIMEVERIFY
/// # let lock_time = LockTime::from_consensus(100); // nLockTime
///
@ -410,7 +411,7 @@ impl Height {
///
/// # Examples
/// ```rust
/// use bitcoin::locktime::Height;
/// use bitcoin::locktime::absolute::Height;
///
/// let h: u32 = 741521;
/// let height = Height::from_consensus(h).expect("invalid height value");
@ -429,7 +430,7 @@ impl Height {
///
/// # Examples
/// ```rust
/// use bitcoin::LockTime;
/// use bitcoin::absolute::LockTime;
///
/// let n_lock_time: u32 = 741521;
/// let lock_time = LockTime::from_consensus(n_lock_time);
@ -493,7 +494,7 @@ impl Time {
///
/// # Examples
/// ```rust
/// use bitcoin::locktime::Time;
/// use bitcoin::locktime::absolute::Time;
///
/// let t: u32 = 1653195600; // May 22nd, 5am UTC.
/// let time = Time::from_consensus(t).expect("invalid time value");
@ -512,7 +513,7 @@ impl Time {
///
/// # Examples
/// ```rust
/// use bitcoin::LockTime;
/// use bitcoin::absolute::LockTime;
///
/// let n_lock_time: u32 = 1653195600; // May 22nd, 5am UTC.
/// let lock_time = LockTime::from_consensus(n_lock_time);

View File

@ -0,0 +1,7 @@
// Rust Bitcoin Library - Written by the rust-bitcoin developers.
// SPDX-License-Identifier: CC0-1.0
//! Provides absolute locktime.
//!
pub mod absolute;

View File

@ -25,7 +25,7 @@ use crate::blockdata::constants::WITNESS_SCALE_FACTOR;
#[cfg(feature="bitcoinconsensus")] use crate::blockdata::script;
use crate::blockdata::script::Script;
use crate::blockdata::witness::Witness;
use crate::blockdata::locktime::{LockTime, PackedLockTime, Height, Time};
use crate::blockdata::locktime::absolute::{self, Height, Time};
use crate::consensus::{encode, Decodable, Encodable};
use crate::hash_types::{Sighash, Txid, Wtxid};
use crate::VarInt;
@ -207,7 +207,8 @@ pub struct TxIn {
}
impl TxIn {
/// Returns true if this input enables the [`LockTime`] (aka `nLockTime`) of its [`Transaction`].
/// Returns true if this input enables the [`absolute::LockTime`] (aka `nLockTime`) of its
/// [`Transaction`].
///
/// `nLockTime` is enabled if *any* input enables it. See [`Transaction::is_lock_time_enabled`]
/// to check the overall state. If none of the inputs enables it, the lock time value is simply
@ -577,7 +578,7 @@ pub struct Transaction {
///
/// * [BIP-65 OP_CHECKLOCKTIMEVERIFY](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)
/// * [BIP-113 Median time-past as endpoint for lock-time calculations](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki)
pub lock_time: PackedLockTime,
pub lock_time: absolute::PackedLockTime,
/// List of transaction inputs.
pub input: Vec<TxIn>,
/// List of transaction outputs.
@ -882,7 +883,7 @@ impl Transaction {
if !self.is_lock_time_enabled() {
return true;
}
LockTime::from(self.lock_time).is_satisfied_by(height, time)
absolute::LockTime::from(self.lock_time).is_satisfied_by(height, time)
}
/// Returns `true` if this transactions nLockTime is enabled ([BIP-65]).
@ -1033,7 +1034,7 @@ mod tests {
use crate::blockdata::constants::WITNESS_SCALE_FACTOR;
use crate::blockdata::script::Script;
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
use crate::consensus::encode::serialize;
use crate::consensus::encode::deserialize;
@ -1132,7 +1133,7 @@ mod tests {
"ce9ea9f6f5e422c6a9dbcddb3b9a14d1c78fab9ab520cb281aa2a74a09575da1".to_string());
assert_eq!(realtx.input[0].previous_output.vout, 1);
assert_eq!(realtx.output.len(), 1);
assert_eq!(realtx.lock_time, PackedLockTime::ZERO);
assert_eq!(realtx.lock_time, absolute::PackedLockTime::ZERO);
assert_eq!(format!("{:x}", realtx.txid()),
"a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string());
@ -1166,7 +1167,7 @@ mod tests {
"7cac3cf9a112cf04901a51d605058615d56ffe6d04b45270e89d1720ea955859".to_string());
assert_eq!(realtx.input[0].previous_output.vout, 1);
assert_eq!(realtx.output.len(), 1);
assert_eq!(realtx.lock_time, PackedLockTime::ZERO);
assert_eq!(realtx.lock_time, absolute::PackedLockTime::ZERO);
assert_eq!(format!("{:x}", realtx.txid()),
"f5864806e3565c34d1b41e716f72609d00b55ea5eac5b924c9719a842ef42206".to_string());

View File

@ -95,7 +95,7 @@ use core2::io;
pub use crate::address::{Address, AddressType};
pub use crate::blockdata::block::{self, Block, BlockHeader};
pub use crate::blockdata::locktime::{self, LockTime, PackedLockTime};
pub use crate::blockdata::locktime::{self, absolute};
pub use crate::blockdata::script::{self, Script};
#[allow(deprecated)]
pub use crate::blockdata::transaction::SigHashType;

View File

@ -78,10 +78,10 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
/// panics if `input_index` is out of bounds with respect of the number of inputs
///
/// ```
/// use bitcoin::{EcdsaSighashType, Script, Transaction, PackedLockTime};
/// use bitcoin::util::bip143::SigHashCache;
/// use bitcoin::{absolute, EcdsaSighashType, Script, Transaction};
///
/// let mut tx_to_sign = Transaction { version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
/// let mut tx_to_sign = Transaction { version: 2, lock_time: absolute::PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
/// let input_count = tx_to_sign.input.len();
///
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);

View File

@ -372,17 +372,18 @@ impl BlockTransactions {
#[cfg(test)]
mod test {
use super::*;
use crate::blockdata::locktime::absolute;
use crate::consensus::encode::{deserialize, serialize};
use crate::hashes::hex::FromHex;
use crate::{
Block, BlockHash, BlockHeader, OutPoint, Script, Sequence, Transaction, TxIn, TxMerkleNode,
TxOut, Txid, Witness, LockTime,
TxOut, Txid, Witness,
};
fn dummy_tx(nonce: &[u8]) -> Transaction {
Transaction {
version: 1,
lock_time: LockTime::from_consensus(2).into(),
lock_time: absolute::LockTime::from_consensus(2).into(),
input: vec![TxIn {
previous_output: OutPoint::new(Txid::hash(nonce), 0),
script_sig: Script::new(),

View File

@ -335,7 +335,7 @@ impl Decodable for PartiallySignedTransaction {
mod tests {
use super::*;
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
use crate::hashes::hex::FromHex;
use crate::hashes::{sha256, hash160, Hash, ripemd160};
use crate::hash_types::Txid;
@ -359,7 +359,7 @@ mod tests {
let psbt = PartiallySignedTransaction {
unsigned_tx: Transaction {
version: 2,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![],
output: vec![],
},
@ -429,7 +429,7 @@ mod tests {
let expected = PartiallySignedTransaction {
unsigned_tx: Transaction {
version: 2,
lock_time: PackedLockTime(1257139),
lock_time: absolute::PackedLockTime(1257139),
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(
@ -502,7 +502,7 @@ mod tests {
// create some values to use in the PSBT
let tx = Transaction {
version: 1,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex("e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389").unwrap(),
@ -600,7 +600,7 @@ mod tests {
use crate::blockdata::script::Script;
use crate::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence};
use crate::consensus::encode::serialize_hex;
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
use crate::util::psbt::map::{Map, Input, Output};
use crate::util::psbt::raw;
use crate::util::psbt::{PartiallySignedTransaction, Error};
@ -690,7 +690,7 @@ mod tests {
let unserialized = PartiallySignedTransaction {
unsigned_tx: Transaction {
version: 2,
lock_time: PackedLockTime(1257139),
lock_time: absolute::PackedLockTime(1257139),
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(
@ -721,7 +721,7 @@ mod tests {
inputs: vec![Input {
non_witness_utxo: Some(Transaction {
version: 1,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(
@ -1002,7 +1002,7 @@ mod tests {
let mut unserialized = PartiallySignedTransaction {
unsigned_tx: Transaction {
version: 2,
lock_time: PackedLockTime(1257139),
lock_time: absolute::PackedLockTime(1257139),
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(
@ -1033,7 +1033,7 @@ mod tests {
inputs: vec![Input {
non_witness_utxo: Some(Transaction {
version: 1,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(

View File

@ -1035,9 +1035,9 @@ impl<R: DerefMut<Target=Transaction>> SighashCache<R> {
///
/// This allows in-line signing such as
/// ```
/// use bitcoin::{EcdsaSighashType, PackedLockTime, Script, SighashCache, Transaction};
/// use bitcoin::{absolute, EcdsaSighashType, SighashCache, Transaction, Script};
///
/// let mut tx_to_sign = Transaction { version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
/// let mut tx_to_sign = Transaction { version: 2, lock_time: absolute::PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
/// let input_count = tx_to_sign.input.len();
///
/// let mut sig_hasher = SighashCache::new(&mut tx_to_sign);
@ -1099,7 +1099,7 @@ mod tests {
use secp256k1::{self, SecretKey, XOnlyPublicKey};
use crate::{Script, Transaction, TxIn, TxOut, EcdsaSighashType, Address};
use crate::blockdata::locktime::PackedLockTime;
use crate::blockdata::locktime::absolute;
use crate::consensus::deserialize;
use crate::hashes::hex::{FromHex, ToHex};
use crate::hashes::{Hash, HashEngine};
@ -1119,7 +1119,7 @@ mod tests {
// We need a tx with more inputs than outputs.
let tx = Transaction {
version: 1,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn::default(), TxIn::default()],
output: vec![TxOut::default()],
};
@ -1300,7 +1300,7 @@ mod tests {
fn test_sighash_errors() {
let dumb_tx = Transaction {
version: 0,
lock_time: PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,
input: vec![TxIn::default()],
output: vec![],
};