Merge pull request #620 from TheBlueMatt/2020-05-pre-bindings-cleanups
[rust-lightning] / lightning / src / ln / channelmonitor.rs
index 2a873f6b7d305f19836d98dfe4e0e155f27d141c..6d10fdb4f05f049d2d035873d1b986514a0335b4 100644 (file)
@@ -149,66 +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 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys, T: De
        }
 }
 
-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,16 +370,63 @@ struct LocalSignedTx {
        htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
 }
 
-/// Cache remote basepoint to compute any transaction on
-/// remote outputs, either justice or preimage/timeout transactions.
+/// 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 RemoteTxCache {
+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
@@ -747,7 +736,7 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
        current_remote_commitment_txid: Option<Txid>,
        prev_remote_commitment_txid: Option<Txid>,
 
-       remote_tx_cache: RemoteTxCache,
+       remote_tx_cache: RemoteCommitmentTransaction,
        funding_redeemscript: Script,
        channel_value_satoshis: u64,
        // first is the idx of the first of the two revocation points
@@ -823,6 +812,70 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
        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
@@ -904,17 +957,7 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
                self.current_remote_commitment_txid.write(writer)?;
                self.prev_remote_commitment_txid.write(writer)?;
 
-               self.remote_tx_cache.remote_delayed_payment_base_key.write(writer)?;
-               self.remote_tx_cache.remote_htlc_base_key.write(writer)?;
-               writer.write_all(&byte_utils::be16_to_array(self.remote_tx_cache.on_remote_tx_csv))?;
-               writer.write_all(&byte_utils::be64_to_array(self.remote_tx_cache.per_htlc.len() as u64))?;
-               for (ref txid, ref htlcs) in self.remote_tx_cache.per_htlc.iter() {
-                       writer.write_all(&txid[..])?;
-                       writer.write_all(&byte_utils::be64_to_array(htlcs.len() as u64))?;
-                       for &ref htlc in htlcs.iter() {
-                               htlc.write(writer)?;
-                       }
-               }
+               self.remote_tx_cache.write(writer)?;
                self.funding_redeemscript.write(writer)?;
                self.channel_value_satoshis.write(writer)?;
 
@@ -1079,7 +1122,7 @@ impl<ChanSigner: ChannelKeys> 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 remote_tx_cache = RemoteTxCache { 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 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);
 
@@ -2162,7 +2205,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                        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 },
                                        output: outp.clone(),
                                        key_derivation_params: self.keys.key_derivation_params(),
@@ -2237,31 +2280,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for (BlockHash, ChannelMonitor
                let current_remote_commitment_txid = Readable::read(reader)?;
                let prev_remote_commitment_txid = Readable::read(reader)?;
 
-               let remote_tx_cache = {
-                       let remote_delayed_payment_base_key = Readable::read(reader)?;
-                       let remote_htlc_base_key = Readable::read(reader)?;
-                       let on_remote_tx_csv: u16 = Readable::read(reader)?;
-                       let per_htlc_len: u64 = Readable::read(reader)?;
-                       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(reader)?;
-                               let htlcs_count: u64 = Readable::read(reader)?;
-                               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(reader)?;
-                                       htlcs.push(htlc);
-                               }
-                               if let Some(_) = per_htlc.insert(txid, htlcs) {
-                                       return Err(DecodeError::InvalidValue);
-                               }
-                       }
-                       RemoteTxCache {
-                               remote_delayed_payment_base_key,
-                               remote_htlc_base_key,
-                               on_remote_tx_csv,
-                               per_htlc,
-                       }
-               };
+               let remote_tx_cache = Readable::read(reader)?;
                let funding_redeemscript = Readable::read(reader)?;
                let channel_value_satoshis = Readable::read(reader)?;