Merge pull request #620 from TheBlueMatt/2020-05-pre-bindings-cleanups
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Thu, 28 May 2020 19:34:42 +0000 (19:34 +0000)
committerGitHub <noreply@github.com>
Thu, 28 May 2020 19:34:42 +0000 (19:34 +0000)
Pre-C Bindings Cleanup

1  2 
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
lightning/src/chain/keysinterface.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmonitor.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/util/macro_logger.rs
lightning/src/util/test_utils.rs

index b5fc307a713a39e93aa5a6ba14cf0a37cc33fefb,3a236cdfb46ea03ff7c5e4dd47ebc3950668d42b..c5c3c9f3a8327f03aae74f0d117b6cc3c0f62cda
@@@ -96,7 -96,9 +96,9 @@@ impl TestChannelMonitor 
                }
        }
  }
- impl channelmonitor::ManyChannelMonitor<EnforcingChannelKeys> for TestChannelMonitor {
+ impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
+       type Keys = EnforcingChannelKeys;
        fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
                let mut ser = VecWriter(Vec::new());
                monitor.write_for_disk(&mut ser).unwrap();
@@@ -164,7 -166,6 +166,7 @@@ impl KeysInterface for KeyProvider 
                        SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
                        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
                        channel_value_satoshis,
 +                      (0, 0),
                ))
        }
  
@@@ -196,7 -197,7 +198,7 @@@ pub fn do_test<Out: test_logger::Output
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
                        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-                       (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap()),
+                       (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0)),
                        monitor)
                } }
        }
                                        let tx = Transaction { version: $chan_id, lock_time: 0, input: Vec::new(), output: vec![TxOut {
                                                value: *channel_value_satoshis, script_pubkey: output_script.clone(),
                                        }]};
-                                       funding_output = OutPoint::new(tx.txid(), 0);
+                                       funding_output = OutPoint { txid: tx.txid(), index: 0 };
                                        $source.funding_transaction_generated(&temporary_channel_id, funding_output);
                                        channel_txn.push(tx);
                                } else { panic!("Wrong event type"); }
diff --combined fuzz/src/full_stack.rs
index d6ea085a782442a2df3e4dfa36a78c9220bec0a8,d8053e48f52f94604bbe16e8455a2718a72c80df..df3b20b038639f299f43987c4bc16545d8bb5100
@@@ -134,10 -134,17 +134,17 @@@ impl<'a> std::hash::Hash for Peer<'a> 
        }
  }
  
+ type ChannelMan = ChannelManager<
+       EnforcingChannelKeys,
+       Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+       Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
+ type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan>, Arc<NetGraphMsgHandler<Arc<ChainWatchInterfaceUtil>, Arc<dyn Logger>>>, Arc<dyn Logger>>;
  struct MoneyLossDetector<'a> {
-       manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
-       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
-       handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>,
+       manager: Arc<ChannelMan>,
+       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<
+               OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+       handler: PeerMan<'a>,
  
        peers: &'a RefCell<[bool; 256]>,
        funding_txn: Vec<Transaction>,
  }
  impl<'a> MoneyLossDetector<'a> {
        pub fn new(peers: &'a RefCell<[bool; 256]>,
-                  manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
+                  manager: Arc<ChannelMan>,
                   monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
-                  handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>) -> Self {
+                  handler: PeerMan<'a>) -> Self {
                MoneyLossDetector {
                        manager,
                        monitor,
@@@ -262,7 -269,6 +269,7 @@@ impl KeysInterface for KeyProvider 
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(),
                                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr],
                                channel_value_satoshis,
 +                              (0, 0),
                        )
                } else {
                        InMemoryChannelKeys::new(
                                SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(),
                                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr],
                                channel_value_satoshis,
 +                              (0, 0),
                        )
                })
        }
@@@ -334,7 -339,7 +341,7 @@@ pub fn do_test(data: &[u8], logger: &Ar
        config.channel_options.fee_proportional_millionths =  slice_to_be32(get_slice!(4));
        config.channel_options.announced_channel = get_slice!(1)[0] != 0;
        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-       let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap());
+       let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0));
        let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
        let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(watch.clone(), Arc::clone(&logger)));
  
                                        let funding_output = 'search_loop: loop {
                                                let funding_txid = tx.txid();
                                                if let None = loss_detector.txids_confirmed.get(&funding_txid) {
-                                                       let outpoint = OutPoint::new(funding_txid, 0);
+                                                       let outpoint = OutPoint { txid: funding_txid, index: 0 };
                                                        for chan in channelmanager.list_channels() {
                                                                if chan.channel_id == outpoint.to_channel_id() {
                                                                        tx.version += 1;
index 4e4d182aa24c2243bf9ef4b89369efb8eefac089,47eafa35a89bdf242c765e9eea0be25ae56e292e..9de35f0ef43d78b2a5c9f63c7fa47d8ecd856bb1
@@@ -49,66 -49,43 +49,66 @@@ pub enum SpendableOutputDescriptor 
                output: TxOut,
        },
        /// An output to a P2WSH script which can be spent with a single signature after a CSV delay.
 -      /// The private key which should be used to sign the transaction is provided, as well as the
 -      /// full witness redeemScript which is hashed in the output script_pubkey.
 +      ///
        /// The witness in the spending input should be:
 -      /// <BIP 143 signature generated with the given key> <empty vector> (MINIMALIF standard rule)
 -      /// <witness_script as provided>
 -      /// Note that the nSequence field in the input must be set to_self_delay (which corresponds to
 -      /// the transaction not being broadcastable until at least to_self_delay blocks after the input
 -      /// confirms).
 +      /// <BIP 143 signature> <empty vector> (MINIMALIF standard rule) <provided witnessScript>
 +      ///
 +      /// Note that the nSequence field in the spending input must be set to to_self_delay
 +      /// (which means the transaction is not broadcastable until at least to_self_delay
 +      /// blocks after the outpoint confirms).
 +      ///
        /// These are generally the result of a "revocable" output to us, spendable only by us unless
 -      /// it is an output from us having broadcast an old state (which should never happen).
 +      /// it is an output from an old state which we broadcast (which should never happen).
 +      ///
 +      /// To derive the delayed_payment key which is used to sign for this input, you must pass the
 +      /// local delayed_payment_base_key (ie the private key which corresponds to the pubkey in
 +      /// ChannelKeys::pubkeys().delayed_payment_basepoint) and the provided per_commitment_point to
 +      /// chan_utils::derive_private_key. The public key can be generated without the secret key
 +      /// using chan_utils::derive_public_key and only the delayed_payment_basepoint which appears in
 +      /// ChannelKeys::pubkeys().
 +      ///
 +      /// To derive the remote_revocation_pubkey provided here (which is used in the witness
 +      /// script generation), you must pass the remote revocation_basepoint (which appears in the
 +      /// call to ChannelKeys::set_remote_channel_pubkeys) and the provided per_commitment point
 +      /// to chan_utils::derive_public_revocation_key.
 +      ///
 +      /// The witness script which is hashed and included in the output script_pubkey may be
 +      /// regenerated by passing the revocation_pubkey (derived as above), our delayed_payment pubkey
 +      /// (derived as above), and the to_self_delay contained here to
 +      /// chan_utils::get_revokeable_redeemscript.
 +      //
 +      // TODO: we need to expose utility methods in KeyManager to do all the relevant derivation.
        DynamicOutputP2WSH {
                /// The outpoint which is spendable
                outpoint: OutPoint,
 -              /// The secret key which must be used to sign the spending transaction
 -              key: SecretKey,
 -              /// The witness redeemScript which is hashed to create the script_pubkey in the given output
 -              witness_script: Script,
 +              /// Per commitment point to derive delayed_payment_key by key holder
 +              per_commitment_point: PublicKey,
                /// The nSequence value which must be set in the spending input to satisfy the OP_CSV in
                /// the witness_script.
                to_self_delay: u16,
                /// The output which is referenced by the given outpoint
                output: TxOut,
 +              /// The channel keys state used to proceed to derivation of signing key. Must
 +              /// be pass to KeysInterface::derive_channel_keys.
 +              key_derivation_params: (u64, u64),
 +              /// The remote_revocation_pubkey used to derive witnessScript
 +              remote_revocation_pubkey: PublicKey
        },
 -      // TODO: Note that because key is now static and exactly what is provided by us, we should drop
 -      // this in favor of StaticOutput:
 -      /// An output to a P2WPKH, spendable exclusively by the given private key.
 +      /// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which
 +      /// corresponds to the public key in ChannelKeys::pubkeys().payment_point).
        /// The witness in the spending input, is, thus, simply:
 -      /// <BIP 143 signature generated with the given key> <public key derived from the given key>
 +      /// <BIP 143 signature> <payment key>
 +      ///
        /// These are generally the result of our counterparty having broadcast the current state,
        /// allowing us to claim the non-HTLC-encumbered outputs immediately.
 -      DynamicOutputP2WPKH {
 +      StaticOutputRemotePayment {
                /// The outpoint which is spendable
                outpoint: OutPoint,
 -              /// The secret key which must be used to sign the spending transaction
 -              key: SecretKey,
                /// The output which is reference by the given outpoint
                output: TxOut,
 +              /// The channel keys state used to proceed to derivation of signing key. Must
 +              /// be pass to KeysInterface::derive_channel_keys.
 +              key_derivation_params: (u64, u64),
        }
  }
  
@@@ -120,22 -97,19 +120,22 @@@ impl Writeable for SpendableOutputDescr
                                outpoint.write(writer)?;
                                output.write(writer)?;
                        },
 -                      &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => {
 +                      &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref remote_revocation_pubkey } => {
                                1u8.write(writer)?;
                                outpoint.write(writer)?;
 -                              key.write(writer)?;
 -                              witness_script.write(writer)?;
 +                              per_commitment_point.write(writer)?;
                                to_self_delay.write(writer)?;
                                output.write(writer)?;
 +                              key_derivation_params.0.write(writer)?;
 +                              key_derivation_params.1.write(writer)?;
 +                              remote_revocation_pubkey.write(writer)?;
                        },
 -                      &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => {
 +                      &SpendableOutputDescriptor::StaticOutputRemotePayment { ref outpoint, ref output, ref key_derivation_params } => {
                                2u8.write(writer)?;
                                outpoint.write(writer)?;
 -                              key.write(writer)?;
                                output.write(writer)?;
 +                              key_derivation_params.0.write(writer)?;
 +                              key_derivation_params.1.write(writer)?;
                        },
                }
                Ok(())
@@@ -151,44 -125,21 +151,22 @@@ impl Readable for SpendableOutputDescri
                        }),
                        1u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WSH {
                                outpoint: Readable::read(reader)?,
 -                              key: Readable::read(reader)?,
 -                              witness_script: Readable::read(reader)?,
 +                              per_commitment_point: Readable::read(reader)?,
                                to_self_delay: Readable::read(reader)?,
                                output: Readable::read(reader)?,
 +                              key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?),
 +                              remote_revocation_pubkey: Readable::read(reader)?,
                        }),
 -                      2u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WPKH {
 +                      2u8 => Ok(SpendableOutputDescriptor::StaticOutputRemotePayment {
                                outpoint: Readable::read(reader)?,
 -                              key: Readable::read(reader)?,
                                output: Readable::read(reader)?,
 +                              key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?),
                        }),
                        _ => Err(DecodeError::InvalidValue),
                }
        }
  }
  
- /// A trait to describe an object which can get user secrets and key material.
- pub trait KeysInterface: Send + Sync {
-       /// A type which implements ChannelKeys which will be returned by get_channel_keys.
-       type ChanKeySigner : ChannelKeys;
-       /// Get node secret key (aka node_id or network_key)
-       fn get_node_secret(&self) -> SecretKey;
-       /// Get destination redeemScript to encumber static protocol exit points.
-       fn get_destination_script(&self) -> Script;
-       /// Get shutdown_pubkey to use as PublicKey at channel closure
-       fn get_shutdown_pubkey(&self) -> PublicKey;
-       /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
-       /// restarted with some stale data!
-       fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner;
-       /// Get a secret and PRNG seed for construting an onion packet
-       fn get_onion_rand(&self) -> (SecretKey, [u8; 32]);
-       /// Get a unique temporary channel id. Channels will be referred to by this until the funding
-       /// transaction is created, at which point they will use the outpoint in the funding
-       /// transaction.
-       fn get_channel_id(&self) -> [u8; 32];
- }
  /// Set of lightning keys needed to operate a channel as described in BOLT 3.
  ///
  /// Signing services could be implemented on a hardware wallet. In this case,
