Avoid use of OnlyReadsKeysInterface
[rust-lightning] / lightning / src / ln / chan_utils.rs
index a8c9dcc826e540d91e4020c67789df23e30297a4..4a66f85e2c98e63281fd82e5e2cfd42f761e416a 100644 (file)
@@ -14,6 +14,7 @@ use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::opcodes;
 use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, EcdsaSighashType};
 use bitcoin::util::sighash;
+use bitcoin::util::address::Payload;
 
 use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -25,11 +26,11 @@ use crate::ln::msgs::DecodeError;
 use crate::util::ser::{Readable, Writeable, Writer};
 use crate::util::{byte_utils, transaction_utils};
 
-use bitcoin::hash_types::WPubkeyHash;
 use bitcoin::secp256k1::{SecretKey, PublicKey, Scalar};
 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Message};
 use bitcoin::secp256k1::Error as SecpError;
 use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
+use bitcoin::PublicKey as BitcoinPublicKey;
 
 use crate::io;
 use crate::prelude::*;
@@ -41,13 +42,20 @@ use core::ops::Deref;
 use crate::chain;
 use crate::util::crypto::sign;
 
-pub(crate) const MAX_HTLCS: u16 = 483;
-pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
-pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 136;
-// The weight of `accepted_htlc_script` can vary in function of its CLTV argument value. We define a
-// range that encompasses both its non-anchors and anchors variants.
+/// Maximum number of one-way in-flight HTLC (protocol-level value).
+pub const MAX_HTLCS: u16 = 483;
+/// The weight of a BIP141 witnessScript for a BOLT3's "offered HTLC output" on a commitment transaction, non-anchor variant.
+pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
+/// The weight of a BIP141 witnessScript for a BOLT3's "offered HTLC output" on a commitment transaction, anchor variant.
+pub const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 136;
+
+/// The weight of a BIP141 witnessScript for a BOLT3's "received HTLC output" can vary in function of its CLTV argument value.
+/// We define a range that encompasses both its non-anchors and anchors variants.
 pub(crate) const MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 136;
-pub(crate) const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 143;
+/// The weight of a BIP141 witnessScript for a BOLT3's "received HTLC output" can vary in function of its CLTV argument value.
+/// We define a range that encompasses both its non-anchors and anchors variants.
+/// This is the maximum post-anchor value.
+pub const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 143;
 
 /// Gets the weight for an HTLC-Success transaction.
 #[inline]
@@ -65,18 +73,24 @@ pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
        if opt_anchors { HTLC_TIMEOUT_ANCHOR_TX_WEIGHT } else { HTLC_TIMEOUT_TX_WEIGHT }
 }
 
+/// Describes the type of HTLC claim as determined by analyzing the witness.
 #[derive(PartialEq, Eq)]
-pub(crate) enum HTLCClaim {
+pub enum HTLCClaim {
+       /// Claims an offered output on a commitment transaction through the timeout path.
        OfferedTimeout,
+       /// Claims an offered output on a commitment transaction through the success path.
        OfferedPreimage,
+       /// Claims an accepted output on a commitment transaction through the timeout path.
        AcceptedTimeout,
+       /// Claims an accepted output on a commitment transaction through the success path.
        AcceptedPreimage,
+       /// Claims an offered/accepted output on a commitment transaction through the revocation path.
        Revocation,
 }
 
 impl HTLCClaim {
        /// Check if a given input witness attempts to claim a HTLC.
-       pub(crate) fn from_witness(witness: &Witness) -> Option<Self> {
+       pub fn from_witness(witness: &Witness) -> Option<Self> {
                debug_assert_eq!(OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS, MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT);
                if witness.len() < 2 {
                        return None;
@@ -660,7 +674,7 @@ pub fn make_funding_redeemscript(broadcaster: &PublicKey, countersignatory: &Pub
 ///
 /// Panics if htlc.transaction_output_index.is_none() (as such HTLCs do not appear in the
 /// commitment transaction).
-pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, contest_delay: u16, htlc: &HTLCOutputInCommitment, opt_anchors: bool, broadcaster_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
+pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, contest_delay: u16, htlc: &HTLCOutputInCommitment, opt_anchors: bool, use_non_zero_fee_anchors: bool, broadcaster_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
        let mut txins: Vec<TxIn> = Vec::new();
        txins.push(TxIn {
                previous_output: OutPoint {
@@ -677,7 +691,7 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
        } else {
                htlc_success_tx_weight(opt_anchors)
        };
-       let output_value = if opt_anchors {
+       let output_value = if opt_anchors && !use_non_zero_fee_anchors {
                htlc.amount_msat / 1000
        } else {
                let total_fee = feerate_per_kw as u64 * weight / 1000;
@@ -700,7 +714,7 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
 
 /// Gets the witnessScript for the to_remote output when anchors are enabled.
 #[inline]
-pub(crate) fn get_to_countersignatory_with_anchors_redeemscript(payment_point: &PublicKey) -> Script {
+pub fn get_to_countersignatory_with_anchors_redeemscript(payment_point: &PublicKey) -> Script {
        Builder::new()
                .push_slice(&payment_point.serialize()[..])
                .push_opcode(opcodes::all::OP_CHECKSIGVERIFY)
@@ -749,7 +763,7 @@ pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signatu
 ///
 /// Normally, this is converted to the broadcaster/countersignatory-organized DirectedChannelTransactionParameters
 /// before use, via the as_holder_broadcastable and as_counterparty_broadcastable functions.
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct ChannelTransactionParameters {
        /// Holder public keys
        pub holder_pubkeys: ChannelPublicKeys,
@@ -765,11 +779,15 @@ pub struct ChannelTransactionParameters {
        pub funding_outpoint: Option<chain::transaction::OutPoint>,
        /// Are anchors (zero fee HTLC transaction variant) used for this channel. Boolean is
        /// serialization backwards-compatible.
-       pub opt_anchors: Option<()>
+       pub opt_anchors: Option<()>,
+       /// Are non-zero-fee anchors are enabled (used in conjuction with opt_anchors)
+       /// It is intended merely for backwards compatibility with signers that need it.
+       /// There is no support for this feature in LDK channel negotiation.
+       pub opt_non_zero_fee_anchors: Option<()>,
 }
 
 /// Late-bound per-channel counterparty data used to build transactions.
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct CounterpartyChannelTransactionParameters {
        /// Counter-party public keys
        pub pubkeys: ChannelPublicKeys,
@@ -820,6 +838,7 @@ impl_writeable_tlv_based!(ChannelTransactionParameters, {
        (6, counterparty_parameters, option),
        (8, funding_outpoint, option),
        (10, opt_anchors, option),
+       (12, opt_non_zero_fee_anchors, option),
 });
 
 /// Static channel fields used to build transactions given per-commitment fields, organized by
@@ -942,7 +961,8 @@ impl HolderCommitmentTransaction {
                        is_outbound_from_holder: false,
                        counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: channel_pubkeys.clone(), selected_contest_delay: 0 }),
                        funding_outpoint: Some(chain::transaction::OutPoint { txid: Txid::all_zeros(), index: 0 }),
-                       opt_anchors: None
+                       opt_anchors: None,
+                       opt_non_zero_fee_anchors: None,
                };
                let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();
                let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, false, dummy_key.clone(), dummy_key.clone(), keys, 0, &mut htlcs_with_aux, &channel_parameters.as_counterparty_broadcastable());
@@ -1160,6 +1180,8 @@ pub struct CommitmentTransaction {
        htlcs: Vec<HTLCOutputInCommitment>,
        // A boolean that is serialization backwards-compatible
        opt_anchors: Option<()>,
+       // Whether non-zero-fee anchors should be used
+       opt_non_zero_fee_anchors: Option<()>,
        // A cache of the parties' pubkeys required to construct the transaction, see doc for trust()
        keys: TxCreationKeys,
        // For access to the pre-built transaction, see doc for trust()
@@ -1193,6 +1215,7 @@ impl_writeable_tlv_based!(CommitmentTransaction, {
        (10, built, required),
        (12, htlcs, vec_type),
        (14, opt_anchors, option),
+       (16, opt_non_zero_fee_anchors, option),
 });
 
 impl CommitmentTransaction {
@@ -1225,9 +1248,18 @@ impl CommitmentTransaction {
                                transaction,
                                txid
                        },
+                       opt_non_zero_fee_anchors: None,
                }
        }
 
+       /// Use non-zero fee anchors
+       ///
+       /// (C-not exported) due to move, and also not likely to be useful for binding users
+       pub fn with_non_zero_fee_anchors(mut self) -> Self {
+               self.opt_non_zero_fee_anchors = Some(());
+               self
+       }
+
        fn internal_rebuild_transaction(&self, keys: &TxCreationKeys, channel_parameters: &DirectedChannelTransactionParameters, broadcaster_funding_key: &PublicKey, countersignatory_funding_key: &PublicKey) -> Result<BuiltCommitmentTransaction, ()> {
                let (obscured_commitment_transaction_number, txins) = Self::internal_build_inputs(self.commitment_number, channel_parameters);
 
@@ -1266,7 +1298,7 @@ impl CommitmentTransaction {
                        let script = if opt_anchors {
                            get_to_countersignatory_with_anchors_redeemscript(&countersignatory_pubkeys.payment_point).to_v0_p2wsh()
                        } else {
-                           get_p2wpkh_redeemscript(&countersignatory_pubkeys.payment_point)
+                           Payload::p2wpkh(&BitcoinPublicKey::new(countersignatory_pubkeys.payment_point)).unwrap().script_pubkey()
                        };
                        txouts.push((
                                TxOut {
@@ -1492,7 +1524,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
 
                for this_htlc in inner.htlcs.iter() {
                        assert!(this_htlc.transaction_output_index.is_some());
-                       let htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
+                       let htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), self.opt_non_zero_fee_anchors.is_some(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
 
                        let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
 
@@ -1514,7 +1546,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
                // Further, we should never be provided the preimage for an HTLC-Timeout transaction.
                if  this_htlc.offered && preimage.is_some() { unreachable!(); }
 
-               let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
+               let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, self.opt_anchors(), self.opt_non_zero_fee_anchors.is_some(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
 
                let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
 
@@ -1572,18 +1604,12 @@ pub fn get_commitment_transaction_number_obscure_factor(
                | ((res[31] as u64) << 0 * 8)
 }
 
-fn get_p2wpkh_redeemscript(key: &PublicKey) -> Script {
-       Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0)
-               .push_slice(&WPubkeyHash::hash(&key.serialize())[..])
-               .into_script()
-}
-
 #[cfg(test)]
 mod tests {
        use super::CounterpartyCommitmentSecrets;
        use crate::{hex, chain};
        use crate::prelude::*;
-       use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, get_p2wpkh_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
+       use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
        use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
        use crate::util::test_utils;
        use crate::chain::keysinterface::{KeysInterface, BaseSign};
@@ -1591,6 +1617,8 @@ mod tests {
        use bitcoin::hashes::Hash;
        use crate::ln::PaymentHash;
        use bitcoin::hashes::hex::ToHex;
+       use bitcoin::util::address::Payload;
+       use bitcoin::PublicKey as BitcoinPublicKey;
 
        #[test]
        fn test_anchors() {
@@ -1599,8 +1627,8 @@ mod tests {
                let seed = [42; 32];
                let network = Network::Testnet;
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
-               let signer = keys_provider.get_channel_signer(false, 3000);
-               let counterparty_signer = keys_provider.get_channel_signer(false, 3000);
+               let signer = keys_provider.derive_channel_signer(3000, keys_provider.generate_channel_keys_id(false, 1_000_000, 0));
+               let counterparty_signer = keys_provider.derive_channel_signer(3000, keys_provider.generate_channel_keys_id(true, 1_000_000, 1));
                let delayed_payment_base = &signer.pubkeys().delayed_payment_basepoint;
                let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap();
                let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
@@ -1614,7 +1642,8 @@ mod tests {
                        is_outbound_from_holder: false,
                        counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: counterparty_pubkeys.clone(), selected_contest_delay: 0 }),
                        funding_outpoint: Some(chain::transaction::OutPoint { txid: Txid::all_zeros(), index: 0 }),
-                       opt_anchors: None
+                       opt_anchors: None,
+                       opt_non_zero_fee_anchors: None,
                };
 
                let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();
@@ -1629,7 +1658,7 @@ mod tests {
                        &mut htlcs_with_aux, &channel_parameters.as_holder_broadcastable()
                );
                assert_eq!(tx.built.transaction.output.len(), 2);
-               assert_eq!(tx.built.transaction.output[1].script_pubkey, get_p2wpkh_redeemscript(&counterparty_pubkeys.payment_point));
+               assert_eq!(tx.built.transaction.output[1].script_pubkey, Payload::p2wpkh(&BitcoinPublicKey::new(counterparty_pubkeys.payment_point)).unwrap().script_pubkey());
 
                // Generate broadcaster and counterparty outputs as well as two anchors
                let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
@@ -1695,9 +1724,9 @@ mod tests {
                assert_eq!(tx.built.transaction.output[0].script_pubkey, get_htlc_redeemscript(&received_htlc, false, &keys).to_v0_p2wsh());
                assert_eq!(tx.built.transaction.output[1].script_pubkey, get_htlc_redeemscript(&offered_htlc, false, &keys).to_v0_p2wsh());
                assert_eq!(get_htlc_redeemscript(&received_htlc, false, &keys).to_v0_p2wsh().to_hex(),
-                                  "002085cf52e41ba7c099a39df504e7b61f6de122971ceb53b06731876eaeb85e8dc5");
+                                  "0020e43a7c068553003fe68fcae424fb7b28ec5ce48cd8b6744b3945631389bad2fb");
                assert_eq!(get_htlc_redeemscript(&offered_htlc, false, &keys).to_v0_p2wsh().to_hex(),
-                                  "002049f0736bb335c61a04d2623a24df878a7592a3c51fa7258d41b2c85318265e73");
+                                  "0020215d61bba56b19e9eadb6107f5a85d7f99c40f65992443f69229c290165bc00d");
 
                // Generate broadcaster output and received and offered HTLC outputs,  with anchors
                channel_parameters.opt_anchors = Some(());
@@ -1714,9 +1743,9 @@ mod tests {
                assert_eq!(tx.built.transaction.output[2].script_pubkey, get_htlc_redeemscript(&received_htlc, true, &keys).to_v0_p2wsh());
                assert_eq!(tx.built.transaction.output[3].script_pubkey, get_htlc_redeemscript(&offered_htlc, true, &keys).to_v0_p2wsh());
                assert_eq!(get_htlc_redeemscript(&received_htlc, true, &keys).to_v0_p2wsh().to_hex(),
-                                  "002067114123af3f95405bae4fd930fc95de03e3c86baaee8b2dd29b43dd26cf613c");
+                                  "0020b70d0649c72b38756885c7a30908d912a7898dd5d79457a7280b8e9a20f3f2bc");
                assert_eq!(get_htlc_redeemscript(&offered_htlc, true, &keys).to_v0_p2wsh().to_hex(),
-                                  "0020a06e3b0d4fcf704f2b9c41e16a70099e39989466c3142b8573a1154542f28f57");
+                                  "002087a3faeb1950a469c0e2db4a79b093a41b9526e5a6fc6ef5cb949bde3be379c7");
        }
 
        #[test]