You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add util fn for creating a Transaction from spendable outputs
This adds a utility method, `KeysManager::spend_spendable_outputs`,
which constructs a Transaction from a given set of
`SpendableOutputDescriptor`s, deriving relevant keys as needed.
It also adds methods which can sign individual inputs where
channel-specific key derivation is required to
`InMemoryChannelKeys`, making it easy to sign transaction inputs
when a custom `KeysInterface` is used with `InMemoryChannelKeys`.
Copy file name to clipboardExpand all lines: lightning/src/chain/keysinterface.rs
+200-2Lines changed: 200 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -11,9 +11,11 @@
11
11
//! spendable on-chain outputs which the user owns and is responsible for using just as any other
12
12
//! on-chain output which is theirs.
13
13
14
-
use bitcoin::blockdata::transaction::{Transaction,TxOut,SigHashType};
14
+
use bitcoin::blockdata::transaction::{Transaction,TxOut,TxIn,SigHashType};
15
15
use bitcoin::blockdata::script::{Script,Builder};
16
16
use bitcoin::blockdata::opcodes;
17
+
use bitcoin::consensus::Encodable;
18
+
use bitcoin::consensus::encode::VarInt;
17
19
use bitcoin::network::constants::Network;
18
20
use bitcoin::util::bip32::{ExtendedPrivKey,ExtendedPubKey,ChildNumber};
19
21
use bitcoin::util::bip143;
@@ -36,9 +38,10 @@ use ln::chan_utils;
36
38
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript,ChannelPublicKeys,HolderCommitmentTransaction,ChannelTransactionParameters,CommitmentTransaction};
37
39
use ln::msgs::UnsignedChannelAnnouncement;
38
40
41
+
use std::collections::HashSet;
39
42
use std::sync::atomic::{AtomicUsize,Ordering};
40
43
use std::io::Error;
41
-
use ln::msgs::DecodeError;
44
+
use ln::msgs::{DecodeError,MAX_VALUE_MSAT};
42
45
43
46
/// Information about a spendable output to a P2WSH script. See
44
47
/// SpendableOutputDescriptor::DynamicOutputP2WSH for more details on how to spend this.
// TODO: We really should be taking the SigHashCache as a parameter here instead of
516
+
// spend_tx, but ideally the SigHashCache would expose the transaction's inputs read-only
517
+
// so that we can check them. This requires upstream rust-bitcoin changes (as well as
518
+
// bindings updates to support SigHashCache objects).
519
+
if spend_tx.input.len() <= input_idx {returnErr(());}
520
+
if !spend_tx.input[input_idx].script_sig.is_empty(){returnErr(());}
521
+
if spend_tx.input[input_idx].previous_output != descriptor.outpoint.into_bitcoin_outpoint(){returnErr(());}
522
+
523
+
let remotepubkey = self.pubkeys().payment_point;
524
+
let witness_script = bitcoin::Address::p2pkh(&::bitcoin::PublicKey{compressed:true,key: remotepubkey},Network::Testnet).script_pubkey();
525
+
let sighash = hash_to_message!(&bip143::SigHashCache::new(&*spend_tx).signature_hash(input_idx,&witness_script, descriptor.output.value,SigHashType::All)[..]);
526
+
let remotesig = secp_ctx.sign(&sighash,&self.payment_key);
// TODO: We really should be taking the SigHashCache as a parameter here instead of
543
+
// spend_tx, but ideally the SigHashCache would expose the transaction's inputs read-only
544
+
// so that we can check them. This requires upstream rust-bitcoin changes (as well as
545
+
// bindings updates to support SigHashCache objects).
546
+
if spend_tx.input.len() <= input_idx {returnErr(());}
547
+
if !spend_tx.input[input_idx].script_sig.is_empty(){returnErr(());}
548
+
if spend_tx.input[input_idx].previous_output != descriptor.outpoint.into_bitcoin_outpoint(){returnErr(());}
549
+
if spend_tx.input[input_idx].sequence != descriptor.to_self_delayasu32{returnErr(());}
550
+
551
+
let delayed_payment_key = chan_utils::derive_private_key(&secp_ctx,&descriptor.per_commitment_point,&self.delayed_payment_base_key)
552
+
.expect("We constructed the payment_base_key, so we can only fail here if the RNG is busted.");
553
+
let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx,&delayed_payment_key);
554
+
let witness_script = chan_utils::get_revokeable_redeemscript(&descriptor.revocation_pubkey, descriptor.to_self_delay,&delayed_payment_pubkey);
555
+
let sighash = hash_to_message!(&bip143::SigHashCache::new(&*spend_tx).signature_hash(input_idx,&witness_script, descriptor.output.value,SigHashType::All)[..]);
556
+
let local_delayedsig = secp_ctx.sign(&sighash,&delayed_payment_key);
0 commit comments