X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmonitor.rs;h=b18a49e0107709e886576ca0c704518929674625;hb=676e15910c1a681e5ff2019bc7e53540119ceee5;hp=3c86d7564d0111d8b0f84d2cfad6e7496bb66bd5;hpb=3ea13194e8ad3ea3493ca4ba63cd215eee105feb;p=rust-lightning diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index 3c86d756..b18a49e0 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -19,14 +19,13 @@ use bitcoin::blockdata::opcodes; use bitcoin::consensus::encode; use bitcoin::util::hash::BitcoinHash; -use bitcoin_hashes::Hash; -use bitcoin_hashes::sha256::Hash as Sha256; -use bitcoin_hashes::hash160::Hash as Hash160; -use bitcoin_hashes::sha256d::Hash as Sha256dHash; +use bitcoin::hashes::Hash; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; -use secp256k1::{Secp256k1,Signature}; -use secp256k1::key::{SecretKey,PublicKey}; -use secp256k1; +use bitcoin::secp256k1::{Secp256k1,Signature}; +use bitcoin::secp256k1::key::{SecretKey,PublicKey}; +use bitcoin::secp256k1; use ln::msgs::DecodeError; use ln::chan_utils; @@ -37,11 +36,11 @@ use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInter use chain::transaction::OutPoint; use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys}; use util::logger::Logger; -use util::ser::{ReadableArgs, Readable, MaybeReadable, Writer, Writeable, U48}; +use util::ser::{Readable, MaybeReadable, Writer, Writeable, U48}; use util::{byte_utils, events}; use std::collections::{HashMap, hash_map}; -use std::sync::{Arc,Mutex}; +use std::sync::{Mutex, MutexGuard}; use std::{hash,cmp, mem}; use std::ops::Deref; @@ -210,6 +209,27 @@ pub trait ManyChannelMonitor: Send + Sync { fn get_and_clear_pending_htlcs_updated(&self) -> Vec; } +/// A lock held on a specific ManyChannelMonitor that includes a reference to the current version +/// of a ChannelMonitor contained within. +pub struct ManyChannelMonitorLock<'a, Key, ChanSigner: ChannelKeys> { + lock_ptr: *mut MutexGuard<'a, HashMap>>, + monitor: &'a ChannelMonitor, +} +impl<'a, Key, ChanSigner: ChannelKeys> ::std::ops::Deref for ManyChannelMonitorLock<'a, Key, ChanSigner> { + type Target = ChannelMonitor; + fn deref(&self) -> &ChannelMonitor { + self.monitor + } +} +impl<'a, Key, ChanSigner: ChannelKeys> Drop for ManyChannelMonitorLock<'a, Key, ChanSigner> { + fn drop(&mut self) { + // Dereferencing the lock_ptr is trivially safe here - it is created when this object is + // created, is never null, and is not modified at any point other than creation. + let _ = unsafe { Box::from_raw(self.lock_ptr) }; + // Drop the box, freeing the lock + } +} + /// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a /// watchtower or watch our own channels. /// @@ -221,31 +241,35 @@ pub trait ManyChannelMonitor: Send + Sync { /// /// If you're using this for local monitoring of your own channels, you probably want to use /// `OutPoint` as the key, which will give you a ManyChannelMonitor implementation. -pub struct SimpleManyChannelMonitor +pub struct SimpleManyChannelMonitor where T::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, + C::Target: ChainWatchInterface, { #[cfg(test)] // Used in ChannelManager tests to manipulate channels directly pub monitors: Mutex>>, #[cfg(not(test))] monitors: Mutex>>, - chain_monitor: Arc, + chain_monitor: C, broadcaster: T, - logger: Arc, + logger: L, fee_estimator: F } -impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send> - ChainListener for SimpleManyChannelMonitor +impl + ChainListener for SimpleManyChannelMonitor where T::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, + C::Target: ChainWatchInterface, { fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[u32]) { let block_hash = header.bitcoin_hash(); { let mut monitors = self.monitors.lock().unwrap(); for monitor in monitors.values_mut() { - let txn_outputs = monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster, &*self.fee_estimator); + let txn_outputs = monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster, &*self.fee_estimator, &*self.logger); for (ref txid, ref outputs) in txn_outputs { for (idx, output) in outputs.iter().enumerate() { @@ -260,18 +284,20 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + let block_hash = header.bitcoin_hash(); let mut monitors = self.monitors.lock().unwrap(); for monitor in monitors.values_mut() { - monitor.block_disconnected(disconnected_height, &block_hash, &*self.broadcaster, &*self.fee_estimator); + monitor.block_disconnected(disconnected_height, &block_hash, &*self.broadcaster, &*self.fee_estimator, &*self.logger); } } } -impl SimpleManyChannelMonitor +impl SimpleManyChannelMonitor where T::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, + C::Target: ChainWatchInterface, { /// Creates a new object which can be used to monitor several channels given the chain /// interface with which to register to receive notifications. - pub fn new(chain_monitor: Arc, broadcaster: T, logger: Arc, feeest: F) -> SimpleManyChannelMonitor { + pub fn new(chain_monitor: C, broadcaster: T, logger: L, feeest: F) -> SimpleManyChannelMonitor { let res = SimpleManyChannelMonitor { monitors: Mutex::new(HashMap::new()), chain_monitor, @@ -290,7 +316,7 @@ impl return Err(MonitorUpdateError("Channel monitor for given key is already present")), hash_map::Entry::Vacant(e) => e, }; - log_trace!(self, "Got new Channel Monitor for channel {}", log_bytes!(monitor.funding_info.0.to_channel_id()[..])); + log_trace!(self.logger, "Got new Channel Monitor for channel {}", log_bytes!(monitor.funding_info.0.to_channel_id()[..])); self.chain_monitor.install_watch_tx(&monitor.funding_info.0.txid, &monitor.funding_info.1); self.chain_monitor.install_watch_outpoint((monitor.funding_info.0.txid, monitor.funding_info.0.index as u32), &monitor.funding_info.1); for (txid, outputs) in monitor.get_outputs_to_watch().iter() { @@ -307,17 +333,50 @@ impl { - log_trace!(self, "Updating Channel Monitor for channel {}", log_funding_info!(orig_monitor)); - orig_monitor.update_monitor(update, &self.broadcaster) + log_trace!(self.logger, "Updating Channel Monitor for channel {}", log_funding_info!(orig_monitor)); + orig_monitor.update_monitor(update, &self.broadcaster, &self.logger) }, None => Err(MonitorUpdateError("No such monitor registered")) } } + + /// Gets a reference to the latest copy of a given ChannelMonitor given a &Key, if any has been + /// registered. + /// + /// The returned value contains a lock on this object, and other calls into this object will + /// almost certainly block until the returned value is dropped! + pub fn get_monitor_ref_by_key<'a>(&'a self, key: &Key) -> Option> { + // Rust doesn't natively allow self-referential structs, and the only way to return a + // reference to something inside our Mutex is to return a struct that contains the lock and + // a reference to something pulled out of said lock. + // To avoid this, we have to fall back to some use of unsafe, but luckily its incredibly + // trivial - we simply Box up the MutexGuard and Box::leak() it, ensuring that its sitting + // in our heap without Rust having any reference to drop it. + // Then, we do a map lookup against the raw pointer, either returning a + // ManyChannelMonitorMonRef (which will drop the lock by recreating the Box when it gets + // dropped), or we will recreate the Box immediately and drop the lock before returning + // None. + // + // The returned ManyChannelMonitorMonRef is templated by a lifetime for which &self is + // valid, ensuring this object cannot be dropped until after the returned value is. + let lock = Box::new(self.monitors.lock().unwrap()); + let lock_ptr: *mut MutexGuard>> = Box::leak(lock); + let mon = unsafe { (*lock_ptr).get(key) }; + if let Some(monitor) = mon { + Some(ManyChannelMonitorLock { lock_ptr, monitor }) + } else { + let _ = unsafe { Box::from_raw(lock_ptr) }; + // Drop the lock again + None + } + } } -impl ManyChannelMonitor for SimpleManyChannelMonitor +impl ManyChannelMonitor for SimpleManyChannelMonitor where T::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, + C::Target: ChainWatchInterface, { fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr> { match self.add_monitor_by_key(funding_txo, monitor) { @@ -342,9 +401,11 @@ impl Ma } } -impl events::EventsProvider for SimpleManyChannelMonitor +impl events::EventsProvider for SimpleManyChannelMonitor where T::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, + C::Target: ChainWatchInterface, { fn get_and_clear_pending_events(&self) -> Vec { let mut pending_events = Vec::new(); @@ -383,11 +444,33 @@ pub(crate) const LATENCY_GRACE_PERIOD_BLOCKS: u32 = 3; /// solved by a previous claim tx. What we want to avoid is reorg evicting our claim tx and us not /// keeping bumping another claim tx to solve the outpoint. pub(crate) const ANTI_REORG_DELAY: u32 = 6; +/// Number of blocks before confirmation at which we fail back an un-relayed HTLC or at which we +/// refuse to accept a new HTLC. +/// +/// This is used for a few separate purposes: +/// 1) if we've received an MPP HTLC to us and it expires within this many blocks and we are +/// waiting on additional parts (or waiting on the preimage for any HTLC from the user), we will +/// fail this HTLC, +/// 2) if we receive an HTLC within this many blocks of its expiry (plus one to avoid a race +/// condition with the above), we will fail this HTLC without telling the user we received it, +/// 3) if we are waiting on a connection or a channel state update to send an HTLC to a peer, and +/// that HTLC expires within this many blocks, we will simply fail the HTLC instead. +/// +/// (1) is all about protecting us - we need enough time to update the channel state before we hit +/// CLTV_CLAIM_BUFFER, at which point we'd go on chain to claim the HTLC with the preimage. +/// +/// (2) is the same, but with an additional buffer to avoid accepting an HTLC which is immediately +/// in a race condition between the user connecting a block (which would fail it) and the user +/// providing us the preimage (which would claim it). +/// +/// (3) is about our counterparty - we don't want to relay an HTLC to a counterparty when they may +/// end up force-closing the channel on us to claim it. +pub(crate) const HTLC_FAIL_BACK_BUFFER: u32 = CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS; #[derive(Clone, PartialEq)] struct LocalSignedTx { /// txid of the transaction in tx, just used to make comparison faster - txid: Sha256dHash, + txid: Txid, revocation_key: PublicKey, a_htlc_key: PublicKey, b_htlc_key: PublicKey, @@ -421,7 +504,7 @@ pub(crate) enum InputMaterial { amount: u64, }, Funding { - channel_value: u64, + funding_redeemscript: Script, } } @@ -449,9 +532,9 @@ impl Writeable for InputMaterial { preimage.write(writer)?; writer.write_all(&byte_utils::be64_to_array(*amount))?; }, - &InputMaterial::Funding { ref channel_value } => { + &InputMaterial::Funding { ref funding_redeemscript } => { writer.write_all(&[3; 1])?; - channel_value.write(writer)?; + funding_redeemscript.write(writer)?; } } Ok(()) @@ -498,9 +581,8 @@ impl Readable for InputMaterial { } }, 3 => { - let channel_value = Readable::read(reader)?; InputMaterial::Funding { - channel_value + funding_redeemscript: Readable::read(reader)?, } } _ => return Err(DecodeError::InvalidValue), @@ -569,11 +651,6 @@ pub(super) enum ChannelMonitorUpdateStep { idx: u64, secret: [u8; 32], }, - /// Indicates our channel is likely a stale version, we're closing, but this update should - /// allow us to spend what is ours if our counterparty broadcasts their latest state. - RescueRemoteCommitmentTXInfo { - their_current_per_commitment_point: PublicKey, - }, /// Used to indicate that the no future updates will occur, and likely that the latest local /// commitment transaction(s) should be broadcast, as the channel has been force-closed. ChannelForceClosed { @@ -616,12 +693,8 @@ impl Writeable for ChannelMonitorUpdateStep { idx.write(w)?; secret.write(w)?; }, - &ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { ref their_current_per_commitment_point } => { - 4u8.write(w)?; - their_current_per_commitment_point.write(w)?; - }, &ChannelMonitorUpdateStep::ChannelForceClosed { ref should_broadcast } => { - 5u8.write(w)?; + 4u8.write(w)?; should_broadcast.write(w)?; }, } @@ -671,11 +744,6 @@ impl Readable for ChannelMonitorUpdateStep { }) }, 4u8 => { - Ok(ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { - their_current_per_commitment_point: Readable::read(r)?, - }) - }, - 5u8 => { Ok(ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast: Readable::read(r)? }) @@ -701,13 +769,13 @@ pub struct ChannelMonitor { destination_script: Script, broadcasted_local_revokable_script: Option<(Script, SecretKey, Script)>, - broadcasted_remote_payment_script: Option<(Script, SecretKey)>, + remote_payment_script: Script, shutdown_script: Script, keys: ChanSigner, funding_info: (OutPoint, Script), - current_remote_commitment_txid: Option, - prev_remote_commitment_txid: Option, + current_remote_commitment_txid: Option, + prev_remote_commitment_txid: Option, their_htlc_base_key: PublicKey, their_delayed_payment_base_key: PublicKey, @@ -720,13 +788,13 @@ pub struct ChannelMonitor { their_to_self_delay: u16, commitment_secrets: CounterpartyCommitmentSecrets, - remote_claimable_outpoints: HashMap>)>>, + remote_claimable_outpoints: HashMap>)>>, /// We cannot identify HTLC-Success or HTLC-Timeout transactions by themselves on the chain. /// Nor can we figure out their commitment numbers without the commitment transaction they are /// spending. Thus, in order to claim them via revocation key, we track all the remote /// commitment transactions which we find on-chain, mapping them to the commitment number which /// can be used to derive the revocation key and claim the transactions. - remote_commitment_txn_on_chain: HashMap)>, + remote_commitment_txn_on_chain: HashMap)>, /// Cache used to make pruning of payment_preimages faster. /// Maps payment_hash values to commitment numbers for remote transactions for non-revoked /// remote transactions (ie should remain pretty small). @@ -738,7 +806,7 @@ pub struct ChannelMonitor { // various monitors for one channel being out of sync, and us broadcasting a local // transaction for which we have deleted claim information on some watchtowers. prev_local_signed_commitment_tx: Option, - current_local_signed_commitment_tx: Option, + current_local_commitment_tx: LocalSignedTx, // Used just for ChannelManager to make sure it has the latest channel data during // deserialization @@ -761,24 +829,30 @@ pub struct ChannelMonitor { // interface knows about the TXOs that we want to be notified of spends of. We could probably // be smart and derive them from the above storage fields, but its much simpler and more // Obviously Correct (tm) if we just keep track of them explicitly. - outputs_to_watch: HashMap>, + outputs_to_watch: HashMap>, #[cfg(test)] pub onchain_tx_handler: OnchainTxHandler, #[cfg(not(test))] onchain_tx_handler: OnchainTxHandler, - // Used to detect programming bug due to unsafe monitor update sequence { ChannelForceClosed, LatestLocalCommitmentTXInfo } + // This is set when the Channel[Manager] generated a ChannelMonitorUpdate which indicated the + // channel has been force-closed. After this is set, no further local commitment transaction + // updates may occur, and we panic!() if one is provided. lockdown_from_offchain: bool, + // Set once we've signed a local commitment transaction and handed it over to our + // OnchainTxHandler. After this is set, no future updates to our local commitment transactions + // may occur, and we fail any such monitor updates. + local_tx_signed: bool, + // We simply modify last_block_hash in Channel's block_connected so that serialization is // consistent but hopefully the users' copy handles block_connected in a consistent way. // (we do *not*, however, update them in update_monitor to ensure any local user copies keep // their last_block_hash from its state and not based on updated copies that didn't run through // the full block_connected). - pub(crate) last_block_hash: Sha256dHash, + pub(crate) last_block_hash: BlockHash, secp_ctx: Secp256k1, //TODO: dedup this a bit... - logger: Arc, } #[cfg(any(test, feature = "fuzztarget"))] @@ -790,7 +864,7 @@ impl PartialEq for ChannelMonitor { self.commitment_transaction_number_obscure_factor != other.commitment_transaction_number_obscure_factor || self.destination_script != other.destination_script || self.broadcasted_local_revokable_script != other.broadcasted_local_revokable_script || - self.broadcasted_remote_payment_script != other.broadcasted_remote_payment_script || + self.remote_payment_script != other.remote_payment_script || self.keys.pubkeys() != other.keys.pubkeys() || self.funding_info != other.funding_info || self.current_remote_commitment_txid != other.current_remote_commitment_txid || @@ -809,12 +883,14 @@ impl PartialEq for ChannelMonitor { self.prev_local_signed_commitment_tx != other.prev_local_signed_commitment_tx || self.current_remote_commitment_number != other.current_remote_commitment_number || self.current_local_commitment_number != other.current_local_commitment_number || - self.current_local_signed_commitment_tx != other.current_local_signed_commitment_tx || + self.current_local_commitment_tx != other.current_local_commitment_tx || self.payment_preimages != other.payment_preimages || self.pending_htlcs_updated != other.pending_htlcs_updated || self.pending_events.len() != other.pending_events.len() || // We trust events to round-trip properly self.onchain_events_waiting_threshold_conf != other.onchain_events_waiting_threshold_conf || - self.outputs_to_watch != other.outputs_to_watch + self.outputs_to_watch != other.outputs_to_watch || + self.lockdown_from_offchain != other.lockdown_from_offchain || + self.local_tx_signed != other.local_tx_signed { false } else { @@ -852,13 +928,7 @@ impl ChannelMonitor { writer.write_all(&[1; 1])?; } - if let Some(ref broadcasted_remote_payment_script) = self.broadcasted_remote_payment_script { - writer.write_all(&[0; 1])?; - broadcasted_remote_payment_script.0.write(writer)?; - broadcasted_remote_payment_script.1.write(writer)?; - } else { - writer.write_all(&[1; 1])?; - } + self.remote_payment_script.write(writer)?; self.shutdown_script.write(writer)?; self.keys.write(writer)?; @@ -963,12 +1033,7 @@ impl ChannelMonitor { writer.write_all(&[0; 1])?; } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - writer.write_all(&[1; 1])?; - serialize_local_tx!(cur_local_tx); - } else { - writer.write_all(&[0; 1])?; - } + serialize_local_tx!(self.current_local_commitment_tx); writer.write_all(&byte_utils::be48_to_array(self.current_remote_commitment_number))?; writer.write_all(&byte_utils::be48_to_array(self.current_local_commitment_number))?; @@ -1020,6 +1085,7 @@ impl ChannelMonitor { self.onchain_tx_handler.write(writer)?; self.lockdown_from_offchain.write(writer)?; + self.local_tx_signed.write(writer)?; Ok(()) } @@ -1031,11 +1097,34 @@ impl ChannelMonitor { their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey, their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, commitment_transaction_number_obscure_factor: u64, - logger: Arc) -> ChannelMonitor { + initial_local_commitment_tx: LocalCommitmentTransaction) -> ChannelMonitor { assert!(commitment_transaction_number_obscure_factor <= (1 << 48)); - let our_channel_close_key_hash = Hash160::hash(&shutdown_pubkey.serialize()); + let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize()); let shutdown_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script(); + 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 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; + let local_commitment_tx = LocalSignedTx { + txid: initial_local_commitment_tx.txid(), + revocation_key: initial_local_commitment_tx.local_keys.revocation_key, + a_htlc_key: initial_local_commitment_tx.local_keys.a_htlc_key, + b_htlc_key: initial_local_commitment_tx.local_keys.b_htlc_key, + delayed_payment_key: initial_local_commitment_tx.local_keys.a_delayed_payment_key, + per_commitment_point: initial_local_commitment_tx.local_keys.per_commitment_point, + feerate_per_kw: initial_local_commitment_tx.feerate_per_kw, + htlc_outputs: Vec::new(), // There are never any HTLCs in the initial commitment transactions + }; + // Returning a monitor error before updating tracking points means in case of using + // a concurrent watchtower implementation for same channel, if this one doesn't + // reject update as we do, you MAY have the latest local valid commitment tx onchain + // for which you want to spend outputs. We're NOT robust again this scenario right + // now but we should consider it later. + onchain_tx_handler.provide_latest_local_tx(initial_local_commitment_tx).unwrap(); ChannelMonitor { latest_update_id: 0, @@ -1043,17 +1132,17 @@ impl ChannelMonitor { destination_script: destination_script.clone(), broadcasted_local_revokable_script: None, - broadcasted_remote_payment_script: None, + remote_payment_script, shutdown_script, - keys: keys.clone(), + keys, funding_info, 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(), - funding_redeemscript: funding_redeemscript.clone(), + funding_redeemscript, channel_value_satoshis: channel_value_satoshis, their_cur_revocation_points: None, @@ -1066,9 +1155,9 @@ impl ChannelMonitor { remote_hash_commitment_number: HashMap::new(), prev_local_signed_commitment_tx: None, - current_local_signed_commitment_tx: None, + current_local_commitment_tx: local_commitment_tx, current_remote_commitment_number: 1 << 48, - current_local_commitment_number: 0xffff_ffff_ffff, + current_local_commitment_number: 0xffff_ffff_ffff - ((((local_tx_sequence & 0xffffff) << 3*8) | (local_tx_locktime as u64 & 0xffffff)) ^ commitment_transaction_number_obscure_factor), payment_preimages: HashMap::new(), pending_htlcs_updated: Vec::new(), @@ -1077,13 +1166,13 @@ impl ChannelMonitor { onchain_events_waiting_threshold_conf: HashMap::new(), outputs_to_watch: HashMap::new(), - onchain_tx_handler: OnchainTxHandler::new(destination_script.clone(), keys, their_to_self_delay, logger.clone()), + onchain_tx_handler, lockdown_from_offchain: false, + local_tx_signed: false, last_block_hash: Default::default(), secp_ctx: Secp256k1::new(), - logger, } } @@ -1104,13 +1193,13 @@ impl ChannelMonitor { } if !self.payment_preimages.is_empty() { - let local_signed_commitment_tx = self.current_local_signed_commitment_tx.as_ref().expect("Channel needs at least an initial commitment tx !"); + let cur_local_signed_commitment_tx = &self.current_local_commitment_tx; let prev_local_signed_commitment_tx = self.prev_local_signed_commitment_tx.as_ref(); let min_idx = self.get_min_seen_secret(); let remote_hash_commitment_number = &mut self.remote_hash_commitment_number; self.payment_preimages.retain(|&k, _| { - for &(ref htlc, _, _) in &local_signed_commitment_tx.htlc_outputs { + for &(ref htlc, _, _) in cur_local_signed_commitment_tx.htlc_outputs.iter() { if k == htlc.payment_hash { return true } @@ -1142,7 +1231,7 @@ impl ChannelMonitor { /// The monitor watches for it to be broadcasted and then uses the HTLC information (and /// possibly future revocation/preimage information) to claim outputs where possible. /// We cache also the mapping hash:commitment number to lighten pruning of old preimages by watchtowers. - pub(super) fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_revocation_point: PublicKey) { + pub(super) fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_revocation_point: PublicKey, logger: &L) where L::Target: Logger { // TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction // so that a remote monitor doesn't learn anything unless there is a malicious close. // (only maybe, sadly we cant do the same for local info, as we need to be aware of @@ -1152,8 +1241,8 @@ impl ChannelMonitor { } let new_txid = unsigned_commitment_tx.txid(); - log_trace!(self, "Tracking new remote commitment transaction with txid {} at commitment number {} with {} HTLC outputs", new_txid, commitment_number, htlc_outputs.len()); - log_trace!(self, "New potential remote commitment transaction: {}", encode::serialize_hex(unsigned_commitment_tx)); + log_trace!(logger, "Tracking new remote commitment transaction with txid {} at commitment number {} with {} HTLC outputs", new_txid, commitment_number, htlc_outputs.len()); + 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); @@ -1179,27 +1268,19 @@ impl ChannelMonitor { } } - pub(super) fn provide_rescue_remote_commitment_tx_info(&mut self, their_revocation_point: PublicKey) { - if let Ok(payment_key) = chan_utils::derive_public_key(&self.secp_ctx, &their_revocation_point, &self.keys.pubkeys().payment_basepoint) { - let to_remote_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) - .push_slice(&Hash160::hash(&payment_key.serialize())[..]) - .into_script(); - if let Ok(to_remote_key) = chan_utils::derive_private_key(&self.secp_ctx, &their_revocation_point, &self.keys.payment_base_key()) { - self.broadcasted_remote_payment_script = Some((to_remote_script, to_remote_key)); - } - } - } - /// 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. pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>) -> 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 txid = commitment_tx.txid(); - let sequence = commitment_tx.without_valid_witness().input[0].sequence as u64; - let locktime = commitment_tx.without_valid_witness().lock_time as u64; - let new_local_signed_commitment_tx = LocalSignedTx { + let sequence = commitment_tx.unsigned_tx.input[0].sequence as u64; + let locktime = commitment_tx.unsigned_tx.lock_time as u64; + let mut new_local_commitment_tx = LocalSignedTx { txid, revocation_key: commitment_tx.local_keys.revocation_key, a_htlc_key: commitment_tx.local_keys.a_htlc_key, @@ -1218,8 +1299,8 @@ impl ChannelMonitor { return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed")); } self.current_local_commitment_number = 0xffff_ffff_ffff - ((((sequence & 0xffffff) << 3*8) | (locktime as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); - self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take(); - self.current_local_signed_commitment_tx = Some(new_local_signed_commitment_tx); + mem::swap(&mut new_local_commitment_tx, &mut self.current_local_commitment_tx); + self.prev_local_signed_commitment_tx = Some(new_local_commitment_tx); Ok(()) } @@ -1229,16 +1310,17 @@ impl ChannelMonitor { self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone()); } - pub(super) fn broadcast_latest_local_commitment_txn(&mut self, broadcaster: &B) + pub(super) fn broadcast_latest_local_commitment_txn(&mut self, broadcaster: &B, logger: &L) where B::Target: BroadcasterInterface, + L::Target: Logger, { - for tx in self.get_latest_local_commitment_txn().iter() { + for tx in self.get_latest_local_commitment_txn(logger).iter() { broadcaster.broadcast_transaction(tx); } } /// Used in Channel to cheat wrt the update_ids since it plays games, will be removed soon! - pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> { + pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate, logger: &L) -> Result<(), MonitorUpdateError> where L::Target: Logger { for update in updates.updates.drain(..) { match update { ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, htlc_outputs } => { @@ -1246,13 +1328,11 @@ impl ChannelMonitor { self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? }, ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => - self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), + self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point, logger), ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => self.provide_secret(idx, secret)?, - ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => - self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), ChannelMonitorUpdateStep::ChannelForceClosed { .. } => {}, } } @@ -1264,8 +1344,9 @@ impl ChannelMonitor { /// itself. /// /// panics if the given update is not the next update by update_id. - pub fn update_monitor(&mut self, mut updates: ChannelMonitorUpdate, broadcaster: &B) -> Result<(), MonitorUpdateError> + pub fn update_monitor(&mut self, mut updates: ChannelMonitorUpdate, broadcaster: &B, logger: &L) -> Result<(), MonitorUpdateError> where B::Target: BroadcasterInterface, + L::Target: Logger, { if self.latest_update_id + 1 != updates.update_id { panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!"); @@ -1277,19 +1358,17 @@ impl ChannelMonitor { self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? }, ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => - self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), + self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point, logger), ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => self.provide_secret(idx, secret)?, - ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => - self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => { self.lockdown_from_offchain = true; if should_broadcast { - self.broadcast_latest_local_commitment_txn(broadcaster); + self.broadcast_latest_local_commitment_txn(broadcaster, logger); } else { - log_error!(self, "You have a toxic local commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_local_commitment_txn to be informed of manual action to take"); + log_error!(logger, "You have a toxic local commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_local_commitment_txn to be informed of manual action to take"); } } } @@ -1311,7 +1390,7 @@ impl ChannelMonitor { /// Gets a list of txids, with their output scripts (in the order they appear in the /// transaction), which we must learn about spends of via block_connected(). - pub fn get_outputs_to_watch(&self) -> &HashMap> { + pub fn get_outputs_to_watch(&self) -> &HashMap> { &self.outputs_to_watch } @@ -1319,7 +1398,7 @@ impl ChannelMonitor { /// Generally useful when deserializing as during normal operation the return values of /// block_connected are sufficient to ensure all relevant outpoints are being monitored (note /// that the get_funding_txo outpoint and transaction must also be monitored for!). - pub fn get_monitored_outpoints(&self) -> Vec<(Sha256dHash, u32, &Script)> { + pub fn get_monitored_outpoints(&self) -> Vec<(Txid, u32, &Script)> { let mut res = Vec::with_capacity(self.remote_commitment_txn_on_chain.len() * 2); for (ref txid, &(_, ref outputs)) in self.remote_commitment_txn_on_chain.iter() { for (idx, output) in outputs.iter().enumerate() { @@ -1372,7 +1451,7 @@ impl ChannelMonitor { /// HTLC-Success/HTLC-Timeout transactions. /// Return updates for HTLC pending in the channel and failed automatically by the broadcast of /// revoked remote commitment tx - fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec, (Sha256dHash, Vec)) { + fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32, logger: &L) -> (Vec, (Txid, Vec)) where L::Target: Logger { // Most secp and related errors trying to create keys means we have no hope of constructing // a spend transaction...so we return no transactions to broadcast let mut claimable_outpoints = Vec::new(); @@ -1398,20 +1477,12 @@ impl ChannelMonitor { 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 local_payment_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, &per_commitment_point, &self.keys.payment_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.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 revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key); let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh(); - self.broadcasted_remote_payment_script = { - // Note that the Network here is ignored as we immediately drop the address for the - // script_pubkey version - let payment_hash160 = Hash160::hash(&PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize()); - Some((Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script(), local_payment_key)) - }; - // First, process non-htlc outputs (to_local & to_remote) for (idx, outp) in tx.output.iter().enumerate() { if outp.script_pubkey == revokeable_p2wsh { @@ -1439,7 +1510,7 @@ impl ChannelMonitor { // Last, track onchain revoked commitment transaction and fail backward outgoing HTLCs as payment path is broken if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours // We're definitely a remote commitment transaction! - log_trace!(self, "Got broadcast of revoked remote commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len()); + log_trace!(logger, "Got broadcast of revoked remote commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len()); watch_outputs.append(&mut tx.output.clone()); self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect())); @@ -1448,7 +1519,7 @@ impl ChannelMonitor { if let Some(ref outpoints) = self.remote_claimable_outpoints.get($txid) { for &(ref htlc, ref source_option) in outpoints.iter() { if let &Some(ref source) = source_option { - log_info!(self, "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, height + ANTI_REORG_DELAY - 1); + log_info!(logger, "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, height + ANTI_REORG_DELAY - 1); match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); @@ -1490,7 +1561,7 @@ impl ChannelMonitor { watch_outputs.append(&mut tx.output.clone()); self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect())); - log_trace!(self, "Got broadcast of non-revoked remote commitment transaction {}", commitment_txid); + log_trace!(logger, "Got broadcast of non-revoked remote commitment transaction {}", commitment_txid); macro_rules! check_htlc_fails { ($txid: expr, $commitment_tx: expr, $id: tt) => { @@ -1511,7 +1582,7 @@ impl ChannelMonitor { continue $id; } } - log_trace!(self, "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of remote commitment transaction", log_bytes!(htlc.payment_hash.0), $commitment_tx); + log_trace!(logger, "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of remote commitment transaction", log_bytes!(htlc.payment_hash.0), $commitment_tx); match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); @@ -1552,14 +1623,6 @@ impl ChannelMonitor { 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)); - let local_payment_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &self.keys.payment_base_key())); - - self.broadcasted_remote_payment_script = { - // Note that the Network here is ignored as we immediately drop the address for the - // script_pubkey version - let payment_hash160 = Hash160::hash(&PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize()); - Some((Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script(), local_payment_key)) - }; // Then, try to find htlc outputs for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() { @@ -1585,7 +1648,7 @@ impl ChannelMonitor { } /// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key - fn check_spend_remote_htlc(&mut self, tx: &Transaction, commitment_number: u64, height: u32) -> (Vec, Option<(Sha256dHash, Vec)>) { + fn check_spend_remote_htlc(&mut self, tx: &Transaction, commitment_number: u64, height: u32, logger: &L) -> (Vec, Option<(Txid, Vec)>) where L::Target: Logger { let htlc_txid = tx.txid(); if tx.input.len() != 1 || tx.output.len() != 1 || tx.input[0].witness.len() != 5 { return (Vec::new(), None) @@ -1608,7 +1671,7 @@ impl ChannelMonitor { 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!(self, "Remote HTLC broadcast {}:{}", htlc_txid, 0); + 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 }); (claimable_outpoints, Some((htlc_txid, tx.output.clone()))) @@ -1625,8 +1688,18 @@ impl ChannelMonitor { for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { Some(*preimage) } else { None }; - claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, witness_data: InputMaterial::LocalHTLC { preimage, amount: htlc.amount_msat / 1000 }}); + claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, + witness_data: InputMaterial::LocalHTLC { + preimage: if !htlc.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { + Some(preimage.clone()) + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }, + amount: htlc.amount_msat, + }}); watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone()); } } @@ -1637,14 +1710,14 @@ impl ChannelMonitor { /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet) /// revoked using data in local_claimable_outpoints. /// Should not be used if check_spend_revoked_transaction succeeds. - fn check_spend_local_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec, (Sha256dHash, Vec)) { + fn check_spend_local_transaction(&mut self, tx: &Transaction, height: u32, logger: &L) -> (Vec, (Txid, Vec)) where L::Target: Logger { let commitment_txid = tx.txid(); let mut claim_requests = Vec::new(); let mut watch_outputs = Vec::new(); macro_rules! wait_threshold_conf { ($height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => { - log_trace!(self, "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation (at height{})", log_bytes!($payment_hash.0), $commitment_tx, height + ANTI_REORG_DELAY - 1); + log_trace!(logger, "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation (at height{})", log_bytes!($payment_hash.0), $commitment_tx, height + ANTI_REORG_DELAY - 1); match self.onchain_events_waiting_threshold_conf.entry($height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); @@ -1676,18 +1749,15 @@ impl ChannelMonitor { // HTLCs set may differ between last and previous local commitment txn, in case of one them hitting chain, ensure we cancel all HTLCs backward let mut is_local_tx = false; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - if local_tx.txid == commitment_txid { - is_local_tx = true; - log_trace!(self, "Got latest local commitment tx broadcast, searching for available HTLCs to claim"); - let mut res = self.broadcast_by_local_state(tx, local_tx); - append_onchain_update!(res); - } - } - if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { + if self.current_local_commitment_tx.txid == commitment_txid { + is_local_tx = true; + log_trace!(logger, "Got latest local commitment tx broadcast, searching for available HTLCs to claim"); + let mut res = self.broadcast_by_local_state(tx, &self.current_local_commitment_tx); + append_onchain_update!(res); + } else if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { if local_tx.txid == commitment_txid { is_local_tx = true; - log_trace!(self, "Got previous local commitment tx broadcast, searching for available HTLCs to claim"); + log_trace!(logger, "Got previous local commitment tx broadcast, searching for available HTLCs to claim"); let mut res = self.broadcast_by_local_state(tx, local_tx); append_onchain_update!(res); } @@ -1706,9 +1776,7 @@ impl ChannelMonitor { } if is_local_tx { - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - fail_dust_htlcs_after_threshold_conf!(local_tx); - } + fail_dust_htlcs_after_threshold_conf!(self.current_local_commitment_tx); if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { fail_dust_htlcs_after_threshold_conf!(local_tx); } @@ -1726,23 +1794,28 @@ impl ChannelMonitor { /// substantial amount of time (a month or even a year) to get back funds. Best may be to contact /// out-of-band the other node operator to coordinate with him if option is available to you. /// In any-case, choice is up to the user. - pub fn get_latest_local_commitment_txn(&mut self) -> Vec { - log_trace!(self, "Getting signed latest local commitment transaction!"); - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx() { + pub fn get_latest_local_commitment_txn(&mut self, logger: &L) -> Vec where L::Target: Logger { + log_trace!(logger, "Getting signed latest local commitment transaction!"); + self.local_tx_signed = true; + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) { let txid = commitment_tx.txid(); let mut res = vec![commitment_tx]; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - for htlc in local_tx.htlc_outputs.iter() { - if let Some(htlc_index) = htlc.0.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) { - res.push(htlc_tx); - } + for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { + if let Some(vout) = htlc.0.transaction_output_index { + let preimage = if !htlc.0.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }; + if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx( + &::bitcoin::OutPoint { txid, vout }, &preimage) { + res.push(htlc_tx); } } - // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. - // The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation. } + // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. + // The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation. return res } Vec::new() @@ -1752,18 +1825,22 @@ impl ChannelMonitor { /// to bypass LocalCommitmentTransaction state update lockdown after signature and generate /// revoked commitment transaction. #[cfg(test)] - pub fn unsafe_get_latest_local_commitment_txn(&mut self) -> Vec { - log_trace!(self, "Getting signed copy of latest local commitment transaction!"); - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx() { + pub fn unsafe_get_latest_local_commitment_txn(&mut self, logger: &L) -> Vec where L::Target: Logger { + log_trace!(logger, "Getting signed copy of latest local commitment transaction!"); + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(&self.funding_redeemscript) { let txid = commitment_tx.txid(); let mut res = vec![commitment_tx]; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - for htlc in local_tx.htlc_outputs.iter() { - if let Some(htlc_index) = htlc.0.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) { - res.push(htlc_tx); - } + for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { + if let Some(vout) = htlc.0.transaction_output_index { + let preimage = if !htlc.0.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }; + if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx( + &::bitcoin::OutPoint { txid, vout }, &preimage) { + res.push(htlc_tx); } } } @@ -1772,14 +1849,20 @@ impl ChannelMonitor { Vec::new() } - /// Called by SimpleManyChannelMonitor::block_connected, which implements - /// ChainListener::block_connected. - /// Eventually this should be pub and, roughly, implement ChainListener, however this requires - /// &mut self, as well as returns new spendable outputs and outpoints to watch for spending of - /// on-chain. - fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: B, fee_estimator: F)-> Vec<(Sha256dHash, Vec)> + /// Called when a new block has been connected to the best chain by ::block_connected, and should thus generally not be called during normal + /// operation. It is exposed both for users who wish to use ChannelMonitors directly and to + /// simplify rescans that occur at load-time. + /// + /// This is very similar to ChainListener::block_connected itself, but requires an &mut self, + /// and an explicit reference to a transaction broadcaster and fee estimator. + /// + /// Returns a list of new (txid, outputs) pairs which spends of must be watched for. Note that + /// after this call these are also available via get_outputs_to_watch(). + pub fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)-> Vec<(Txid, Vec)> where B::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, { for tx in txn_matched { let mut output_val = 0; @@ -1790,7 +1873,7 @@ impl ChannelMonitor { } } - log_trace!(self, "Block {} at height {} connected with {} txn matched", block_hash, height, txn_matched.len()); + log_trace!(logger, "Block {} at height {} connected with {} txn matched", block_hash, height, txn_matched.len()); let mut watch_outputs = Vec::new(); let mut claimable_outpoints = Vec::new(); for tx in txn_matched { @@ -1802,12 +1885,12 @@ impl ChannelMonitor { let prevout = &tx.input[0].previous_output; if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 { if (tx.input[0].sequence >> 8*3) as u8 == 0x80 && (tx.lock_time >> 8*3) as u8 == 0x20 { - let (mut new_outpoints, new_outputs) = self.check_spend_remote_transaction(&tx, height); + let (mut new_outpoints, new_outputs) = self.check_spend_remote_transaction(&tx, height, &logger); if !new_outputs.1.is_empty() { watch_outputs.push(new_outputs); } if new_outpoints.is_empty() { - let (mut new_outpoints, new_outputs) = self.check_spend_local_transaction(&tx, height); + let (mut new_outpoints, new_outputs) = self.check_spend_local_transaction(&tx, height, &logger); if !new_outputs.1.is_empty() { watch_outputs.push(new_outputs); } @@ -1817,7 +1900,7 @@ impl ChannelMonitor { } } else { if let Some(&(commitment_number, _)) = self.remote_commitment_txn_on_chain.get(&prevout.txid) { - let (mut new_outpoints, new_outputs_option) = self.check_spend_remote_htlc(&tx, commitment_number, height); + let (mut new_outpoints, new_outputs_option) = self.check_spend_remote_htlc(&tx, commitment_number, height, &logger); claimable_outpoints.append(&mut new_outpoints); if let Some(new_outputs) = new_outputs_option { watch_outputs.push(new_outputs); @@ -1828,32 +1911,28 @@ impl ChannelMonitor { // While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs // can also be resolved in a few other ways which can have more than one output. Thus, // we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check. - self.is_resolving_htlc_output(&tx, height); + self.is_resolving_htlc_output(&tx, height, &logger); - self.is_paying_spendable_output(&tx, height); + self.is_paying_spendable_output(&tx, height, &logger); } - let should_broadcast = if let Some(_) = self.current_local_signed_commitment_tx { - self.would_broadcast_at_height(height) - } else { false }; + let should_broadcast = self.would_broadcast_at_height(height, &logger); if should_broadcast { - claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { channel_value: self.channel_value_satoshis }}); - } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - if should_broadcast { - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx() { - let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, cur_local_tx); - if !new_outputs.is_empty() { - watch_outputs.push((cur_local_tx.txid.clone(), new_outputs)); - } - claimable_outpoints.append(&mut new_outpoints); + claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }}); + } + if should_broadcast { + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) { + let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, &self.current_local_commitment_tx); + if !new_outputs.is_empty() { + watch_outputs.push((self.current_local_commitment_tx.txid.clone(), new_outputs)); } + claimable_outpoints.append(&mut new_outpoints); } } if let Some(events) = self.onchain_events_waiting_threshold_conf.remove(&height) { for ev in events { match ev { OnchainEvent::HTLCUpdate { htlc_update } => { - log_trace!(self, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0)); + log_trace!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0)); self.pending_htlcs_updated.push(HTLCUpdate { payment_hash: htlc_update.1, payment_preimage: None, @@ -1861,7 +1940,7 @@ impl ChannelMonitor { }); }, OnchainEvent::MaturingOutput { descriptor } => { - log_trace!(self, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor)); + log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor)); self.pending_events.push(events::Event::SpendableOutputs { outputs: vec![descriptor] }); @@ -1869,7 +1948,7 @@ impl ChannelMonitor { } } } - self.onchain_tx_handler.block_connected(txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator); + self.onchain_tx_handler.block_connected(txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator, &*logger); self.last_block_hash = block_hash.clone(); for &(ref txid, ref output_scripts) in watch_outputs.iter() { @@ -1879,23 +1958,31 @@ impl ChannelMonitor { watch_outputs } - fn block_disconnected(&mut self, height: u32, block_hash: &Sha256dHash, broadcaster: B, fee_estimator: F) + /// Called when a block has been disconnected from the best chain by ::block_disconnected, and should thus generally not be called during + /// normal operation. It is exposed both for users who wish to use ChannelMonitors directly and + /// to simplify rescans that occur at load-time. + /// + /// This is very similar to ChainListener::block_disconnected itself, but requires an &mut self, + /// and an explicit reference to a transaction broadcaster and fee estimator. + pub fn block_disconnected(&mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L) where B::Target: BroadcasterInterface, - F::Target: FeeEstimator + F::Target: FeeEstimator, + L::Target: Logger, { - log_trace!(self, "Block {} at height {} disconnected", block_hash, height); + log_trace!(logger, "Block {} at height {} disconnected", block_hash, height); if let Some(_) = self.onchain_events_waiting_threshold_conf.remove(&(height + ANTI_REORG_DELAY - 1)) { //We may discard: //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected //- maturing spendable output has transaction paying us has been disconnected } - self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator); + self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator, logger); self.last_block_hash = block_hash.clone(); } - pub(super) fn would_broadcast_at_height(&self, height: u32) -> bool { + pub(super) fn would_broadcast_at_height(&self, height: u32, logger: &L) -> bool where L::Target: Logger { // We need to consider all HTLCs which are: // * in any unrevoked remote commitment transaction, as they could broadcast said // transactions and we'd end up in a race, or @@ -1935,16 +2022,14 @@ impl ChannelMonitor { let htlc_outbound = $local_tx == htlc.offered; if ( htlc_outbound && htlc.cltv_expiry + LATENCY_GRACE_PERIOD_BLOCKS <= height) || (!htlc_outbound && htlc.cltv_expiry <= height + CLTV_CLAIM_BUFFER && self.payment_preimages.contains_key(&htlc.payment_hash)) { - log_info!(self, "Force-closing channel due to {} HTLC timeout, HTLC expiry is {}", if htlc_outbound { "outbound" } else { "inbound "}, htlc.cltv_expiry); + log_info!(logger, "Force-closing channel due to {} HTLC timeout, HTLC expiry is {}", if htlc_outbound { "outbound" } else { "inbound "}, htlc.cltv_expiry); return true; } } } } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - scan_commitment!(cur_local_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), true); - } + scan_commitment!(self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), true); if let Some(ref txid) = self.current_remote_commitment_txid { if let Some(ref htlc_outputs) = self.remote_claimable_outpoints.get(txid) { @@ -1962,7 +2047,7 @@ impl ChannelMonitor { /// Check if any transaction broadcasted is resolving HTLC output by a success or timeout on a local /// or remote commitment tx, if so send back the source, preimage if found and payment_hash of resolved HTLC - fn is_resolving_htlc_output(&mut self, tx: &Transaction, height: u32) { + fn is_resolving_htlc_output(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger { 'outer_loop: for input in &tx.input { let mut payment_data = None; let revocation_sig_claim = (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && input.witness[1].len() == 33) @@ -1979,12 +2064,12 @@ impl ChannelMonitor { let outbound_htlc = $local_tx == $htlc.offered; if ($local_tx && revocation_sig_claim) || (outbound_htlc && !$source_avail && (accepted_preimage_claim || offered_preimage_claim)) { - log_error!(self, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!", + log_error!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!", $tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(), if outbound_htlc { "outbound" } else { "inbound" }, log_bytes!($htlc.payment_hash.0), if revocation_sig_claim { "revocation sig" } else { "preimage claim after we'd passed the HTLC resolution back" }); } else { - log_info!(self, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}", + log_info!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}", $tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(), if outbound_htlc { "outbound" } else { "inbound" }, log_bytes!($htlc.payment_hash.0), if revocation_sig_claim { "revocation sig" } else if accepted_preimage_claim || offered_preimage_claim { "preimage" } else { "timeout" }); @@ -2035,11 +2120,9 @@ impl ChannelMonitor { } } - if let Some(ref current_local_signed_commitment_tx) = self.current_local_signed_commitment_tx { - if input.previous_output.txid == current_local_signed_commitment_tx.txid { - scan_commitment!(current_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), - "our latest local commitment tx", true); - } + if input.previous_output.txid == self.current_local_commitment_tx.txid { + scan_commitment!(self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), + "our latest local commitment tx", true); } if let Some(ref prev_local_signed_commitment_tx) = self.prev_local_signed_commitment_tx { if input.previous_output.txid == prev_local_signed_commitment_tx.txid { @@ -2075,7 +2158,7 @@ impl ChannelMonitor { }); } } else { - log_info!(self, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})", log_bytes!(payment_hash.0), height + ANTI_REORG_DELAY - 1); + log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})", log_bytes!(payment_hash.0), height + ANTI_REORG_DELAY - 1); match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); @@ -2099,7 +2182,7 @@ impl ChannelMonitor { } /// Check if any transaction broadcasted is paying fund back to some address we can assume to own - fn is_paying_spendable_output(&mut self, tx: &Transaction, height: u32) { + fn is_paying_spendable_output(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger { let mut spendable_output = None; for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us if outp.script_pubkey == self.destination_script { @@ -2119,15 +2202,13 @@ impl ChannelMonitor { }); break; } - } else if let Some(ref broadcasted_remote_payment_script) = self.broadcasted_remote_payment_script { - if broadcasted_remote_payment_script.0 == outp.script_pubkey { - spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WPKH { - outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, - key: broadcasted_remote_payment_script.1, - output: outp.clone(), - }); - break; - } + } else if self.remote_payment_script == outp.script_pubkey { + spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WPKH { + outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, + key: self.keys.payment_key().clone(), + output: outp.clone(), + }); + break; } else if outp.script_pubkey == self.shutdown_script { spendable_output = Some(SpendableOutputDescriptor::StaticOutput { outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, @@ -2136,7 +2217,7 @@ impl ChannelMonitor { } } if let Some(spendable_output) = spendable_output { - log_trace!(self, "Maturing {} until {}", log_spendable!(spendable_output), height + ANTI_REORG_DELAY - 1); + log_trace!(logger, "Maturing {} until {}", log_spendable!(spendable_output), height + ANTI_REORG_DELAY - 1); match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); @@ -2152,8 +2233,8 @@ impl ChannelMonitor { const MAX_ALLOC_SIZE: usize = 64*1024; -impl ReadableArgs> for (Sha256dHash, ChannelMonitor) { - fn read(reader: &mut R, logger: Arc) -> Result { +impl Readable for (BlockHash, ChannelMonitor) { + fn read(reader: &mut R) -> Result { macro_rules! unwrap_obj { ($key: expr) => { match $key { @@ -2183,15 +2264,7 @@ impl ReadableArgs> for (Sha256dH 1 => { None }, _ => return Err(DecodeError::InvalidValue), }; - let broadcasted_remote_payment_script = match ::read(reader)? { - 0 => { - let payment_address = Readable::read(reader)?; - let payment_key = Readable::read(reader)?; - Some((payment_address, payment_key)) - }, - 1 => { None }, - _ => return Err(DecodeError::InvalidValue), - }; + let remote_payment_script = Readable::read(reader)?; let shutdown_script = Readable::read(reader)?; let keys = Readable::read(reader)?; @@ -2249,7 +2322,7 @@ impl ReadableArgs> for (Sha256dH let remote_claimable_outpoints_len: u64 = Readable::read(reader)?; let mut remote_claimable_outpoints = HashMap::with_capacity(cmp::min(remote_claimable_outpoints_len as usize, MAX_ALLOC_SIZE / 64)); for _ in 0..remote_claimable_outpoints_len { - let txid: Sha256dHash = Readable::read(reader)?; + 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 { @@ -2263,7 +2336,7 @@ impl ReadableArgs> for (Sha256dH let remote_commitment_txn_on_chain_len: u64 = Readable::read(reader)?; let mut remote_commitment_txn_on_chain = HashMap::with_capacity(cmp::min(remote_commitment_txn_on_chain_len as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..remote_commitment_txn_on_chain_len { - let txid: Sha256dHash = Readable::read(reader)?; + let txid: Txid = Readable::read(reader)?; let commitment_number = ::read(reader)?.0; let outputs_count = ::read(reader)?; let mut outputs = Vec::with_capacity(cmp::min(outputs_count as usize, MAX_ALLOC_SIZE / 8)); @@ -2324,14 +2397,7 @@ impl ReadableArgs> for (Sha256dH }, _ => return Err(DecodeError::InvalidValue), }; - - let current_local_signed_commitment_tx = match ::read(reader)? { - 0 => None, - 1 => { - Some(read_local_tx!()) - }, - _ => return Err(DecodeError::InvalidValue), - }; + let current_local_commitment_tx = read_local_tx!(); let current_remote_commitment_number = ::read(reader)?.0; let current_local_commitment_number = ::read(reader)?.0; @@ -2360,7 +2426,7 @@ impl ReadableArgs> for (Sha256dH } } - let last_block_hash: Sha256dHash = Readable::read(reader)?; + let last_block_hash: BlockHash = Readable::read(reader)?; let waiting_threshold_conf_len: u64 = Readable::read(reader)?; let mut onchain_events_waiting_threshold_conf = HashMap::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128)); @@ -2391,7 +2457,7 @@ impl ReadableArgs> for (Sha256dH } let outputs_to_watch_len: u64 = Readable::read(reader)?; - let mut outputs_to_watch = HashMap::with_capacity(cmp::min(outputs_to_watch_len as usize, MAX_ALLOC_SIZE / (mem::size_of::() + mem::size_of::>()))); + let mut outputs_to_watch = HashMap::with_capacity(cmp::min(outputs_to_watch_len as usize, MAX_ALLOC_SIZE / (mem::size_of::() + mem::size_of::>()))); for _ in 0..outputs_to_watch_len { let txid = Readable::read(reader)?; let outputs_len: u64 = Readable::read(reader)?; @@ -2403,9 +2469,10 @@ impl ReadableArgs> for (Sha256dH return Err(DecodeError::InvalidValue); } } - let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?; + let onchain_tx_handler = Readable::read(reader)?; let lockdown_from_offchain = Readable::read(reader)?; + let local_tx_signed = Readable::read(reader)?; Ok((last_block_hash.clone(), ChannelMonitor { latest_update_id, @@ -2413,7 +2480,7 @@ impl ReadableArgs> for (Sha256dH destination_script, broadcasted_local_revokable_script, - broadcasted_remote_payment_script, + remote_payment_script, shutdown_script, keys, @@ -2436,7 +2503,7 @@ impl ReadableArgs> for (Sha256dH remote_hash_commitment_number, prev_local_signed_commitment_tx, - current_local_signed_commitment_tx, + current_local_commitment_tx, current_remote_commitment_number, current_local_commitment_number, @@ -2450,10 +2517,10 @@ impl ReadableArgs> for (Sha256dH onchain_tx_handler, lockdown_from_offchain, + local_tx_signed, last_block_hash, secp_ctx: Secp256k1::new(), - logger, })) } } @@ -2465,10 +2532,10 @@ mod tests { use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType}; use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; use bitcoin::util::bip143; - use bitcoin_hashes::Hash; - use bitcoin_hashes::sha256::Hash as Sha256; - use bitcoin_hashes::sha256d::Hash as Sha256dHash; - use bitcoin_hashes::hex::FromHex; + use bitcoin::hashes::Hash; + use bitcoin::hashes::sha256::Hash as Sha256; + use bitcoin::hashes::hex::FromHex; + use bitcoin::hash_types::Txid; use hex; use chain::transaction::OutPoint; use ln::channelmanager::{PaymentPreimage, PaymentHash}; @@ -2477,8 +2544,8 @@ mod tests { use ln::chan_utils; use ln::chan_utils::{HTLCOutputInCommitment, LocalCommitmentTransaction}; use util::test_utils::TestLogger; - use secp256k1::key::{SecretKey,PublicKey}; - use secp256k1::Secp256k1; + use bitcoin::secp256k1::key::{SecretKey,PublicKey}; + use bitcoin::secp256k1::Secp256k1; use rand::{thread_rng,Rng}; use std::sync::Arc; use chain::keysinterface::InMemoryChannelKeys; @@ -2552,16 +2619,16 @@ mod tests { // old state. let mut monitor = ChannelMonitor::new(keys, &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(), - (OutPoint { txid: Sha256dHash::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()), + (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()), &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[44; 32]).unwrap()), &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[45; 32]).unwrap()), - 10, Script::new(), 46, 0, logger.clone()); + 10, Script::new(), 46, 0, LocalCommitmentTransaction::dummy()); monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), preimages_to_local_htlcs!(preimages[0..10])).unwrap(); - monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key); - monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key); - monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key); - monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key); + monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger); + monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger); + monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger); + monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger); for &(ref preimage, ref hash) in preimages.iter() { monitor.provide_payment_preimage(hash, preimage); } @@ -2640,7 +2707,7 @@ mod tests { } let script_pubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(); - let txid = Sha256dHash::from_hex("56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d").unwrap(); + let txid = Txid::from_hex("56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d").unwrap(); // Justice tx with 1 to_local, 2 revoked offered HTLCs, 1 revoked received HTLCs let mut claim_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };