Add holder anchor signing support to BaseSign
authorWilmer Paulino <wilmer.paulino@gmail.com>
Wed, 13 Jul 2022 17:39:40 +0000 (10:39 -0700)
committerWilmer Paulino <wilmer.paulino@gmail.com>
Tue, 18 Oct 2022 19:23:25 +0000 (12:23 -0700)
lightning/src/chain/keysinterface.rs
lightning/src/util/enforcing_trait_impls.rs

index a89cc602bc2b61588509a5c7b83239979fbf3226..1c64a8bccdfbe4953b6944cb9b9bbc4115b18f4e 100644 (file)
@@ -36,6 +36,7 @@ use util::crypto::{hkdf_extract_expand_twice, sign};
 use util::ser::{Writeable, Writer, Readable, ReadableArgs};
 
 use chain::transaction::OutPoint;
+use ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use ln::{chan_utils, PaymentPreimage};
 use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
 use ln::msgs::UnsignedChannelAnnouncement;
@@ -348,6 +349,12 @@ pub trait BaseSign {
        /// chosen to forgo their output as dust.
        fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
 
+       /// Computes the signature for a commitment transaction's anchor output used as an
+       /// input within `anchor_tx`, which spends the commitment transaction, at index `input`.
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()>;
+
        /// Signs a channel announcement message with our funding key and our node secret key (aka
        /// node_id or network_key), proving it comes from one of the channel participants.
        ///
@@ -645,6 +652,7 @@ impl InMemorySigner {
                witness.push(witness_script.clone().into_bytes());
                Ok(witness)
        }
+
 }
 
 impl BaseSign for InMemorySigner {
@@ -762,6 +770,16 @@ impl BaseSign for InMemorySigner {
                Ok(closing_tx.trust().sign(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
        }
 
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()> {
+               let witness_script = chan_utils::get_anchor_redeemscript(&self.holder_channel_pubkeys.funding_pubkey);
+               let sighash = sighash::SighashCache::new(&*anchor_tx).segwit_signature_hash(
+                       input, &witness_script, ANCHOR_OUTPUT_VALUE_SATOSHI, EcdsaSighashType::All,
+               ).unwrap();
+               Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
+       }
+
        fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
        -> Result<(Signature, Signature), ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
index f4450cc129d81979cedbf1580e5cc3a0450dad62..34b5954d48525b4555ba45b3de803b334ab24007 100644 (file)
@@ -7,6 +7,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSHIS};
 use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
 use ln::{chan_utils, msgs, PaymentPreimage};
 use chain::keysinterface::{Sign, InMemorySigner, BaseSign};
@@ -199,6 +200,16 @@ impl BaseSign for EnforcingSigner {
                Ok(self.inner.sign_closing_transaction(closing_tx, secp_ctx).unwrap())
        }
 
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()> {
+               debug_assert!(MIN_CHAN_DUST_LIMIT_SATOSHIS > ANCHOR_OUTPUT_VALUE_SATOSHI);
+               // As long as our minimum dust limit is enforced and is greater than our anchor output
+               // value, an anchor output can only have an index within [0, 1].
+               assert!(anchor_tx.input[input].previous_output.vout == 0 || anchor_tx.input[input].previous_output.vout == 1);
+               self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx)
+       }
+
        fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
        -> Result<(Signature, Signature), ()> {
                self.inner.sign_channel_announcement(msg, secp_ctx)