@@@ -233,10 -184,6 +211,10 @@@ pub trait ChannelKeys : Send+Clone 
        fn commitment_seed<'a>(&'a self) -> &'a [u8; 32];
        /// Gets the local channel public keys and basepoints
        fn pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys;
 +      /// Gets arbitrary identifiers describing the set of keys which are provided back to you in
 +      /// some SpendableOutputDescriptor types. These should be sufficient to identify this
 +      /// ChannelKeys object uniquely and lookup or re-derive its keys.
 +      fn key_derivation_params(&self) -> (u64, u64);
  
        /// Create a signature for a remote commitment transaction and associated HTLC transactions.
        ///
        /// return value must contain a signature.
        fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>;
  
 +      /// Create a signature for the given input in a transaction spending an HTLC or commitment
 +      /// transaction output when our counterparty broadcasts an old state.
 +      ///
 +      /// A justice transaction may claim multiples outputs at the same time if timelocks are
 +      /// similar, but only a signature for the input at index `input` should be signed for here.
 +      /// It may be called multiples time for same output(s) if a fee-bump is needed with regards
 +      /// to an upcoming timelock expiration.
 +      ///
 +      /// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
 +      ///
 +      /// per_commitment_key is revocation secret which was provided by our counterparty when they
 +      /// revoked the state which they eventually broadcast. It's not a _local_ secret key and does
 +      /// not allow the spending of any funds by itself (you need our local revocation_secret to do
 +      /// so).
 +      ///
 +      /// htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus
 +      /// changing the format of the witness script (which is committed to in the BIP 143
 +      /// signatures).
 +      ///
 +      /// on_remote_tx_csv is the relative lock-time that that our counterparty would have to set on
 +      /// their transaction were they to spend the same output. It is included in the witness script
 +      /// and thus committed to in the BIP 143 signature.
 +      fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
 +
 +      /// Create a signature for a claiming transaction for a HTLC output on a remote commitment
 +      /// transaction, either offered or received.
 +      ///
 +      /// Such a transaction may claim multiples offered outputs at same time if we know the
 +      /// preimage for each when we create it, but only the input at index `input` should be
 +      /// signed for here. It may be called multiple times for same output(s) if a fee-bump is
 +      /// needed with regards to an upcoming timelock expiration.
 +      ///
 +      /// Witness_script is either a offered or received script as defined in BOLT3 for HTLC
 +      /// outputs.
 +      ///
 +      /// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
 +      ///
 +      /// Per_commitment_point is the dynamic point corresponding to the channel state
 +      /// detected onchain. It has been generated by our counterparty and is used to derive
 +      /// channel state keys, which are then included in the witness script and committed to in the
 +      /// BIP 143 signature.
 +      fn sign_remote_htlc_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
 +
        /// Create a signature for a (proposed) closing transaction.
        ///
        /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have
        fn set_remote_channel_pubkeys(&mut self, channel_points: &ChannelPublicKeys);
  }
  
+ /// A trait to describe an object which can get user secrets and key material.
+ pub trait KeysInterface: Send + Sync {
+       /// A type which implements ChannelKeys which will be returned by get_channel_keys.
+       type ChanKeySigner : ChannelKeys;
+       /// Get node secret key (aka node_id or network_key)
+       fn get_node_secret(&self) -> SecretKey;
+       /// Get destination redeemScript to encumber static protocol exit points.
+       fn get_destination_script(&self) -> Script;
+       /// Get shutdown_pubkey to use as PublicKey at channel closure
+       fn get_shutdown_pubkey(&self) -> PublicKey;
+       /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
+       /// restarted with some stale data!
+       fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner;
+       /// Get a secret and PRNG seed for constructing an onion packet
+       fn get_onion_rand(&self) -> (SecretKey, [u8; 32]);
+       /// Get a unique temporary channel id. Channels will be referred to by this until the funding
+       /// transaction is created, at which point they will use the outpoint in the funding
+       /// transaction.
+       fn get_channel_id(&self) -> [u8; 32];
+ }
  #[derive(Clone)]
  /// A simple implementation of ChannelKeys that just keeps the private keys in memory.
  pub struct InMemoryChannelKeys {
        pub(crate) remote_channel_pubkeys: Option<ChannelPublicKeys>,
        /// The total value of this channel
        channel_value_satoshis: u64,
 +      /// Key derivation parameters
 +      key_derivation_params: (u64, u64),
  }
  
  impl InMemoryChannelKeys {
                delayed_payment_base_key: SecretKey,
                htlc_base_key: SecretKey,
                commitment_seed: [u8; 32],
 -              channel_value_satoshis: u64) -> InMemoryChannelKeys {
 +              channel_value_satoshis: u64,
 +              key_derivation_params: (u64, u64)) -> InMemoryChannelKeys {
                let local_channel_pubkeys =
                        InMemoryChannelKeys::make_local_keys(secp_ctx, &funding_key, &revocation_base_key,
                                                             &payment_key, &delayed_payment_base_key,
                        channel_value_satoshis,
                        local_channel_pubkeys,
                        remote_channel_pubkeys: None,
 +                      key_derivation_params,
                }
        }
  
                        htlc_basepoint: from_secret(&htlc_base_key),
                }
        }
 +
 +      fn remote_pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys { self.remote_channel_pubkeys.as_ref().unwrap() }
  }
  
  impl ChannelKeys for InMemoryChannelKeys {
        fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key }
        fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed }
        fn pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys { &self.local_channel_pubkeys }
 +      fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }
  
        fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
                if commitment_tx.input.len() != 1 { return Err(()); }
                local_commitment_tx.get_htlc_sigs(&self.htlc_base_key, local_csv, secp_ctx)
        }
  
 +      fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
 +              let revocation_key = match chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_key, &self.revocation_base_key) {
 +                      Ok(revocation_key) => revocation_key,
 +                      Err(_) => return Err(())
 +              };
 +              let per_commitment_point = PublicKey::from_secret_key(secp_ctx, &per_commitment_key);
 +              let revocation_pubkey = match chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &self.pubkeys().revocation_basepoint) {
 +                      Ok(revocation_pubkey) => revocation_pubkey,
 +                      Err(_) => return Err(())
 +              };
 +              let witness_script = if let &Some(ref htlc) = htlc {
 +                      let remote_htlcpubkey = match chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.remote_pubkeys().htlc_basepoint) {
 +                              Ok(remote_htlcpubkey) => remote_htlcpubkey,
 +                              Err(_) => return Err(())
 +                      };
 +                      let local_htlcpubkey = match chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint) {
 +                              Ok(local_htlcpubkey) => local_htlcpubkey,
 +                              Err(_) => return Err(())
 +                      };
 +                      chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &remote_htlcpubkey, &local_htlcpubkey, &revocation_pubkey)
 +              } else {
 +                      let remote_delayedpubkey = match chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.remote_pubkeys().delayed_payment_basepoint) {
 +                              Ok(remote_delayedpubkey) => remote_delayedpubkey,
 +                              Err(_) => return Err(())
 +                      };
 +                      chan_utils::get_revokeable_redeemscript(&revocation_pubkey, on_remote_tx_csv, &remote_delayedpubkey)
 +              };
 +              let sighash_parts = bip143::SighashComponents::new(&justice_tx);
 +              let sighash = hash_to_message!(&sighash_parts.sighash_all(&justice_tx.input[input], &witness_script, amount)[..]);
 +              return Ok(secp_ctx.sign(&sighash, &revocation_key))
 +      }
 +
 +      fn sign_remote_htlc_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
 +              if let Ok(htlc_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &self.htlc_base_key) {
 +                      let witness_script = if let Ok(revocation_pubkey) = chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &self.pubkeys().revocation_basepoint) {
 +                              if let Ok(remote_htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.remote_pubkeys().htlc_basepoint) {
 +                                      if let Ok(local_htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint) {
 +                                              chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &remote_htlcpubkey, &local_htlcpubkey, &revocation_pubkey)
 +                                      } else { return Err(()) }
 +                              } else { return Err(()) }
 +                      } else { return Err(()) };
 +                      let sighash_parts = bip143::SighashComponents::new(&htlc_tx);
 +                      let sighash = hash_to_message!(&sighash_parts.sighash_all(&htlc_tx.input[input], &witness_script, amount)[..]);
 +                      return Ok(secp_ctx.sign(&sighash, &htlc_key))
 +              }
 +              Err(())
 +      }
 +
        fn sign_closing_transaction<T: secp256k1::Signing>(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
                if closing_tx.input.len() != 1 { return Err(()); }
                if closing_tx.input[0].witness.len() != 0 { return Err(()); }
@@@ -558,8 -429,6 +558,8 @@@ impl Writeable for InMemoryChannelKeys 
                self.commitment_seed.write(writer)?;
                self.remote_channel_pubkeys.write(writer)?;
                self.channel_value_satoshis.write(writer)?;
 +              self.key_derivation_params.0.write(writer)?;
 +              self.key_derivation_params.1.write(writer)?;
  
                Ok(())
        }
@@@ -580,8 -449,6 +580,8 @@@ impl Readable for InMemoryChannelKeys 
                        InMemoryChannelKeys::make_local_keys(&secp_ctx, &funding_key, &revocation_base_key,
                                                             &payment_key, &delayed_payment_base_key,
                                                             &htlc_base_key);
 +              let params_1 = Readable::read(reader)?;
 +              let params_2 = Readable::read(reader)?;
  
                Ok(InMemoryChannelKeys {
                        funding_key,
                        commitment_seed,
                        channel_value_satoshis,
                        local_channel_pubkeys,
 -                      remote_channel_pubkeys
 +                      remote_channel_pubkeys,
 +                      key_derivation_params: (params_1, params_2),
                })
        }
  }
@@@ -617,9 -483,7 +617,9 @@@ pub struct KeysManager 
        channel_id_master_key: ExtendedPrivKey,
        channel_id_child_index: AtomicUsize,
  
 -      unique_start: Sha256State,
 +      seed: [u8; 32],
 +      starting_time_secs: u64,
 +      starting_time_nanos: u32,
  }
  
  impl KeysManager {
        /// Note that until the 0.1 release there is no guarantee of backward compatibility between
        /// versions. Once the library is more fully supported, the docs will be updated to include a
        /// detailed description of the guarantee.
-       pub fn new(seed: &[u8; 32], network: Network, starting_time_secs: u64, starting_time_nanos: u32) -> KeysManager {
+       pub fn new(seed: &[u8; 32], network: Network, starting_time_secs: u64, starting_time_nanos: u32) -> Self {
                let secp_ctx = Secp256k1::signing_only();
                match ExtendedPrivKey::new_master(network.clone(), seed) {
                        Ok(master_key) => {
                                let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
                                let channel_id_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted");
  
 -                              let mut unique_start = Sha256::engine();
 -                              unique_start.input(&byte_utils::be64_to_array(starting_time_secs));
 -                              unique_start.input(&byte_utils::be32_to_array(starting_time_nanos));
 -                              unique_start.input(seed);
 -
                                KeysManager {
                                        secp_ctx,
                                        node_secret,
                                        channel_id_master_key,
                                        channel_id_child_index: AtomicUsize::new(0),
  
 -                                      unique_start,
 +                                      seed: *seed,
 +                                      starting_time_secs,
 +                                      starting_time_nanos,
                                }
                        },
                        Err(_) => panic!("Your rng is busted"),
                }
        }
 -}
 -
 -impl KeysInterface for KeysManager {
 -      type ChanKeySigner = InMemoryChannelKeys;
 -
 -      fn get_node_secret(&self) -> SecretKey {
 -              self.node_secret.clone()
 -      }
 -
 -      fn get_destination_script(&self) -> Script {
 -              self.destination_script.clone()
 -      }
 -
 -      fn get_shutdown_pubkey(&self) -> PublicKey {
 -              self.shutdown_pubkey.clone()
 +      fn derive_unique_start(&self) -> Sha256State {
 +              let mut unique_start = Sha256::engine();
 +              unique_start.input(&byte_utils::be64_to_array(self.starting_time_secs));
 +              unique_start.input(&byte_utils::be32_to_array(self.starting_time_nanos));
 +              unique_start.input(&self.seed);
 +              unique_start
        }
 +      /// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation
 +      /// parameters.
 +      /// Key derivation parameters are accessible through a per-channel secrets
 +      /// ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of
 +      /// onchain output detection for which a corresponding delayed_payment_key must be derived.
 +      pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params_1: u64, params_2: u64) -> InMemoryChannelKeys {
 +              let chan_id = ((params_1 & 0xFFFF_FFFF_0000_0000) >> 32) as u32;
 +              let mut unique_start = Sha256::engine();
 +              unique_start.input(&byte_utils::be64_to_array(params_2));
 +              unique_start.input(&byte_utils::be32_to_array(params_1 as u32));
 +              unique_start.input(&self.seed);
  
 -      fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> InMemoryChannelKeys {
                // We only seriously intend to rely on the channel_master_key for true secure
                // entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
                // starting_time provided in the constructor) to be unique.
 -              let mut sha = self.unique_start.clone();
 -
 -              let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
 -              let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
 -              sha.input(&child_privkey.private_key.key[..]);
 +              let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id).expect("key space exhausted")).expect("Your RNG is busted");
 +              unique_start.input(&child_privkey.private_key.key[..]);
  
 -              let seed = Sha256::from_engine(sha).into_inner();
 +              let seed = Sha256::from_engine(unique_start).into_inner();
  
                let commitment_seed = {
                        let mut sha = Sha256::engine();
                        delayed_payment_base_key,
                        htlc_base_key,
                        commitment_seed,
 -                      channel_value_satoshis
 +                      channel_value_satoshis,
 +                      (params_1, params_2),
                )
        }
 +}
 +
 +impl KeysInterface for KeysManager {
 +      type ChanKeySigner = InMemoryChannelKeys;
 +
 +      fn get_node_secret(&self) -> SecretKey {
 +              self.node_secret.clone()
 +      }
 +
 +      fn get_destination_script(&self) -> Script {
 +              self.destination_script.clone()
 +      }
 +
 +      fn get_shutdown_pubkey(&self) -> PublicKey {
 +              self.shutdown_pubkey.clone()
 +      }
 +
 +      fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> InMemoryChannelKeys {
 +              let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
 +              let ix_and_nanos: u64 = (child_ix as u64) << 32 | (self.starting_time_nanos as u64);
 +              self.derive_channel_keys(channel_value_satoshis, ix_and_nanos, self.starting_time_secs)
 +      }
  
        fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) {
 -              let mut sha = self.unique_start.clone();
 +              let mut sha = self.derive_unique_start();
  
                let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel);
                let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
        }
  
        fn get_channel_id(&self) -> [u8; 32] {
 -              let mut sha = self.unique_start.clone();
 +              let mut sha = self.derive_unique_start();
  
                let child_ix = self.channel_id_child_index.fetch_add(1, Ordering::AcqRel);
                let child_privkey = self.channel_id_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
index 53a6e25f764cfd6fe75c0aa99abf08d08ea34246,949d008c0d7d23ff69af82e8c80f568814875233..a97a5a6088fd28fb27ac4115d8f3e63edba2570a
@@@ -5,7 -5,8 +5,8 @@@
  use bitcoin::blockdata::script::{Script,Builder};
  use bitcoin::blockdata::opcodes;
  use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, SigHashType};
