Merge pull request #662 from lightning-signer/compat5
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Tue, 11 Aug 2020 16:10:05 +0000 (09:10 -0700)
committerGitHub <noreply@github.com>
Tue, 11 Aug 2020 16:10:05 +0000 (09:10 -0700)
Export various fields and structures

lightning/Cargo.toml
lightning/src/chain/keysinterface.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channelmonitor.rs
lightning/src/ln/onchaintx.rs
lightning/src/util/enforcing_trait_impls.rs

index e1b9462668b1ac8f9348a479f918f3be11581a51..20a6460d62dfec24bfe84d7aaaf823395e5912fd 100644 (file)
@@ -18,6 +18,9 @@ max_level_error = []
 max_level_warn = []
 max_level_info = []
 max_level_debug = []
+# Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling).
+# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
+unsafe_revoked_tx_signing = []
 
 [dependencies]
 bitcoin = "0.23"
index 0a4366e881fa743af704a8b70c2d5cc23c1f7a05..fbc6c9bc6e6c673ca4d8f2555bd41d630b312cd7 100644 (file)
@@ -247,7 +247,7 @@ pub trait ChannelKeys : Send+Clone {
        /// transactions which will be broadcasted later, after the channel has moved on to a newer
        /// state. Thus, needs its own method as sign_local_commitment may enforce that we only ever
        /// get called once.
-       #[cfg(test)]
+       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
 
        /// Create a signature for each HTLC transaction spending a local commitment transaction.
@@ -508,7 +508,7 @@ impl ChannelKeys for InMemoryChannelKeys {
                Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
        }
 
-       #[cfg(test)]
+       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
                let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
                let remote_channel_pubkeys = &self.accepted_channel_data.as_ref().expect("must accept before signing").remote_channel_pubkeys;
index c655e120de53a7bae3ce8f95afbdea072cd4e57f..8a4b3982b7ff3863398d8518b172b45e604ab279 100644 (file)
@@ -599,11 +599,26 @@ impl LocalCommitmentTransaction {
        }
 
        /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction,
-       /// remote signature and both parties keys
-       pub(crate) fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u32, htlc_data: Vec<(HTLCOutputInCommitment, Option<Signature>)>) -> LocalCommitmentTransaction {
+       /// remote signature and both parties keys.
+       ///
+       /// The unsigned transaction outputs must be consistent with htlc_data.  This function
+       /// only checks that the shape and amounts are consistent, but does not check the scriptPubkey.
+       pub fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u32, htlc_data: Vec<(HTLCOutputInCommitment, Option<Signature>)>) -> LocalCommitmentTransaction {
                if unsigned_tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); }
                if unsigned_tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); }
 
+               for htlc in &htlc_data {
+                       if let Some(index) = htlc.0.transaction_output_index {
+                               let out = &unsigned_tx.output[index as usize];
+                               if out.value != htlc.0.amount_msat / 1000 {
+                                       panic!("HTLC at index {} has incorrect amount", index);
+                               }
+                               if !out.script_pubkey.is_v0_p2wsh() {
+                                       panic!("HTLC at index {} doesn't have p2wsh scriptPubkey", index);
+                               }
+                       }
+               }
+
                Self {
                        unsigned_tx,
                        their_sig,
index 28ca19fe0817617d06a5f457c8315de071e85bc7..b69636e0797b5ef9327da195f785474127d92d0f 100644 (file)
@@ -175,10 +175,8 @@ pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys, T: Deref, F: D
         L::Target: Logger,
         C::Target: ChainWatchInterface,
 {
-       #[cfg(test)] // Used in ChannelManager tests to manipulate channels directly
+       /// The monitors
        pub monitors: Mutex<HashMap<Key, ChannelMonitor<ChanSigner>>>,
-       #[cfg(not(test))]
-       monitors: Mutex<HashMap<Key, ChannelMonitor<ChanSigner>>>,
        chain_monitor: C,
        broadcaster: T,
        logger: L,
@@ -1849,7 +1847,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        /// Unsafe test-only version of get_latest_local_commitment_txn used by our test framework
        /// to bypass LocalCommitmentTransaction state update lockdown after signature and generate
        /// revoked commitment transaction.
-       #[cfg(test)]
+       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        pub fn unsafe_get_latest_local_commitment_txn<L: Deref>(&mut self, logger: &L) -> Vec<Transaction> where L::Target: Logger {
                log_trace!(logger, "Getting signed copy of latest local commitment transaction!");
                if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(&self.funding_redeemscript) {
index 01294bba751cc369405181159e40a0c349da3107..e21e8fb2ddf39090cf0a88c701b83ac5a70559ee 100644 (file)
@@ -939,7 +939,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
                }
        }
 
-       #[cfg(test)]
+       #[cfg(any(test, feature="unsafe_revoked_tx_signing"))]
        pub(super) fn get_fully_signed_copy_local_tx(&mut self, funding_redeemscript: &Script) -> Option<Transaction> {
                if let Some(ref mut local_commitment) = self.local_commitment {
                        let local_commitment = local_commitment.clone();
@@ -979,7 +979,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
                htlc_tx
        }
 
-       #[cfg(test)]
+       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        pub(super) fn unsafe_get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
                let latest_had_sigs = self.local_htlc_sigs.is_some();
                let prev_had_sigs = self.prev_local_htlc_sigs.is_some();
index a361973a43a20acf66ca37964a2faa997ec2071e..0d20f7ad4224258161d6bcd79d137baab0a66e02 100644 (file)
@@ -93,7 +93,7 @@ impl ChannelKeys for EnforcingChannelKeys {
                Ok(self.inner.sign_local_commitment(local_commitment_tx, secp_ctx).unwrap())
        }
 
-       #[cfg(test)]
+       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
        fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
                Ok(self.inner.unsafe_sign_local_commitment(local_commitment_tx, secp_ctx).unwrap())
        }