examples: clean up taproot PSBT example locktime handling

This still has the line

    let lock_time = absolute::LockTime::from_height(psbt.unsigned_tx.lock_time.to_consensus_u32() + lock_time_delta).unwrap();

I'm unsure whether this "adding height to a locktime" concept is a
meaningful thing or just the sort of thing that shows up in example
code. Maybe we should have first-class support for it.

Note that the line, as written, depends on the fact that the original
locktime was a small blockheight. A proper function for this would
handle the exceptional case gracefully.
This commit is contained in:
Andrew Poelstra 2022-12-11 18:30:31 +00:00
parent 821842e1a1
commit f2a5596899
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 11 additions and 11 deletions

View File

@ -144,7 +144,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?, ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?,
beneficiary.master_xpub(), beneficiary.master_xpub(),
)?; )?;
let (tx, psbt) = benefactor.create_inheritance_funding_tx(1000, UTXO_2)?; let (tx, psbt) = benefactor.create_inheritance_funding_tx(absolute::LockTime::from_height(1000).unwrap(), UTXO_2)?;
let tx_hex = encode::serialize_hex(&tx); let tx_hex = encode::serialize_hex(&tx);
println!("Inheritance funding tx hex:\n\n{}", tx_hex); println!("Inheritance funding tx hex:\n\n{}", tx_hex);
@ -154,7 +154,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// And mine a block to confirm the transaction: // And mine a block to confirm the transaction:
// bt generatetoaddress 1 $(bt-benefactor getnewaddress '' 'bech32m') // bt generatetoaddress 1 $(bt-benefactor getnewaddress '' 'bech32m')
let spending_tx = beneficiary.spend_inheritance(psbt, 1000, to_address)?; let spending_tx = beneficiary.spend_inheritance(psbt, absolute::LockTime::from_height(1000).unwrap(), to_address)?;
let spending_tx_hex = encode::serialize_hex(&spending_tx); let spending_tx_hex = encode::serialize_hex(&spending_tx);
println!("\nInheritance spending tx hex:\n\n{}", spending_tx_hex); println!("\nInheritance spending tx hex:\n\n{}", spending_tx_hex);
// If you try to broadcast now, the transaction will be rejected as it is timelocked. // If you try to broadcast now, the transaction will be rejected as it is timelocked.
@ -176,7 +176,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?, ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?,
beneficiary.master_xpub(), beneficiary.master_xpub(),
)?; )?;
let (tx, _) = benefactor.create_inheritance_funding_tx(2000, UTXO_3)?; let (tx, _) = benefactor.create_inheritance_funding_tx(absolute::LockTime::from_height(2000).unwrap(), UTXO_3)?;
let tx_hex = encode::serialize_hex(&tx); let tx_hex = encode::serialize_hex(&tx);
println!("Inheritance funding tx hex:\n\n{}", tx_hex); println!("Inheritance funding tx hex:\n\n{}", tx_hex);
@ -357,9 +357,9 @@ impl BenefactorWallet {
}) })
} }
fn time_lock_script(locktime: u32, beneficiary_key: XOnlyPublicKey) -> Script { fn time_lock_script(locktime: absolute::LockTime, beneficiary_key: XOnlyPublicKey) -> Script {
script::Builder::new() script::Builder::new()
.push_int(locktime as i64) .push_int(locktime.to_consensus_u32() as i64)
.push_opcode(OP_CLTV) .push_opcode(OP_CLTV)
.push_opcode(OP_DROP) .push_opcode(OP_DROP)
.push_x_only_key(&beneficiary_key) .push_x_only_key(&beneficiary_key)
@ -369,7 +369,7 @@ impl BenefactorWallet {
fn create_inheritance_funding_tx( fn create_inheritance_funding_tx(
&mut self, &mut self,
lock_time: u32, lock_time: absolute::LockTime,
input_utxo: P2trUtxo, input_utxo: P2trUtxo,
) -> Result<(Transaction, Psbt), Box<dyn std::error::Error>> { ) -> Result<(Transaction, Psbt), Box<dyn std::error::Error>> {
if let ChildNumber::Normal { index } = self.next { if let ChildNumber::Normal { index } = self.next {
@ -412,7 +412,7 @@ impl BenefactorWallet {
// CREATOR + UPDATER // CREATOR + UPDATER
let next_tx = Transaction { let next_tx = Transaction {
version: 2, version: 2,
lock_time: absolute::LockTime::from_consensus(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 },
script_sig: Script::new(), script_sig: Script::new(),
@ -482,7 +482,7 @@ impl BenefactorWallet {
self.beneficiary_xpub.derive_pub(&self.secp, &new_derivation_path)?.to_x_only_pub(); self.beneficiary_xpub.derive_pub(&self.secp, &new_derivation_path)?.to_x_only_pub();
// Build up the leaf script and combine with internal key into a taproot commitment // Build up the leaf script and combine with internal key into a taproot commitment
let lock_time = psbt.unsigned_tx.lock_time.to_consensus_u32() + lock_time_delta; let lock_time = absolute::LockTime::from_height(psbt.unsigned_tx.lock_time.to_consensus_u32() + lock_time_delta).unwrap();
let script = Self::time_lock_script(lock_time, beneficiary_key); let script = Self::time_lock_script(lock_time, beneficiary_key);
let leaf_hash = TapLeafHash::from_script(&script, LeafVersion::TapScript); let leaf_hash = TapLeafHash::from_script(&script, LeafVersion::TapScript);
@ -557,7 +557,7 @@ impl BenefactorWallet {
let next_tx = Transaction { let next_tx = Transaction {
version: 2, version: 2,
lock_time: absolute::LockTime::from_consensus(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 },
script_sig: Script::new(), script_sig: Script::new(),
@ -626,13 +626,13 @@ impl BeneficiaryWallet {
fn spend_inheritance( fn spend_inheritance(
&self, &self,
mut psbt: Psbt, mut psbt: Psbt,
lock_time: u32, lock_time: absolute::LockTime,
to_address: Address, to_address: Address,
) -> Result<Transaction, Box<dyn std::error::Error>> { ) -> Result<Transaction, Box<dyn std::error::Error>> {
let input_value = psbt.inputs[0].witness_utxo.as_ref().unwrap().value; let input_value = psbt.inputs[0].witness_utxo.as_ref().unwrap().value;
let input_script_pubkey = let input_script_pubkey =
psbt.inputs[0].witness_utxo.as_ref().unwrap().script_pubkey.clone(); psbt.inputs[0].witness_utxo.as_ref().unwrap().script_pubkey.clone();
psbt.unsigned_tx.lock_time = absolute::LockTime::from_consensus(lock_time); psbt.unsigned_tx.lock_time = lock_time;
psbt.unsigned_tx.output = vec![TxOut { psbt.unsigned_tx.output = vec![TxOut {
script_pubkey: to_address.script_pubkey(), script_pubkey: to_address.script_pubkey(),
value: input_value - ABSOLUTE_FEES_IN_SATS, value: input_value - ABSOLUTE_FEES_IN_SATS,