- use bitcoin::consensus::encode::{self, Decodable, Encodable};
+ use bitcoin::consensus::encode::{Decodable, Encodable};
+ use bitcoin::consensus::encode;
  use bitcoin::util::bip143;
  
  use bitcoin::hashes::{Hash, HashEngine};
@@@ -171,11 -172,8 +172,11 @@@ impl Readable for CounterpartyCommitmen
        }
  }
  
 -/// Derives a per-commitment-transaction private key (eg an htlc key or payment key) from the base
 -/// private key for that type of key and the per_commitment_point (available in TxCreationKeys)
 +/// Derives a per-commitment-transaction private key (eg an htlc key or delayed_payment key)
 +/// from the base secret and the per_commitment_point.
 +///
 +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
 +/// generated (ie our own).
  pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
        let mut sha = Sha256::engine();
        sha.input(&per_commitment_point.serialize());
        Ok(key)
  }
  
 -pub(super) fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
 +/// Derives a per-commitment-transaction public key (eg an htlc key or a delayed_payment key)
 +/// from the base point and the per_commitment_key. This is the public equivalent of
 +/// derive_private_key - using only public keys to derive a public key instead of private keys.
 +///
 +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
 +/// generated (ie our own).
 +pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
        let mut sha = Sha256::engine();
        sha.input(&per_commitment_point.serialize());
        sha.input(&base_point.serialize());
        base_point.combine(&hashkey)
  }
  
 -/// Derives a revocation key from its constituent parts.
 +/// Derives a per-commitment-transaction revocation key from its constituent parts.
 +///
  /// Note that this is infallible iff we trust that at least one of the two input keys are randomly
  /// generated (ie our own).
 -pub(super) fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
 +pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
        let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret);
        let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
  
        Ok(part_a)
  }
  
 -pub(super) fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
 +/// Derives a per-commitment-transaction revocation public key from its constituent parts. This is
 +/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
 +/// public key instead of private keys.
 +///
 +/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
 +/// generated (ie our own).
 +pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
        let rev_append_commit_hash_key = {
                let mut sha = Sha256::engine();
                sha.input(&revocation_base_point.serialize());
@@@ -289,9 -274,9 +290,9 @@@ pub struct ChannelPublicKeys 
        /// on-chain channel lock-in 2-of-2 multisig output.
        pub funding_pubkey: PublicKey,
        /// The base point which is used (with derive_public_revocation_key) to derive per-commitment
 -      /// revocation keys. The per-commitment revocation private key is then revealed by the owner of
 -      /// a commitment transaction so that their counterparty can claim all available funds if they
 -      /// broadcast an old state.
 +      /// revocation keys. This is combined with the per-commitment-secret generated by the
 +      /// counterparty to create a secret which the counterparty can reveal to revoke previous
 +      /// states.
        pub revocation_basepoint: PublicKey,
        /// The public key which receives our immediately spendable primary channel balance in
        /// remote-broadcasted commitment transactions. This key is static across every commitment
@@@ -327,10 -312,9 +328,10 @@@ impl TxCreationKeys 
        }
  }
  
 -/// Gets the "to_local" output redeemscript, ie the script which is time-locked or spendable by
 -/// the revocation key
 -pub(super) fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script {
 +/// A script either spendable by the revocation
 +/// key or the delayed_payment_key and satisfying the relative-locktime OP_CSV constrain.
 +/// Encumbering a `to_local` output on a commitment transaction or 2nd-stage HTLC transactions.
 +pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script {
        Builder::new().push_opcode(opcodes::all::OP_IF)
                      .push_slice(&revocation_key.serialize())
                      .push_opcode(opcodes::all::OP_ELSE)
index b0f8ef9abee0d60441aaf80563098cf43f880bd9,6ddaa8fd8241bde04ef1baff5a2df86167006b95..8d55804f41d62a8c83825f1dc7b02df8f52a10c9
@@@ -1486,7 -1486,7 +1486,7 @@@ impl<ChanSigner: ChannelKeys> Channel<C
                        panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
                }
  
-               let funding_txo = OutPoint::new(msg.funding_txid, msg.funding_output_index);
+               let funding_txo = OutPoint{ txid: msg.funding_txid, index: msg.funding_output_index };
                self.funding_txo = Some(funding_txo.clone());
  
                let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature, logger) {
@@@ -4387,7 -4387,7 +4387,7 @@@ mod tests 
                let tx = Transaction { version: 1, lock_time: 0, input: Vec::new(), output: vec![TxOut {
                        value: 10000000, script_pubkey: output_script.clone(),
                }]};
-               let funding_outpoint = OutPoint::new(tx.txid(), 0);
+               let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
                let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap();
                let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, &&logger).unwrap();
  
                        // These aren't set in the test vectors:
                        [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
                        10_000_000,
 +                      (0, 0)
                );
  
                assert_eq!(PublicKey::from_secret_key(&secp_ctx, chan_keys.funding_key()).serialize()[..],
                chan.their_to_self_delay = 144;
                chan.our_dust_limit_satoshis = 546;
  
-               let funding_info = OutPoint::new(Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
+               let funding_info = OutPoint{ txid: Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), index: 0 };
                chan.funding_txo = Some(funding_info);
  
                let their_pubkeys = ChannelPublicKeys {
index 5db9d17141ce28244d005780a304ca5b2a8b0948,b054258319485be03ee5ddac0aaa4b8500f6d4e5..6d10fdb4f05f049d2d035873d1b986514a0335b4
@@@ -31,7 -31,7 +31,7 @@@ use ln::msgs::DecodeError
  use ln::chan_utils;
  use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, LocalCommitmentTransaction, HTLCType};
  use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
 -use ln::onchaintx::OnchainTxHandler;
 +use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
  use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface, FeeEstimator};
  use chain::transaction::OutPoint;
  use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys};
@@@ -149,66 -149,6 +149,6 @@@ pub struct HTLCUpdate 
  }
  impl_writeable!(HTLCUpdate, 0, { payment_hash, payment_preimage, source });
  
- /// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
- /// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
- /// events to it, while also taking any add/update_monitor events and passing them to some remote
- /// server(s).
- ///
- /// In general, you must always have at least one local copy in memory, which must never fail to
- /// update (as it is responsible for broadcasting the latest state in case the channel is closed),
- /// and then persist it to various on-disk locations. If, for some reason, the in-memory copy fails
- /// to update (eg out-of-memory or some other condition), you must immediately shut down without
- /// taking any further action such as writing the current state to disk. This should likely be
- /// accomplished via panic!() or abort().
- ///
- /// Note that any updates to a channel's monitor *must* be applied to each instance of the
- /// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
- /// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
- /// which we have revoked, allowing our counterparty to claim all funds in the channel!
- ///
- /// User needs to notify implementors of ManyChannelMonitor when a new block is connected or
- /// disconnected using their `block_connected` and `block_disconnected` methods. However, rather
- /// than calling these methods directly, the user should register implementors as listeners to the
- /// BlockNotifier and call the BlockNotifier's `block_(dis)connected` methods, which will notify
- /// all registered listeners in one go.
- pub trait ManyChannelMonitor<ChanSigner: ChannelKeys>: Send + Sync {
-       /// Adds a monitor for the given `funding_txo`.
-       ///
-       /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
-       /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
-       /// callbacks with the funding transaction, or any spends of it.
-       ///
-       /// Further, the implementer must also ensure that each output returned in
-       /// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
-       /// any spends of any of the outputs.
-       ///
-       /// Any spends of outputs which should have been registered which aren't passed to
-       /// ChannelMonitors via block_connected may result in FUNDS LOSS.
-       fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<ChanSigner>) -> Result<(), ChannelMonitorUpdateErr>;
-       /// Updates a monitor for the given `funding_txo`.
-       ///
-       /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
-       /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
-       /// callbacks with the funding transaction, or any spends of it.
-       ///
-       /// Further, the implementer must also ensure that each output returned in
-       /// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
-       /// any spends of any of the outputs.
-       ///
-       /// Any spends of outputs which should have been registered which aren't passed to
-       /// ChannelMonitors via block_connected may result in FUNDS LOSS.
-       fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
-       /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
-       /// with success or failure.
-       ///
-       /// You should probably just call through to
-       /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
-       /// the full list.
-       fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate>;
- }
  /// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
  /// watchtower or watch our own channels.
  ///
@@@ -320,12 -260,14 +260,14 @@@ impl<Key : Send + cmp::Eq + hash::Hash 
        }
  }
  
- impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send, C: Deref + Sync + Send> ManyChannelMonitor<ChanSigner> for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F, L, C>
+ impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send, L: Deref + Sync + Send, C: Deref + Sync + Send> ManyChannelMonitor for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F, L, C>
        where T::Target: BroadcasterInterface,
              F::Target: FeeEstimator,
              L::Target: Logger,
          C::Target: ChainWatchInterface,
  {
+       type Keys = ChanSigner;
        fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<ChanSigner>) -> Result<(), ChannelMonitorUpdateErr> {
                match self.add_monitor_by_key(funding_txo, monitor) {
                        Ok(_) => Ok(()),
@@@ -428,84 -370,24 +370,84 @@@ struct LocalSignedTx 
        htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
  }
  
 +/// We use this to track remote commitment transactions and htlcs outputs and
 +/// use it to generate any justice or 2nd-stage preimage/timeout transactions.
 +#[derive(PartialEq)]
 +struct RemoteCommitmentTransaction {
 +      remote_delayed_payment_base_key: PublicKey,
 +      remote_htlc_base_key: PublicKey,
 +      on_remote_tx_csv: u16,
 +      per_htlc: HashMap<Txid, Vec<HTLCOutputInCommitment>>
 +}
 +
 +impl Writeable for RemoteCommitmentTransaction {
 +      fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
 +              self.remote_delayed_payment_base_key.write(w)?;
 +              self.remote_htlc_base_key.write(w)?;
 +              w.write_all(&byte_utils::be16_to_array(self.on_remote_tx_csv))?;
 +              w.write_all(&byte_utils::be64_to_array(self.per_htlc.len() as u64))?;
 +              for (ref txid, ref htlcs) in self.per_htlc.iter() {
 +                      w.write_all(&txid[..])?;
 +                      w.write_all(&byte_utils::be64_to_array(htlcs.len() as u64))?;
 +                      for &ref htlc in htlcs.iter() {
 +                              htlc.write(w)?;
 +                      }
 +              }
 +              Ok(())
 +      }
 +}
 +impl Readable for RemoteCommitmentTransaction {
 +      fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
 +              let remote_commitment_transaction = {
 +                      let remote_delayed_payment_base_key = Readable::read(r)?;
 +                      let remote_htlc_base_key = Readable::read(r)?;
 +                      let on_remote_tx_csv: u16 = Readable::read(r)?;
 +                      let per_htlc_len: u64 = Readable::read(r)?;
 +                      let mut per_htlc = HashMap::with_capacity(cmp::min(per_htlc_len as usize, MAX_ALLOC_SIZE / 64));
 +                      for _  in 0..per_htlc_len {
 +                              let txid: Txid = Readable::read(r)?;
 +                              let htlcs_count: u64 = Readable::read(r)?;
 +                              let mut htlcs = Vec::with_capacity(cmp::min(htlcs_count as usize, MAX_ALLOC_SIZE / 32));
 +                              for _ in 0..htlcs_count {
 +                                      let htlc = Readable::read(r)?;
 +                                      htlcs.push(htlc);
 +                              }
 +                              if let Some(_) = per_htlc.insert(txid, htlcs) {
 +                                      return Err(DecodeError::InvalidValue);
 +                              }
 +                      }
 +                      RemoteCommitmentTransaction {
 +                              remote_delayed_payment_base_key,
 +                              remote_htlc_base_key,
 +                              on_remote_tx_csv,
 +                              per_htlc,
 +                      }
 +              };
 +              Ok(remote_commitment_transaction)
 +      }
 +}
 +
  /// When ChannelMonitor discovers an onchain outpoint being a step of a channel and that it needs
  /// to generate a tx to push channel state forward, we cache outpoint-solving tx material to build
  /// a new bumped one in case of lenghty confirmation delay
  #[derive(Clone, PartialEq)]
  pub(crate) enum InputMaterial {
        Revoked {
 -              witness_script: Script,
 -              pubkey: Option<PublicKey>,
 -              key: SecretKey,
 -              is_htlc: bool,
 +              per_commitment_point: PublicKey,
 +              remote_delayed_payment_base_key: PublicKey,
 +              remote_htlc_base_key: PublicKey,
 +              per_commitment_key: SecretKey,
 +              input_descriptor: InputDescriptors,
                amount: u64,
 +              htlc: Option<HTLCOutputInCommitment>,
 +              on_remote_tx_csv: u16,
        },
        RemoteHTLC {
 -              witness_script: Script,
 -              key: SecretKey,
 +              per_commitment_point: PublicKey,
 +              remote_delayed_payment_base_key: PublicKey,
 +              remote_htlc_base_key: PublicKey,
                preimage: Option<PaymentPreimage>,
 -              amount: u64,
 -              locktime: u32,
 +              htlc: HTLCOutputInCommitment
        },
        LocalHTLC {
                preimage: Option<PaymentPreimage>,
  impl Writeable for InputMaterial  {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                match self {
 -                      &InputMaterial::Revoked { ref witness_script, ref pubkey, ref key, ref is_htlc, ref amount} => {
 +                      &InputMaterial::Revoked { ref per_commitment_point, ref remote_delayed_payment_base_key, ref remote_htlc_base_key, ref per_commitment_key, ref input_descriptor, ref amount, ref htlc, ref on_remote_tx_csv} => {
                                writer.write_all(&[0; 1])?;
 -                              witness_script.write(writer)?;
 -                              pubkey.write(writer)?;
 -                              writer.write_all(&key[..])?;
 -                              is_htlc.write(writer)?;
 +                              per_commitment_point.write(writer)?;
 +                              remote_delayed_payment_base_key.write(writer)?;
 +                              remote_htlc_base_key.write(writer)?;
 +                              writer.write_all(&per_commitment_key[..])?;
 +                              input_descriptor.write(writer)?;
                                writer.write_all(&byte_utils::be64_to_array(*amount))?;
 +                              htlc.write(writer)?;
 +                              on_remote_tx_csv.write(writer)?;
                        },
 -                      &InputMaterial::RemoteHTLC { ref witness_script, ref key, ref preimage, ref amount, ref locktime } => {
 +                      &InputMaterial::RemoteHTLC { ref per_commitment_point, ref remote_delayed_payment_base_key, ref remote_htlc_base_key, ref preimage, ref htlc} => {
                                writer.write_all(&[1; 1])?;
 -                              witness_script.write(writer)?;
 -                              key.write(writer)?;
 +                              per_commitment_point.write(writer)?;
 +                              remote_delayed_payment_base_key.write(writer)?;
 +                              remote_htlc_base_key.write(writer)?;
                                preimage.write(writer)?;
 -                              writer.write_all(&byte_utils::be64_to_array(*amount))?;
 -                              writer.write_all(&byte_utils::be32_to_array(*locktime))?;
 +                              htlc.write(writer)?;
                        },
                        &InputMaterial::LocalHTLC { ref preimage, ref amount } => {
                                writer.write_all(&[2; 1])?;
@@@ -556,37 -435,31 +498,37 @@@ impl Readable for InputMaterial 
        fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
                let input_material = match <u8 as Readable>::read(reader)? {
                        0 => {
 -                              let witness_script = Readable::read(reader)?;
 -                              let pubkey = Readable::read(reader)?;
 -                              let key = Readable::read(reader)?;
 -                              let is_htlc = Readable::read(reader)?;
 +                              let per_commitment_point = Readable::read(reader)?;
 +                              let remote_delayed_payment_base_key = Readable::read(reader)?;
 +                              let remote_htlc_base_key = Readable::read(reader)?;
 +                              let per_commitment_key = Readable::read(reader)?;
 +                              let input_descriptor = Readable::read(reader)?;
                                let amount = Readable::read(reader)?;
 +                              let htlc = Readable::read(reader)?;
 +                              let on_remote_tx_csv = Readable::read(reader)?;
                                InputMaterial::Revoked {
 -                                      witness_script,
 -                                      pubkey,
 -                                      key,
 -                                      is_htlc,
 -                                      amount
 +                                      per_commitment_point,
 +                                      remote_delayed_payment_base_key,
 +                                      remote_htlc_base_key,
 +                                      per_commitment_key,
 +                                      input_descriptor,
 +                                      amount,
 +                                      htlc,
 +                                      on_remote_tx_csv
                                }
                        },
                        1 => {
 -                              let witness_script = Readable::read(reader)?;
 -                              let key = Readable::read(reader)?;
 +                              let per_commitment_point = Readable::read(reader)?;
 +                              let remote_delayed_payment_base_key = Readable::read(reader)?;
 +                              let remote_htlc_base_key = Readable::read(reader)?;
                                let preimage = Readable::read(reader)?;
 -                              let amount = Readable::read(reader)?;
 -                              let locktime = Readable::read(reader)?;
 +                              let htlc = Readable::read(reader)?;
                                InputMaterial::RemoteHTLC {
 -                                      witness_script,
 -                                      key,
 +                                      per_commitment_point,
 +                                      remote_delayed_payment_base_key,
 +                                      remote_htlc_base_key,
                                        preimage,
 -                                      amount,
 -                                      locktime
 +                                      htlc
                                }
                        },
                        2 => {
@@@ -785,7 -658,7 +727,7 @@@ pub struct ChannelMonitor<ChanSigner: C
        commitment_transaction_number_obscure_factor: u64,
  
        destination_script: Script,
 -      broadcasted_local_revokable_script: Option<(Script, SecretKey, Script)>,
 +      broadcasted_local_revokable_script: Option<(Script, PublicKey, PublicKey)>,
        remote_payment_script: Script,
        shutdown_script: Script,
  
        current_remote_commitment_txid: Option<Txid>,
        prev_remote_commitment_txid: Option<Txid>,
  
 -      their_htlc_base_key: PublicKey,
 -      their_delayed_payment_base_key: PublicKey,
 +      remote_tx_cache: RemoteCommitmentTransaction,
        funding_redeemscript: Script,
        channel_value_satoshis: u64,
        // first is the idx of the first of the two revocation points
        their_cur_revocation_points: Option<(u64, PublicKey, Option<PublicKey>)>,
  
 -      our_to_self_delay: u16,
 -      their_to_self_delay: u16,
 +      on_local_tx_csv: u16,
  
        commitment_secrets: CounterpartyCommitmentSecrets,
        remote_claimable_outpoints: HashMap<Txid, Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>,
        secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
  }
  
+ /// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
+ /// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
+ /// events to it, while also taking any add/update_monitor events and passing them to some remote
+ /// server(s).
+ ///
+ /// In general, you must always have at least one local copy in memory, which must never fail to
+ /// update (as it is responsible for broadcasting the latest state in case the channel is closed),
+ /// and then persist it to various on-disk locations. If, for some reason, the in-memory copy fails
+ /// to update (eg out-of-memory or some other condition), you must immediately shut down without
+ /// taking any further action such as writing the current state to disk. This should likely be
+ /// accomplished via panic!() or abort().
+ ///
+ /// Note that any updates to a channel's monitor *must* be applied to each instance of the
+ /// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
+ /// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
+ /// which we have revoked, allowing our counterparty to claim all funds in the channel!
+ ///
+ /// User needs to notify implementors of ManyChannelMonitor when a new block is connected or
+ /// disconnected using their `block_connected` and `block_disconnected` methods. However, rather
+ /// than calling these methods directly, the user should register implementors as listeners to the
+ /// BlockNotifier and call the BlockNotifier's `block_(dis)connected` methods, which will notify
+ /// all registered listeners in one go.
+ pub trait ManyChannelMonitor: Send + Sync {
+       /// The concrete type which signs for transactions and provides access to our channel public
+       /// keys.
+       type Keys: ChannelKeys;
+       /// Adds a monitor for the given `funding_txo`.
+       ///
+       /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
+       /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
+       /// callbacks with the funding transaction, or any spends of it.
+       ///
+       /// Further, the implementer must also ensure that each output returned in
+       /// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
+       /// any spends of any of the outputs.
+       ///
+       /// Any spends of outputs which should have been registered which aren't passed to
+       /// ChannelMonitors via block_connected may result in FUNDS LOSS.
+       fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor<Self::Keys>) -> Result<(), ChannelMonitorUpdateErr>;
+       /// Updates a monitor for the given `funding_txo`.
+       ///
+       /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
+       /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
+       /// callbacks with the funding transaction, or any spends of it.
+       ///
+       /// Further, the implementer must also ensure that each output returned in
+       /// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
+       /// any spends of any of the outputs.
+       ///
+       /// Any spends of outputs which should have been registered which aren't passed to
+       /// ChannelMonitors via block_connected may result in FUNDS LOSS.
+       fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
+       /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
+       /// with success or failure.
+       ///
+       /// You should probably just call through to
+       /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
+       /// the full list.
+       fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate>;
+ }
  #[cfg(any(test, feature = "fuzztarget"))]
  /// Used only in testing and fuzztarget to check serialization roundtrips don't change the
  /// underlying object
@@@ -884,11 -823,13 +890,11 @@@ impl<ChanSigner: ChannelKeys> PartialE
                        self.funding_info != other.funding_info ||
                        self.current_remote_commitment_txid != other.current_remote_commitment_txid ||
                        self.prev_remote_commitment_txid != other.prev_remote_commitment_txid ||
 -                      self.their_htlc_base_key != other.their_htlc_base_key ||
 -                      self.their_delayed_payment_base_key != other.their_delayed_payment_base_key ||
 +                      self.remote_tx_cache != other.remote_tx_cache ||
                        self.funding_redeemscript != other.funding_redeemscript ||
                        self.channel_value_satoshis != other.channel_value_satoshis ||
                        self.their_cur_revocation_points != other.their_cur_revocation_points ||
 -                      self.our_to_self_delay != other.our_to_self_delay ||
 -                      self.their_to_self_delay != other.their_to_self_delay ||
 +                      self.on_local_tx_csv != other.on_local_tx_csv ||
                        self.commitment_secrets != other.commitment_secrets ||
                        self.remote_claimable_outpoints != other.remote_claimable_outpoints ||
                        self.remote_commitment_txn_on_chain != other.remote_commitment_txn_on_chain ||
@@@ -951,7 -892,8 +957,7 @@@ impl<ChanSigner: ChannelKeys + Writeabl
                self.current_remote_commitment_txid.write(writer)?;
                self.prev_remote_commitment_txid.write(writer)?;
  
 -              writer.write_all(&self.their_htlc_base_key.serialize())?;
 -              writer.write_all(&self.their_delayed_payment_base_key.serialize())?;
 +              self.remote_tx_cache.write(writer)?;
                self.funding_redeemscript.write(writer)?;
                self.channel_value_satoshis.write(writer)?;
  
                        },
                }
  
 -              writer.write_all(&byte_utils::be16_to_array(self.our_to_self_delay))?;
 -              writer.write_all(&byte_utils::be16_to_array(self.their_to_self_delay))?;
 +              writer.write_all(&byte_utils::be16_to_array(self.on_local_tx_csv))?;
  
                self.commitment_secrets.write(writer)?;
  
  
  impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        pub(super) fn new(keys: ChanSigner, shutdown_pubkey: &PublicKey,
 -                      our_to_self_delay: u16, destination_script: &Script, funding_info: (OutPoint, Script),
 -                      their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey,
 -                      their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64,
 +                      on_remote_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script),
 +                      remote_htlc_base_key: &PublicKey, remote_delayed_payment_base_key: &PublicKey,
 +                      on_local_tx_csv: u16, funding_redeemscript: Script, channel_value_satoshis: u64,
                        commitment_transaction_number_obscure_factor: u64,
                        initial_local_commitment_tx: LocalCommitmentTransaction) -> ChannelMonitor<ChanSigner> {
  
                let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
                let remote_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script();
  
 -              let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), their_to_self_delay);
 +              let remote_tx_cache = RemoteCommitmentTransaction { remote_delayed_payment_base_key: *remote_delayed_payment_base_key, remote_htlc_base_key: *remote_htlc_base_key, on_remote_tx_csv, per_htlc: HashMap::new() };
 +
 +              let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), on_local_tx_csv);
  
                let local_tx_sequence = initial_local_commitment_tx.unsigned_tx.input[0].sequence as u64;
                let local_tx_locktime = initial_local_commitment_tx.unsigned_tx.lock_time as u64;
                        current_remote_commitment_txid: None,
                        prev_remote_commitment_txid: None,
  
 -                      their_htlc_base_key: their_htlc_base_key.clone(),
 -                      their_delayed_payment_base_key: their_delayed_payment_base_key.clone(),
 +                      remote_tx_cache,
                        funding_redeemscript,
                        channel_value_satoshis: channel_value_satoshis,
                        their_cur_revocation_points: None,
  
 -                      our_to_self_delay,
 -                      their_to_self_delay,
 +                      on_local_tx_csv,
  
                        commitment_secrets: CounterpartyCommitmentSecrets::new(),
                        remote_claimable_outpoints: HashMap::new(),
                log_trace!(logger, "New potential remote commitment transaction: {}", encode::serialize_hex(unsigned_commitment_tx));
                self.prev_remote_commitment_txid = self.current_remote_commitment_txid.take();
                self.current_remote_commitment_txid = Some(new_txid);
 -              self.remote_claimable_outpoints.insert(new_txid, htlc_outputs);
 +              self.remote_claimable_outpoints.insert(new_txid, htlc_outputs.clone());
                self.current_remote_commitment_number = commitment_number;
                //TODO: Merge this into the other per-remote-transaction output storage stuff
                match self.their_cur_revocation_points {
                                self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None));
                        }
                }
 +              let mut htlcs = Vec::with_capacity(htlc_outputs.len());
 +              for htlc in htlc_outputs {
 +                      if htlc.0.transaction_output_index.is_some() {
 +                              htlcs.push(htlc.0);
 +                      }
 +              }
 +              self.remote_tx_cache.per_htlc.insert(new_txid, htlcs);
        }
  
        /// Informs this monitor of the latest local (ie broadcastable) commitment transaction. The
        /// monitor watches for timeouts and may broadcast it if we approach such a timeout. Thus, it
        /// is important that any clones of this channel monitor (including remote clones) by kept
        /// up-to-date as our local commitment transaction is updated.
 -      /// Panics if set_their_to_self_delay has never been called.
 +      /// Panics if set_on_local_tx_csv has never been called.
        pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), MonitorUpdateError> {
                if self.local_tx_signed {
                        return Err(MonitorUpdateError("A local commitment tx has already been signed, no new local commitment txn can be sent to our counterparty"));
                        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 = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint));
 -                      let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key()));
 -                      let b_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().htlc_basepoint));
 -                      let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_delayed_payment_base_key));
 -                      let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_htlc_base_key));
 +                      let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.remote_tx_cache.remote_delayed_payment_base_key));
  
 -                      let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
 +                      let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.remote_tx_cache.on_remote_tx_csv, &delayed_key);
                        let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
  
                        // First, process non-htlc outputs (to_local & to_remote)
                        for (idx, outp) in tx.output.iter().enumerate() {
                                if outp.script_pubkey == revokeable_p2wsh {
 -                                      let witness_data = InputMaterial::Revoked { witness_script: revokeable_redeemscript.clone(), pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: false, amount: outp.value };
 -                                      claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data});
 +                                      let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: outp.value, htlc: None, on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv};
 +                                      claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data});
                                }
                        }
  
                        if let Some(ref per_commitment_data) = per_commitment_option {
                                for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
                                        if let Some(transaction_output_index) = htlc.transaction_output_index {
 -                                              let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
                                                if transaction_output_index as usize >= tx.output.len() ||
 -                                                              tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
 -                                                              tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
 +                                                              tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
                                                        return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                                }
 -                                              let witness_data = InputMaterial::Revoked { witness_script: expected_script, pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: true, amount: tx.output[transaction_output_index as usize].value };
 +                                              let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, per_commitment_key, input_descriptor: if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, amount: tx.output[transaction_output_index as usize].value, htlc: Some(htlc.clone()), on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv};
                                                claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
                                        }
                                }
                                                if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
                                        } else { None };
                                if let Some(revocation_point) = revocation_point_option {
 -                                      let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().revocation_basepoint));
 -                                      let b_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().htlc_basepoint));
 -                                      let htlc_privkey = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &self.keys.htlc_base_key()));
 -                                      let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.their_htlc_base_key));
 +                                      self.remote_payment_script = {
 +                                              // Note that the Network here is ignored as we immediately drop the address for the
 +                                              // script_pubkey version
 +                                              let payment_hash160 = WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &self.keys.payment_key()).serialize());
 +                                              Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script()
 +                                      };
  
                                        // Then, try to find htlc outputs
                                        for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
                                                if let Some(transaction_output_index) = htlc.transaction_output_index {
 -                                                      let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
                                                        if transaction_output_index as usize >= tx.output.len() ||
 -                                                                      tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
 -                                                                      tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
 +                                                                      tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
                                                                return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                                        }
                                                        let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
                                                        let aggregable = if !htlc.offered { false } else { true };
                                                        if preimage.is_some() || !htlc.offered {
 -                                                              let witness_data = InputMaterial::RemoteHTLC { witness_script: expected_script, key: htlc_privkey, preimage, amount: htlc.amount_msat / 1000, locktime: htlc.cltv_expiry };
 +                                                              let witness_data = InputMaterial::RemoteHTLC { per_commitment_point: *revocation_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, preimage, htlc: htlc.clone() };
                                                                claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
                                                        }
                                                }
                let secret = if let Some(secret) = self.get_secret(commitment_number) { secret } else { return (Vec::new(), None); };
                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 = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint));
 -              let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key()));
 -              let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &self.their_delayed_payment_base_key));
 -              let redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
  
                log_trace!(logger, "Remote HTLC broadcast {}:{}", htlc_txid, 0);
 -              let witness_data = InputMaterial::Revoked { witness_script: redeemscript, pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: false, amount: tx.output[0].value };
 -              let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data });
 +              let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key,  per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: tx.output[0].value, htlc: None, on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv };
 +              let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data });
                (claimable_outpoints, Some((htlc_txid, tx.output.clone())))
        }
  
 -      fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec<ClaimRequest>, Vec<TxOut>, Option<(Script, SecretKey, Script)>) {
 +      fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec<ClaimRequest>, Vec<TxOut>, Option<(Script, PublicKey, PublicKey)>) {
                let mut claim_requests = Vec::with_capacity(local_tx.htlc_outputs.len());
                let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
  
 -              let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay, &local_tx.delayed_payment_key);
 -              let broadcasted_local_revokable_script = if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, &local_tx.per_commitment_point, self.keys.delayed_payment_base_key()) {
 -                      Some((redeemscript.to_v0_p2wsh(), local_delayedkey, redeemscript))
 -              } else { None };
 +              let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.on_local_tx_csv, &local_tx.delayed_payment_key);
 +              let broadcasted_local_revokable_script = Some((redeemscript.to_v0_p2wsh(), local_tx.per_commitment_point.clone(), local_tx.revocation_key.clone()));
  
                for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() {
                        if let Some(transaction_output_index) = htlc.transaction_output_index {
                                if broadcasted_local_revokable_script.0 == outp.script_pubkey {
                                        spendable_output =  Some(SpendableOutputDescriptor::DynamicOutputP2WSH {
                                                outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
 -                                              key: broadcasted_local_revokable_script.1,
 -                                              witness_script: broadcasted_local_revokable_script.2.clone(),
 -                                              to_self_delay: self.their_to_self_delay,
 +                                              per_commitment_point: broadcasted_local_revokable_script.1,
 +                                              to_self_delay: self.on_local_tx_csv,
                                                output: outp.clone(),
 +                                              key_derivation_params: self.keys.key_derivation_params(),
 +                                              remote_revocation_pubkey: broadcasted_local_revokable_script.2.clone(),
                                        });
                                        break;
                                }
                        } else if self.remote_payment_script == outp.script_pubkey {
 -                              spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WPKH {
 +                              spendable_output = Some(SpendableOutputDescriptor::StaticOutputRemotePayment {
                                        outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 },
 -                                      key: self.keys.payment_key().clone(),
                                        output: outp.clone(),
 +                                      key_derivation_params: self.keys.key_derivation_params(),
                                });
                                break;
                        } else if outp.script_pubkey == self.shutdown_script {
@@@ -2253,9 -2199,9 +2259,9 @@@ impl<ChanSigner: ChannelKeys + Readable
                let broadcasted_local_revokable_script = match <u8 as Readable>::read(reader)? {
                        0 => {
                                let revokable_address = Readable::read(reader)?;
 -                              let local_delayedkey = Readable::read(reader)?;
 +                              let per_commitment_point = Readable::read(reader)?;
                                let revokable_script = Readable::read(reader)?;
 -                              Some((revokable_address, local_delayedkey, revokable_script))
 +                              Some((revokable_address, per_commitment_point, revokable_script))
                        },
                        1 => { None },
                        _ => return Err(DecodeError::InvalidValue),
                let current_remote_commitment_txid = Readable::read(reader)?;
                let prev_remote_commitment_txid = Readable::read(reader)?;
  
 -              let their_htlc_base_key = Readable::read(reader)?;
 -              let their_delayed_payment_base_key = Readable::read(reader)?;
 +              let remote_tx_cache = Readable::read(reader)?;
                let funding_redeemscript = Readable::read(reader)?;
                let channel_value_satoshis = Readable::read(reader)?;
  
                        }
                };
  
 -              let our_to_self_delay: u16 = Readable::read(reader)?;
 -              let their_to_self_delay: u16 = Readable::read(reader)?;
 +              let on_local_tx_csv: u16 = Readable::read(reader)?;
  
                let commitment_secrets = Readable::read(reader)?;
  
                        current_remote_commitment_txid,
                        prev_remote_commitment_txid,
  
 -                      their_htlc_base_key,
 -                      their_delayed_payment_base_key,
 +                      remote_tx_cache,
                        funding_redeemscript,
                        channel_value_satoshis,
                        their_cur_revocation_points,
  
 -                      our_to_self_delay,
 -                      their_to_self_delay,
 +                      on_local_tx_csv,
  
                        commitment_secrets,
                        remote_claimable_outpoints,
@@@ -2605,7 -2555,6 +2611,7 @@@ mod tests 
                        SecretKey::from_slice(&[41; 32]).unwrap(),
                        [41; 32],
                        0,
 +                      (0, 0)
                );
  
                // Prune with one old state and a local commitment tx holding a few overlaps with the
