Make sure individual mutexes are constructed on different lines
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index a26866497fcc1df9d405aac495414c02cdfd969d..a664c7c794efe019dd82e909c132c1fd839b9ccf 100644 (file)
@@ -49,7 +49,7 @@ use crate::chain::onchaintx::OnchainTxHandler;
 use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use crate::chain::Filter;
 use crate::util::logger::Logger;
-use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
+use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
 use crate::util::byte_utils;
 use crate::util::events::Event;
 #[cfg(anchors)]
@@ -60,7 +60,7 @@ use core::{cmp, mem};
 use crate::io::{self, Error};
 use core::convert::TryInto;
 use core::ops::Deref;
-use crate::sync::Mutex;
+use crate::sync::{Mutex, LockTestExt};
 
 /// An update generated by the underlying channel itself which contains some new information the
 /// [`ChannelMonitor`] should be made aware of.
@@ -314,8 +314,8 @@ impl Readable for CounterpartyCommitmentParameters {
                                }
                        }
 
-                       let mut counterparty_delayed_payment_base_key = OptionDeserWrapper(None);
-                       let mut counterparty_htlc_base_key = OptionDeserWrapper(None);
+                       let mut counterparty_delayed_payment_base_key = RequiredWrapper(None);
+                       let mut counterparty_htlc_base_key = RequiredWrapper(None);
                        let mut on_counterparty_tx_csv: u16 = 0;
                        read_tlv_fields!(r, {
                                (0, counterparty_delayed_payment_base_key, required),
@@ -454,19 +454,15 @@ impl MaybeReadable for OnchainEventEntry {
                let mut transaction = None;
                let mut block_hash = None;
                let mut height = 0;
-               let mut event = None;
+               let mut event = UpgradableRequired(None);
                read_tlv_fields!(reader, {
                        (0, txid, required),
                        (1, transaction, option),
                        (2, height, required),
                        (3, block_hash, option),
-                       (4, event, ignorable),
+                       (4, event, upgradable_required),
                });
-               if let Some(ev) = event {
-                       Ok(Some(Self { txid, transaction, height, block_hash, event: ev }))
-               } else {
-                       Ok(None)
-               }
+               Ok(Some(Self { txid, transaction, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
        }
 }
 
@@ -848,8 +844,6 @@ pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
 
        /// The node_id of our counterparty
        counterparty_node_id: Option<PublicKey>,
-
-       secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
 }
 
 /// Transaction outputs to watch for on-chain spends.
@@ -857,9 +851,13 @@ pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
 
 impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> where Signer: PartialEq {
        fn eq(&self, other: &Self) -> bool {
-               let inner = self.inner.lock().unwrap();
-               let other = other.inner.lock().unwrap();
-               inner.eq(&other)
+               // We need some kind of total lockorder. Absent a better idea, we sort by position in
+               // memory and take locks in that order (assuming that we can't move within memory while a
+               // lock is held).
+               let ord = ((self as *const _) as usize) < ((other as *const _) as usize);
+               let a = if ord { self.inner.unsafe_well_ordered_double_lock_self() } else { other.inner.unsafe_well_ordered_double_lock_self() };
+               let b = if ord { other.inner.unsafe_well_ordered_double_lock_self() } else { self.inner.unsafe_well_ordered_double_lock_self() };
+               a.eq(&b)
        }
 }
 
@@ -1091,7 +1089,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
 
                let onchain_tx_handler =
                        OnchainTxHandler::new(destination_script.clone(), keys,
-                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx.clone());
+                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx);
 
                let mut outputs_to_watch = HashMap::new();
                outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
@@ -1147,8 +1145,6 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
 
                        best_block,
                        counterparty_node_id: Some(counterparty_node_id),
-
-                       secp_ctx,
                })
        }
 
@@ -2463,9 +2459,9 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                if commitment_number >= self.get_min_seen_secret() {
                        let secret = self.get_secret(commitment_number).unwrap();
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
-                       let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
-                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
+                       let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
+                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx, &PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
 
                        let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_commitment_params.on_counterparty_tx_csv, &delayed_key);
                        let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
@@ -2578,8 +2574,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
 
                if let Some(transaction) = tx {
                        let revocation_pubkey = chan_utils::derive_public_revocation_key(
-                               &self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx,
+                               &self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx,
                                &per_commitment_point,
                                &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
                        let revokeable_p2wsh = chan_utils::get_revokeable_redeemscript(&revocation_pubkey,
@@ -2636,7 +2632,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        Ok(key) => key,
                        Err(_) => return (Vec::new(), None)
                };
-               let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
+               let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
 
                let htlc_txid = tx.txid();
                let mut claimable_outpoints = vec![];
@@ -3882,9 +3878,6 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
                        (13, spendable_txids_confirmed, vec_type),
                });
 
-               let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
-
                Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
                        latest_update_id,
                        commitment_transaction_number_obscure_factor,
@@ -3936,8 +3929,6 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
 
                        best_block,
                        counterparty_node_id,
-
-                       secp_ctx,
                })))
        }
 }
@@ -4079,7 +4070,10 @@ mod tests {
        fn test_prune_preimages() {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(TestLogger::new());
-               let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
+               let broadcaster = Arc::new(TestBroadcaster {
+                       txn_broadcasted: Mutex::new(Vec::new()),
+                       blocks: Arc::new(Mutex::new(Vec::new()))
+               });
                let fee_estimator = TestFeeEstimator { sat_per_kw: Mutex::new(253) };
 
                let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
@@ -4164,7 +4158,7 @@ mod tests {
                // Prune with one old state and a holder commitment tx holding a few overlaps with the
                // old state.
                let shutdown_pubkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
-               let best_block = BestBlock::from_genesis(Network::Testnet);
+               let best_block = BestBlock::from_network(Network::Testnet);
                let monitor = ChannelMonitor::new(Secp256k1::new(), keys,
                                                  Some(ShutdownScript::new_p2wpkh_from_pubkey(shutdown_pubkey).into_inner()), 0, &Script::new(),
                                                  (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),