index f2ea0c028c39a0ee9ce29e7a2ca5b144fc8f1780,da47556968db1a7c05cb486bace634389b52f7ea..13125a36ddaebdd251cc12293394a8da276980c2
@@@ -822,7 -822,7 +822,7 @@@ fn pre_funding_lock_shutdown_test() 
        nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![tx.clone()]}, 1);
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![tx.clone()]}, 1);
  
-       nodes[0].node.close_channel(&OutPoint::new(tx.txid(), 0).to_channel_id()).unwrap();
+       nodes[0].node.close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
        nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
@@@ -3111,7 -3111,7 +3111,7 @@@ fn test_force_close_fail_back() 
        // Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success..
        {
                let mut monitors = nodes[2].chan_monitor.simple_monitor.monitors.lock().unwrap();
-               monitors.get_mut(&OutPoint::new(Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), 0)).unwrap()
+               monitors.get_mut(&OutPoint{ txid: Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), index: 0 }).unwrap()
                        .provide_payment_preimage(&our_payment_hash, &our_payment_preimage);
        }
        nodes[2].block_notifier.block_connected_checked(&header, 1, &[&tx], &[1]);
@@@ -4265,7 -4265,7 +4265,7 @@@ fn test_manager_serialize_deserialize_i
  }
  
  macro_rules! check_spendable_outputs {
 -      ($node: expr, $der_idx: expr) => {
 +      ($node: expr, $der_idx: expr, $keysinterface: expr, $chan_value: expr) => {
                {
                        let events = $node.chan_monitor.simple_monitor.get_and_clear_pending_events();
                        let mut txn = Vec::new();
                                        Event::SpendableOutputs { ref outputs } => {
                                                for outp in outputs {
                                                        match *outp {
 -                                                              SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => {
 +                                                              SpendableOutputDescriptor::StaticOutputRemotePayment { ref outpoint, ref output, ref key_derivation_params } => {
                                                                        let input = TxIn {
                                                                                previous_output: outpoint.clone(),
                                                                                script_sig: Script::new(),
                                                                                output: vec![outp],
                                                                        };
                                                                        let secp_ctx = Secp256k1::new();
 -                                                                      let remotepubkey = PublicKey::from_secret_key(&secp_ctx, &key);
 +                                                                      let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1);
 +                                                                      let remotepubkey = PublicKey::from_secret_key(&secp_ctx, &keys.payment_key());
                                                                        let witness_script = Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, Network::Testnet).script_pubkey();
                                                                        let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap();
 -                                                                      let remotesig = secp_ctx.sign(&sighash, key);
 +                                                                      let remotesig = secp_ctx.sign(&sighash, &keys.payment_key());
                                                                        spend_tx.input[0].witness.push(remotesig.serialize_der().to_vec());
                                                                        spend_tx.input[0].witness[0].push(SigHashType::All as u8);
                                                                        spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec());
                                                                        txn.push(spend_tx);
                                                                },
 -                                                              SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => {
 +                                                              SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref remote_revocation_pubkey } => {
                                                                        let input = TxIn {
                                                                                previous_output: outpoint.clone(),
                                                                                script_sig: Script::new(),
                                                                                output: vec![outp],
                                                                        };
                                                                        let secp_ctx = Secp256k1::new();
 -                                                                      let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], witness_script, output.value)[..]).unwrap();
 -                                                                      let local_delaysig = secp_ctx.sign(&sighash, key);
 -                                                                      spend_tx.input[0].witness.push(local_delaysig.serialize_der().to_vec());
 -                                                                      spend_tx.input[0].witness[0].push(SigHashType::All as u8);
 -                                                                      spend_tx.input[0].witness.push(vec!());
 -                                                                      spend_tx.input[0].witness.push(witness_script.clone().into_bytes());
 +                                                                      let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1);
 +                                                                      if let Ok(delayed_payment_key) = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, keys.delayed_payment_base_key()) {
 +
 +                                                                              let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key);
 +                                                                              let witness_script = chan_utils::get_revokeable_redeemscript(remote_revocation_pubkey, *to_self_delay, &delayed_payment_pubkey);
 +                                                                              let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap();
 +                                                                              let local_delayedsig = secp_ctx.sign(&sighash, &delayed_payment_key);
 +                                                                              spend_tx.input[0].witness.push(local_delayedsig.serialize_der().to_vec());
 +                                                                              spend_tx.input[0].witness[0].push(SigHashType::All as u8);
 +                                                                              spend_tx.input[0].witness.push(vec!()); //MINIMALIF
 +                                                                              spend_tx.input[0].witness.push(witness_script.clone().into_bytes());
 +                                                                      } else { panic!() }
                                                                        txn.push(spend_tx);
                                                                },
                                                                SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
@@@ -4404,7 -4397,7 +4404,7 @@@ fn test_claim_sizeable_push_msat() 
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
  }
@@@ -4434,7 -4427,7 +4434,7 @@@ fn test_claim_on_remote_sizeable_push_m
        check_added_monitors!(nodes[1], 1);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 2);
        assert_eq!(spend_txn[0], spend_txn[1]);
        check_spends!(spend_txn[0], node_txn[0]);
@@@ -4467,7 -4460,7 +4467,7 @@@ fn test_claim_on_remote_revoked_sizeabl
        nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 3);
        assert_eq!(spend_txn[0], spend_txn[1]); // to_remote output on revoked remote commitment_tx
        check_spends!(spend_txn[0], revoked_local_txn[0]);
@@@ -4518,7 -4511,7 +4518,7 @@@ fn test_static_spendable_outputs_preima
        nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
  }
@@@ -4565,7 -4558,7 +4565,7 @@@ fn test_static_spendable_outputs_timeou
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
        expect_payment_failed!(nodes[1], our_payment_hash, true);
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote (*2), timeout_tx.output (*1)
        check_spends!(spend_txn[2], node_txn[0].clone());
  }
@@@ -4601,7 -4594,7 +4601,7 @@@ fn test_static_spendable_outputs_justic
        nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
  }
@@@ -4656,7 -4649,7 +4656,7 @@@ fn test_static_spendable_outputs_justic
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
        // Check B's ChannelMonitor was able to generate the right spendable output descriptor
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 2);
        check_spends!(spend_txn[0], node_txn[0]);
        check_spends!(spend_txn[1], node_txn[2]);
@@@ -4706,7 -4699,7 +4706,7 @@@ fn test_static_spendable_outputs_justic
        connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
  
        // Check A's ChannelMonitor was able to generate the right spendable output descriptor
 -      let spend_txn = check_spendable_outputs!(nodes[0], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 5); // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking
        assert_eq!(spend_txn[0], spend_txn[1]);
        assert_eq!(spend_txn[0], spend_txn[2]);
@@@ -4976,7 -4969,7 +4976,7 @@@ fn test_dynamic_spendable_outputs_local
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash());
  
        // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 2);
        check_spends!(spend_txn[0], node_txn[0]);
        check_spends!(spend_txn[1], node_txn[1]);
@@@ -5273,86 -5266,13 +5273,86 @@@ fn test_dynamic_spendable_outputs_local
        expect_payment_failed!(nodes[0], our_payment_hash, true);
  
        // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
 -      let spend_txn = check_spendable_outputs!(nodes[0], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 3);
        assert_eq!(spend_txn[0], spend_txn[1]);
        check_spends!(spend_txn[0], local_txn[0]);
        check_spends!(spend_txn[2], htlc_timeout);
  }
  
 +#[test]
 +fn test_key_derivation_params() {
 +      // This test is a copy of test_dynamic_spendable_outputs_local_htlc_timeout_tx, with
 +      // a key manager rotation to test that key_derivation_params returned in DynamicOutputP2WSH
 +      // let us re-derive the channel key set to then derive a delayed_payment_key.
 +
 +      let chanmon_cfgs = create_chanmon_cfgs(3);
 +
 +      // We manually create the node configuration to backup the seed.
 +      let mut rng = thread_rng();
 +      let mut seed = [0; 32];
 +      rng.fill_bytes(&mut seed);
 +      let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
 +      let chan_monitor = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].chain_monitor, &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator);
 +      let node = NodeCfg { chain_monitor: &chanmon_cfgs[0].chain_monitor, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, chan_monitor, keys_manager, node_seed: seed };
 +      let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
 +      node_cfgs.remove(0);
 +      node_cfgs.insert(0, node);
 +
 +      let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
 +      let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 +
 +      // Create some initial channels
 +      // Create a dummy channel to advance index by one and thus test re-derivation correctness
 +      // for node 0
 +      let chan_0 = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::known(), InitFeatures::known());
 +      let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
 +      assert_ne!(chan_0.3.output[0].script_pubkey, chan_1.3.output[0].script_pubkey);
 +
 +      let (_, our_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000);
 +      let local_txn_0 = get_local_commitment_txn!(nodes[0], chan_0.2);
 +      let local_txn_1 = get_local_commitment_txn!(nodes[0], chan_1.2);
 +      assert_eq!(local_txn_1[0].input.len(), 1);
 +      check_spends!(local_txn_1[0], chan_1.3);
 +
 +      // We check funding pubkey are unique
 +      let (from_0_funding_key_0, from_0_funding_key_1) = (PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][36..69]));
 +      let (from_1_funding_key_0, from_1_funding_key_1) = (PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][36..69]));
 +      if from_0_funding_key_0 == from_1_funding_key_0
 +          || from_0_funding_key_0 == from_1_funding_key_1
 +          || from_0_funding_key_1 == from_1_funding_key_0
 +          || from_0_funding_key_1 == from_1_funding_key_1 {
 +              panic!("Funding pubkeys aren't unique");
 +      }
 +
 +      // Timeout HTLC on A's chain and so it can generate a HTLC-Timeout tx
 +      let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![local_txn_1[0].clone()] }, 200);
 +      check_closed_broadcast!(nodes[0], false);
 +      check_added_monitors!(nodes[0], 1);
 +
 +      let htlc_timeout = {
 +              let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
 +              assert_eq!(node_txn[0].input.len(), 1);
 +              assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
 +              check_spends!(node_txn[0], local_txn_1[0]);
 +              node_txn[0].clone()
 +      };
 +
 +      let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[0].block_notifier.block_connected(&Block { header: header_201, txdata: vec![htlc_timeout.clone()] }, 201);
 +      connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash());
 +      expect_payment_failed!(nodes[0], our_payment_hash, true);
 +
 +      // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
 +      let new_keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
 +      let spend_txn = check_spendable_outputs!(nodes[0], 1, new_keys_manager, 100000);
 +      assert_eq!(spend_txn.len(), 3);
 +      assert_eq!(spend_txn[0], spend_txn[1]);
 +      check_spends!(spend_txn[0], local_txn_1[0]);
 +      check_spends!(spend_txn[2], htlc_timeout);
 +}
 +
  #[test]
  fn test_static_output_closing_tx() {
        let chanmon_cfgs = create_chanmon_cfgs(2);
        nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0);
        connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[0], 2);
 +      let spend_txn = check_spendable_outputs!(nodes[0], 2, node_cfgs[0].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], closing_tx);
  
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0);
        connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 2);
 +      let spend_txn = check_spendable_outputs!(nodes[1], 2, node_cfgs[1].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], closing_tx);
  }
@@@ -6980,7 -6900,7 +6980,7 @@@ fn test_upfront_shutdown_script() 
        // We test that in case of peer committing upfront to a script, if it changes at closing, we refuse to sign
        let flags = InitFeatures::known();
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
-       nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+       nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
        let mut node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
        node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
        // Test we enforce upfront_scriptpbukey if by providing a diffrent one at closing that  we disconnect peer
  
        // We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
-       nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+       nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
        let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
        // We test that in case of peer committing upfront to a script, if it oesn't change at closing, we sign
        nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
        // We test that if case of peer non-signaling we don't enforce committed script at channel opening
        let flags_no = InitFeatures::known().clear_upfront_shutdown_script();
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags_no, flags.clone());
-       nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+       nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
        let mut node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
        node_1_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
        nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_1_shutdown);
        // We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
        // channel smoothly, opt-out is from channel initiator here
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000, flags.clone(), flags.clone());
-       nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+       nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
        let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
        node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
        nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
        //// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
        //// channel smoothly
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags.clone(), flags.clone());
-       nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+       nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
        let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
        node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
        nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
@@@ -7218,7 -7138,7 +7218,7 @@@ fn test_data_loss_protect() 
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
        nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 0);
        connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
 -      let spend_txn = check_spendable_outputs!(nodes[0], 1);
 +      let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
  }
@@@ -7839,7 -7759,7 +7839,7 @@@ fn test_bump_txn_sanitize_tracking_maps
        connect_blocks(&nodes[0].block_notifier, 5, 130,  false, header_130.bitcoin_hash());
        {
                let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap();
-               if let Some(monitor) = monitors.get(&OutPoint::new(chan.3.txid(), 0)) {
+               if let Some(monitor) = monitors.get(&OutPoint { txid: chan.3.txid(), index: 0 }) {
                        assert!(monitor.onchain_tx_handler.pending_claim_requests.is_empty());
                        assert!(monitor.onchain_tx_handler.claimable_outpoints.is_empty());
                }
index e75c2c96e98c9e28dc24170f379c58bb42b6c4ac,009fa73f939e21ace76acb54acd205e56b2fa70a..12d7284661dee0c68c2fc377d9d6451141232a00
@@@ -10,15 -10,16 +10,16 @@@ use bitcoin::secp256k1::key::{SecretKey
  
  use ln::features::InitFeatures;
  use ln::msgs;
- use ln::msgs::ChannelMessageHandler;
+ use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
  use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
 -use util::ser::VecWriter;
 +use util::ser::{VecWriter, Writeable};
  use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
  use ln::wire;
  use ln::wire::Encode;
  use util::byte_utils;
  use util::events::{MessageSendEvent, MessageSendEventsProvider};
  use util::logger::Logger;
+ use routing::network_graph::NetGraphMsgHandler;
  
  use std::collections::{HashMap,hash_map,HashSet,LinkedList};
  use std::sync::{Arc, Mutex};
@@@ -31,13 -32,15 +32,15 @@@ use bitcoin::hashes::sha256::HashEngin
  use bitcoin::hashes::{HashEngine, Hash};
  
  /// Provides references to trait impls which handle different types of messages.
- pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandler {
+ pub struct MessageHandler<CM: Deref, RM: Deref> where
+               CM::Target: ChannelMessageHandler,
+               RM::Target: RoutingMessageHandler {
        /// A message handler which handles messages specific to channels. Usually this is just a
        /// ChannelManager object.
        pub chan_handler: CM,
        /// A message handler which handles messages updating our knowledge of the network channel
        /// graph. Usually this is just a NetGraphMsgHandlerMonitor object.
-       pub route_handler: Arc<msgs::RoutingMessageHandler>,
+       pub route_handler: RM,
  }
  
  /// Provides an object which can be used to send data to and which uniquely identifies a connection
@@@ -83,7 -86,7 +86,7 @@@ pub trait SocketDescriptor : cmp::Eq + 
  pub struct PeerHandleError {
        /// Used to indicate that we probably can't make any future connections to this peer, implying
        /// we should go ahead and force-close any channels we have with it.
-       no_connection_possible: bool,
+       pub no_connection_possible: bool,
  }
  impl fmt::Debug for PeerHandleError {
        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@@@ -171,7 -174,7 +174,7 @@@ fn _check_usize_is_32_or_64() 
  /// lifetimes). Other times you can afford a reference, which is more efficient, in which case
  /// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents
  /// issues such as overly long function definitions.
- pub type SimpleArcPeerManager<SD, M, T, F, L> = Arc<PeerManager<SD, SimpleArcChannelManager<M, T, F, L>, Arc<L>>>;
+ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = Arc<PeerManager<SD, SimpleArcChannelManager<M, T, F, L>, Arc<NetGraphMsgHandler<Arc<C>, Arc<L>>>, Arc<L>>>;
  
  /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
  /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
  /// usage of lightning-net-tokio (since tokio::spawn requires parameters with static lifetimes).
  /// But if this is not necessary, using a reference is more efficient. Defining these type aliases
  /// helps with issues such as long function definitions.
- pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, SD, M, T, F, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e L>;
+ pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e NetGraphMsgHandler<&'g C, &'f L>, &'f L>;
  
  /// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket
  /// events into messages which it passes on to its MessageHandlers.
  /// essentially you should default to using a SimpleRefPeerManager, and use a
  /// SimpleArcPeerManager when you require a PeerManager with a static lifetime, such as when
  /// you're using lightning-net-tokio.
- pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, L: Deref> where CM::Target: msgs::ChannelMessageHandler, L::Target: Logger {
-       message_handler: MessageHandler<CM>,
+ pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> where
+               CM::Target: ChannelMessageHandler,
+               RM::Target: RoutingMessageHandler,
+               L::Target: Logger {
+       message_handler: MessageHandler<CM, RM>,
        peers: Mutex<PeerHolder<Descriptor>>,
        our_node_secret: SecretKey,
        ephemeral_key_midstate: Sha256Engine,
@@@ -213,11 -219,14 +219,14 @@@ macro_rules! encode_msg 
  
  /// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
  /// PeerIds may repeat, but only after socket_disconnected() has been called.
- impl<Descriptor: SocketDescriptor, CM: Deref, L: Deref> PeerManager<Descriptor, CM, L> where CM::Target: msgs::ChannelMessageHandler, L::Target: Logger {
+ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<Descriptor, CM, RM, L> where
+               CM::Target: ChannelMessageHandler,
+               RM::Target: RoutingMessageHandler,
+               L::Target: Logger {
        /// Constructs a new PeerManager with the given message handlers and node_id secret key
        /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
        /// cryptographically secure random bytes.
-       pub fn new(message_handler: MessageHandler<CM>, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L) -> PeerManager<Descriptor, CM, L> {
+       pub fn new(message_handler: MessageHandler<CM, RM>, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
                let mut ephemeral_key_midstate = Sha256::engine();
                ephemeral_key_midstate.input(ephemeral_random_data);
  
                }
        }
  
 +      /// Append a message to a peer's pending outbound/write buffer, and update the map of peers needing sends accordingly.
 +      fn enqueue_message<M: Encode + Writeable>(&self, peers_needing_send: &mut HashSet<Descriptor>, peer: &mut Peer, descriptor: Descriptor, message: &M) {
 +              let mut buffer = VecWriter(Vec::new());
 +              wire::write(message, &mut buffer).unwrap(); // crash if the write failed
 +              let encoded_message = buffer.0;
 +
 +              log_trace!(self.logger, "Enqueueing message of type {} to {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap()));
 +              peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_message[..]));
 +              peers_needing_send.insert(descriptor);
 +      }
 +
        fn do_read_event(&self, peer_descriptor: &mut Descriptor, data: &[u8]) -> Result<bool, PeerHandleError> {
                let pause_read = {
                        let mut peers_lock = self.peers.lock().unwrap();
                                                if peer.pending_read_buffer_pos == peer.pending_read_buffer.len() {
                                                        peer.pending_read_buffer_pos = 0;
  
 -                                                      macro_rules! encode_and_send_msg {
 -                                                              ($msg: expr) => {
 -                                                                      {
 -                                                                              log_trace!(self.logger, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap()));
 -                                                                              peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(&$msg)[..]));
 -                                                                              peers.peers_needing_send.insert(peer_descriptor.clone());
 -                                                                      }
 -                                                              }
 -                                                      }
 -
                                                        macro_rules! try_potential_handleerror {
                                                                ($thing: expr) => {
                                                                        match $thing {
                                                                                                },
                                                                                                msgs::ErrorAction::SendErrorMessage { msg } => {
                                                                                                        log_trace!(self.logger, "Got Err handling message, sending Error message because {}", e.err);
 -                                                                                                      encode_and_send_msg!(msg);
 +                                                                                                      self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg);
                                                                                                        continue;
                                                                                                },
                                                                                        }
                                                                        }
  
                                                                        let resp = msgs::Init { features };
 -                                                                      encode_and_send_msg!(resp);
 +                                                                      self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp);
                                                                },
                                                                NextNoiseStep::ActThree => {
                                                                        let their_node_id = try_potential_handleerror!(peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..]));
                                                                                                        }
  
                                                                                                        let resp = msgs::Init { features };
 -                                                                                                      encode_and_send_msg!(resp);
 +                                                                                                      self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp);
                                                                                                }
  
                                                                                                self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg);
                                                                                        wire::Message::Ping(msg) => {
                                                                                                if msg.ponglen < 65532 {
                                                                                                        let resp = msgs::Pong { byteslen: msg.ponglen };
 -                                                                                                      encode_and_send_msg!(resp);
 +                                                                                                      self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp);
                                                                                                }
                                                                                        },
                                                                                        wire::Message::Pong(_msg) => {
  
  #[cfg(test)]
  mod tests {
-       use bitcoin::secp256k1::Signature;
-       use bitcoin::BitcoinHash;
-       use bitcoin::network::constants::Network;
-       use bitcoin::blockdata::constants::genesis_block;
        use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor};
        use ln::msgs;
-       use ln::features::ChannelFeatures;
        use util::events;
        use util::test_utils;
  
        use rand::{thread_rng, Rng};
  
        use std;
-       use std::cmp::min;
        use std::sync::{Arc, Mutex};
-       use std::sync::atomic::{AtomicUsize, Ordering};
+       use std::sync::atomic::Ordering;
  
        #[derive(Clone)]
        struct FileDescriptor {
  
        struct PeerManagerCfg {
                chan_handler: test_utils::TestChannelMessageHandler,
+               routing_handler: test_utils::TestRoutingMessageHandler,
                logger: test_utils::TestLogger,
        }
  
        fn create_peermgr_cfgs(peer_count: usize) -> Vec<PeerManagerCfg> {
                let mut cfgs = Vec::new();
                for _ in 0..peer_count {
-                       let chan_handler = test_utils::TestChannelMessageHandler::new();
-                       let logger = test_utils::TestLogger::new();
                        cfgs.push(
                                PeerManagerCfg{
-                                       chan_handler,
-                                       logger,
+                                       chan_handler: test_utils::TestChannelMessageHandler::new(),
+                                       logger: test_utils::TestLogger::new(),
+                                       routing_handler: test_utils::TestRoutingMessageHandler::new(),
                                }
                        );
                }
                cfgs
        }
  
-       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>, routing_handlers: Option<&'a Vec<Arc<msgs::RoutingMessageHandler>>>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>> {
+       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>> {
                let mut peers = Vec::new();
                let mut rng = thread_rng();
                let mut ephemeral_bytes = [0; 32];
                rng.fill_bytes(&mut ephemeral_bytes);
  
                for i in 0..peer_count {
-                       let router = if let Some(routers) = routing_handlers { routers[i].clone() } else {
-                               Arc::new(test_utils::TestRoutingMessageHandler::new())
-                       };
                        let node_id = {
                                let mut key_slice = [0;32];
                                rng.fill_bytes(&mut key_slice);
                                SecretKey::from_slice(&key_slice).unwrap()
                        };
-                       let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: router };
+                       let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler };
                        let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, &cfgs[i].logger);
                        peers.push(peer);
                }
                peers
        }
  
-       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
+       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
                let secp_ctx = Secp256k1::new();
                let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
                let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
                (fd_a.clone(), fd_b.clone())
        }
  
-       fn establish_connection_and_read_events<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
+       fn establish_connection_and_read_events<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>) -> (FileDescriptor, FileDescriptor) {
                let (mut fd_a, mut fd_b) = establish_connection(peer_a, peer_b);
                assert_eq!(peer_b.read_event(&mut fd_b, &fd_a.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
                assert_eq!(peer_a.read_event(&mut fd_a, &fd_b.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
                // push a DisconnectPeer event to remove the node flagged by id
                let cfgs = create_peermgr_cfgs(2);
                let chan_handler = test_utils::TestChannelMessageHandler::new();
-               let mut peers = create_network(2, &cfgs, None);
+               let mut peers = create_network(2, &cfgs);
                establish_connection(&peers[0], &peers[1]);
                assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
  
        fn test_timer_tick_occurred() {
                // Create peers, a vector of two peer managers, perform initial set up and check that peers[0] has one Peer.
                let cfgs = create_peermgr_cfgs(2);
-               let peers = create_network(2, &cfgs, None);
+               let peers = create_network(2, &cfgs);
                establish_connection(&peers[0], &peers[1]);
                assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
  
                assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0);
        }
  
-       pub struct TestRoutingMessageHandler {
-               pub chan_upds_recvd: AtomicUsize,
-               pub chan_anns_recvd: AtomicUsize,
-               pub chan_anns_sent: AtomicUsize,
-       }
-       impl TestRoutingMessageHandler {
-               pub fn new() -> Self {
-                       TestRoutingMessageHandler {
-                               chan_upds_recvd: AtomicUsize::new(0),
-                               chan_anns_recvd: AtomicUsize::new(0),
-                               chan_anns_sent: AtomicUsize::new(0),
-                       }
-               }
-       }
-       impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
-               fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, msgs::LightningError> {
-                       Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
-               }
-               fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, msgs::LightningError> {
-                       self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel);
-                       Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
-               }
-               fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, msgs::LightningError> {
-                       self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
-                       Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
-               }
-               fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
-               fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
-                       let mut chan_anns = Vec::new();
-                       const TOTAL_UPDS: u64 = 100;
-                       let end: u64 =  min(starting_point + batch_amount as u64, TOTAL_UPDS - self.chan_anns_sent.load(Ordering::Acquire) as u64);
-                       for i in starting_point..end {
-                               let chan_upd_1 = get_dummy_channel_update(i);
-                               let chan_upd_2 = get_dummy_channel_update(i);
-                               let chan_ann = get_dummy_channel_announcement(i);
-                               chan_anns.push((chan_ann, Some(chan_upd_1), Some(chan_upd_2)));
-                       }
-                       self.chan_anns_sent.fetch_add(chan_anns.len(), Ordering::AcqRel);
-                       chan_anns
-               }
-               fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> {
-                       Vec::new()
-               }
-               fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool {
-                       true
-               }
-       }
-       fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnouncement {
-               use bitcoin::secp256k1::ffi::Signature as FFISignature;
-               let secp_ctx = Secp256k1::new();
-               let network = Network::Testnet;
-               let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap();
-               let node_2_privkey = SecretKey::from_slice(&[41; 32]).unwrap();
-               let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
-               let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
-               let unsigned_ann = msgs::UnsignedChannelAnnouncement {
-                       features: ChannelFeatures::known(),
-                       chain_hash: genesis_block(network).header.bitcoin_hash(),
-                       short_channel_id: short_chan_id,
-                       node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey),
-                       node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey),
-                       bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey),
-                       bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey),
-                       excess_data: Vec::new(),
-               };
-               msgs::ChannelAnnouncement {
-                       node_signature_1: Signature::from(FFISignature::new()),
-                       node_signature_2: Signature::from(FFISignature::new()),
-                       bitcoin_signature_1: Signature::from(FFISignature::new()),
-                       bitcoin_signature_2: Signature::from(FFISignature::new()),
-                       contents: unsigned_ann,
-               }
-       }
-       fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
-               use bitcoin::secp256k1::ffi::Signature as FFISignature;
-               let network = Network::Testnet;
-               msgs::ChannelUpdate {
-                       signature: Signature::from(FFISignature::new()),
-                       contents: msgs::UnsignedChannelUpdate {
-                               chain_hash: genesis_block(network).header.bitcoin_hash(),
-                               short_channel_id: short_chan_id,
-                               timestamp: 0,
-                               flags: 0,
-                               cltv_expiry_delta: 0,
-                               htlc_minimum_msat: 0,
-                               fee_base_msat: 0,
-                               fee_proportional_millionths: 0,
-                               excess_data: vec![],
-                       }
-               }
-       }
        #[test]
        fn test_do_attempt_write_data() {
                // Create 2 peers with custom TestRoutingMessageHandlers and connect them.
                let cfgs = create_peermgr_cfgs(2);
-               let mut routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = Vec::new();
-               let mut routing_handlers_concrete: Vec<Arc<TestRoutingMessageHandler>> = Vec::new();
-               for _ in 0..2 {
-                       let routing_handler = Arc::new(TestRoutingMessageHandler::new());
-                       routing_handlers.push(routing_handler.clone());
-                       routing_handlers_concrete.push(routing_handler.clone());
-               }
-               let peers = create_network(2, &cfgs, Some(&routing_handlers));
+               cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release);
+               cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
+               let peers = create_network(2, &cfgs);
  
                // By calling establish_connect, we trigger do_attempt_write_data between
                // the peers. Previously this function would mistakenly enter an infinite loop
  
                // Check that each peer has received the expected number of channel updates and channel
                // announcements.
-               assert_eq!(routing_handlers_concrete[0].clone().chan_upds_recvd.load(Ordering::Acquire), 100);
-               assert_eq!(routing_handlers_concrete[0].clone().chan_anns_recvd.load(Ordering::Acquire), 50);
-               assert_eq!(routing_handlers_concrete[1].clone().chan_upds_recvd.load(Ordering::Acquire), 100);
-               assert_eq!(routing_handlers_concrete[1].clone().chan_anns_recvd.load(Ordering::Acquire), 50);
+               assert_eq!(cfgs[0].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100);
+               assert_eq!(cfgs[0].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50);
+               assert_eq!(cfgs[1].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100);
+               assert_eq!(cfgs[1].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50);
        }
  
        #[test]
                // Inbound peer 0 requests initial_routing_sync, but outbound peer 1 does not.
                {
                        let cfgs = create_peermgr_cfgs(2);
-                       let routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = vec![
-                               Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()),
-                               Arc::new(test_utils::TestRoutingMessageHandler::new()),
-                       ];
-                       let peers = create_network(2, &cfgs, Some(&routing_handlers));
+                       cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release);
+                       let peers = create_network(2, &cfgs);
                        let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]);
  
                        let peer_0 = peers[0].peers.lock().unwrap();
                // Outbound peer 1 requests initial_routing_sync, but inbound peer 0 does not.
                {
                        let cfgs = create_peermgr_cfgs(2);
-                       let routing_handlers: Vec<Arc<msgs::RoutingMessageHandler>> = vec![
-                               Arc::new(test_utils::TestRoutingMessageHandler::new()),
-                               Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()),
-                       ];
-                       let peers = create_network(2, &cfgs, Some(&routing_handlers));
+                       cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
+                       let peers = create_network(2, &cfgs);
                        let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]);
  
                        let peer_0 = peers[0].peers.lock().unwrap();
index 196ba9ea9ea73c19c3b07fdd58d6681fdecd8a88,7594041de7d4cd3a4bc7b4d08d72b9245f17029e..01038646f2b5dcafaee30e059a0c4fa115c369ee
@@@ -43,7 -43,7 +43,7 @@@ macro_rules! log_bytes 
  pub(crate) struct DebugFundingChannelId<'a>(pub &'a Txid, pub u16);
  impl<'a> std::fmt::Display for DebugFundingChannelId<'a> {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
-               for i in OutPoint::new(self.0.clone(), self.1).to_channel_id().iter() {
+               for i in (OutPoint { txid: self.0.clone(), index: self.1 }).to_channel_id().iter() {
                        write!(f, "{:02x}", i)?;
                }
                Ok(())
@@@ -132,7 -132,7 +132,7 @@@ impl<'a> std::fmt::Display for DebugSpe
                        &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, .. } => {
                                write!(f, "DynamicOutputP2WSH {}:{} marked for spending", outpoint.txid, outpoint.vout)?;
                        }
 -                      &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, .. } => {
 +                      &SpendableOutputDescriptor::StaticOutputRemotePayment { ref outpoint, .. } => {
                                write!(f, "DynamicOutputP2WPKH {}:{} marked for spending", outpoint.txid, outpoint.vout)?;
                        }
                }
index 0e9c20252cca9a1147960fc0866edf1f3a2d5d37,e426ec2d340a6967955016352a6b78aa8e09569c..91af4202d28be148a7e333673fbb486089e5a061
@@@ -3,15 -3,16 +3,16 @@@ use chain::chaininterface::{Confirmatio
  use chain::transaction::OutPoint;
  use chain::keysinterface;
  use ln::channelmonitor;
- use ln::features::InitFeatures;
+ use ln::features::{ChannelFeatures, InitFeatures};
  use ln::msgs;
- use ln::msgs::LightningError;
  use ln::channelmonitor::HTLCUpdate;
  use util::enforcing_trait_impls::EnforcingChannelKeys;
  use util::events;
  use util::logger::{Logger, Level, Record};
  use util::ser::{Readable, Writer, Writeable};
  
+ use bitcoin::BitcoinHash;
+ use bitcoin::blockdata::constants::genesis_block;
  use bitcoin::blockdata::transaction::Transaction;
  use bitcoin::blockdata::script::{Builder, Script};
  use bitcoin::blockdata::block::Block;
@@@ -19,11 -20,12 +20,12 @@@ use bitcoin::blockdata::opcodes
  use bitcoin::network::constants::Network;
  use bitcoin::hash_types::{Txid, BlockHash};
  
- use bitcoin::secp256k1::{SecretKey, PublicKey};
+ use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, Signature};
  
  use std::time::{SystemTime, UNIX_EPOCH};
  use std::sync::Mutex;
- use std::mem;
+ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
+ use std::{cmp, mem};
  use std::collections::HashMap;
  
  pub struct TestVecWriter(pub Vec<u8>);
@@@ -66,7 -68,9 +68,9 @@@ impl<'a> TestChannelMonitor<'a> 
                }
        }
  }
- impl<'a> channelmonitor::ManyChannelMonitor<EnforcingChannelKeys> for TestChannelMonitor<'a> {
+ impl<'a> channelmonitor::ManyChannelMonitor for TestChannelMonitor<'a> {
+       type Keys = EnforcingChannelKeys;
        fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
                // At every point where we get a monitor update, we should be able to send a useful monitor
                // to a watchtower and disk...
@@@ -170,41 -174,105 +174,105 @@@ impl events::MessageSendEventsProvider 
        }
  }
  
+ fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnouncement {
+       use bitcoin::secp256k1::ffi::Signature as FFISignature;
+       let secp_ctx = Secp256k1::new();
+       let network = Network::Testnet;
+       let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap();
+       let node_2_privkey = SecretKey::from_slice(&[41; 32]).unwrap();
+       let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
+       let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
+       let unsigned_ann = msgs::UnsignedChannelAnnouncement {
+               features: ChannelFeatures::known(),
+               chain_hash: genesis_block(network).header.bitcoin_hash(),
+               short_channel_id: short_chan_id,
+               node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey),
+               node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey),
+               bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey),
+               bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey),
+               excess_data: Vec::new(),
+       };
+       msgs::ChannelAnnouncement {
+               node_signature_1: Signature::from(FFISignature::new()),
+               node_signature_2: Signature::from(FFISignature::new()),
+               bitcoin_signature_1: Signature::from(FFISignature::new()),
+               bitcoin_signature_2: Signature::from(FFISignature::new()),
+               contents: unsigned_ann,
+       }
+ }
+ fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
+       use bitcoin::secp256k1::ffi::Signature as FFISignature;
+       let network = Network::Testnet;
+       msgs::ChannelUpdate {
+               signature: Signature::from(FFISignature::new()),
+               contents: msgs::UnsignedChannelUpdate {
+                       chain_hash: genesis_block(network).header.bitcoin_hash(),
+                       short_channel_id: short_chan_id,
+                       timestamp: 0,
+                       flags: 0,
+                       cltv_expiry_delta: 0,
+                       htlc_minimum_msat: 0,
+                       fee_base_msat: 0,
+                       fee_proportional_millionths: 0,
+                       excess_data: vec![],
+               }
+       }
+ }
  pub struct TestRoutingMessageHandler {
-       request_full_sync: bool,
+       pub chan_upds_recvd: AtomicUsize,
+       pub chan_anns_recvd: AtomicUsize,
+       pub chan_anns_sent: AtomicUsize,
+       pub request_full_sync: AtomicBool,
  }
  
  impl TestRoutingMessageHandler {
        pub fn new() -> Self {
                TestRoutingMessageHandler {
-                       request_full_sync: false,
+                       chan_upds_recvd: AtomicUsize::new(0),
+                       chan_anns_recvd: AtomicUsize::new(0),
+                       chan_anns_sent: AtomicUsize::new(0),
+                       request_full_sync: AtomicBool::new(false),
                }
        }
-       pub fn set_request_full_sync(mut self) -> Self {
-               self.request_full_sync = true;
-               self
-       }
  }
  impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
-       fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
-               Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+       fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, msgs::LightningError> {
+               Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
        }
-       fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> {
-               Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+       fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, msgs::LightningError> {
+               self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel);
+               Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
        }
-       fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> {
-               Err(LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
+       fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, msgs::LightningError> {
+               self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
+               Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError })
        }
        fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
-       fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
-               Vec::new()
+       fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
+               let mut chan_anns = Vec::new();
+               const TOTAL_UPDS: u64 = 100;
+               let end: u64 = cmp::min(starting_point + batch_amount as u64, TOTAL_UPDS - self.chan_anns_sent.load(Ordering::Acquire) as u64);
+               for i in starting_point..end {
+                       let chan_upd_1 = get_dummy_channel_update(i);
+                       let chan_upd_2 = get_dummy_channel_update(i);
+                       let chan_ann = get_dummy_channel_announcement(i);
+                       chan_anns.push((chan_ann, Some(chan_upd_1), Some(chan_upd_2)));
+               }
+               self.chan_anns_sent.fetch_add(chan_anns.len(), Ordering::AcqRel);
+               chan_anns
        }
        fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> {
                Vec::new()
        }
        fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool {
-               self.request_full_sync
+               self.request_full_sync.load(Ordering::Acquire)
        }
  }
  
@@@ -283,9 -351,6 +351,9 @@@ impl TestKeysInterface 
                        override_channel_id_priv: Mutex::new(None),
                }
        }
 +      pub fn derive_channel_keys(&self, channel_value_satoshis: u64, user_id_1: u64, user_id_2: u64) -> EnforcingChannelKeys {
 +              EnforcingChannelKeys::new(self.backing.derive_channel_keys(channel_value_satoshis, user_id_1, user_id_2))
 +      }
  }
  
  pub struct TestChainWatcher {