X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmonitor.rs;h=e7e575a988a86c1dfd690f6e5694791b70881838;hb=06445b61893ab74ec09765a10c091415e877a82c;hp=d5b11b106b96e76e812823ddbfde9fde2b2fb1c7;hpb=56ec6e0060204d8d48c501932dc0f78fd303370d;p=rust-lightning diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index d5b11b10..e7e575a9 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -428,16 +428,63 @@ struct LocalSignedTx { htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>, } -/// 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> } +impl Writeable for RemoteCommitmentTransaction { + fn write(&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: &mut R) -> Result { + 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,13 +794,13 @@ pub struct ChannelMonitor { current_remote_commitment_txid: Option, prev_remote_commitment_txid: Option, - 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 their_cur_revocation_points: Option<(u64, PublicKey, Option)>, - their_to_self_delay: u16, + on_local_tx_csv: u16, commitment_secrets: CounterpartyCommitmentSecrets, remote_claimable_outpoints: HashMap>)>>, @@ -841,7 +888,7 @@ impl PartialEq for ChannelMonitor { self.funding_redeemscript != other.funding_redeemscript || self.channel_value_satoshis != other.channel_value_satoshis || self.their_cur_revocation_points != other.their_cur_revocation_points || - self.their_to_self_delay != other.their_to_self_delay || + self.on_local_tx_csv != other.on_local_tx_csv || self.commitment_secrets != other.commitment_secrets || self.remote_claimable_outpoints != other.remote_claimable_outpoints || self.remote_commitment_txn_on_chain != other.remote_commitment_txn_on_chain || @@ -904,17 +951,7 @@ impl ChannelMonitor { 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)?; @@ -936,7 +973,7 @@ impl ChannelMonitor { }, } - writer.write_all(&byte_utils::be16_to_array(self.their_to_self_delay))?; + writer.write_all(&byte_utils::be16_to_array(self.on_local_tx_csv))?; self.commitment_secrets.write(writer)?; @@ -1069,7 +1106,7 @@ impl ChannelMonitor { pub(super) fn new(keys: ChanSigner, shutdown_pubkey: &PublicKey, on_remote_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script), remote_htlc_base_key: &PublicKey, remote_delayed_payment_base_key: &PublicKey, - their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, + on_local_tx_csv: u16, funding_redeemscript: Script, channel_value_satoshis: u64, commitment_transaction_number_obscure_factor: u64, initial_local_commitment_tx: LocalCommitmentTransaction) -> ChannelMonitor { @@ -1079,9 +1116,9 @@ impl ChannelMonitor { 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(), their_to_self_delay); + let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), on_local_tx_csv); let local_tx_sequence = initial_local_commitment_tx.unsigned_tx.input[0].sequence as u64; let local_tx_locktime = initial_local_commitment_tx.unsigned_tx.lock_time as u64; @@ -1121,7 +1158,7 @@ impl ChannelMonitor { channel_value_satoshis: channel_value_satoshis, their_cur_revocation_points: None, - their_to_self_delay, + on_local_tx_csv, commitment_secrets: CounterpartyCommitmentSecrets::new(), remote_claimable_outpoints: HashMap::new(), @@ -1253,7 +1290,7 @@ impl ChannelMonitor { /// monitor watches for timeouts and may broadcast it if we approach such a timeout. Thus, it /// is important that any clones of this channel monitor (including remote clones) by kept /// up-to-date as our local commitment transaction is updated. - /// Panics if set_their_to_self_delay has never been called. + /// Panics if set_on_local_tx_csv has never been called. pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, 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")); @@ -1653,7 +1690,7 @@ impl ChannelMonitor { let mut claim_requests = Vec::with_capacity(local_tx.htlc_outputs.len()); let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len()); - let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay, &local_tx.delayed_payment_key); + let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.on_local_tx_csv, &local_tx.delayed_payment_key); let broadcasted_local_revokable_script = Some((redeemscript.to_v0_p2wsh(), local_tx.per_commitment_point.clone(), local_tx.revocation_key.clone())); for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() { @@ -2154,7 +2191,7 @@ impl ChannelMonitor { spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, per_commitment_point: broadcasted_local_revokable_script.1, - to_self_delay: self.their_to_self_delay, + to_self_delay: self.on_local_tx_csv, output: outp.clone(), key_derivation_params: self.keys.key_derivation_params(), remote_revocation_pubkey: broadcasted_local_revokable_script.2.clone(), @@ -2237,31 +2274,7 @@ impl 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)?; @@ -2280,7 +2293,7 @@ impl Readable for (BlockHash, ChannelMonitor } }; - let their_to_self_delay: u16 = Readable::read(reader)?; + let on_local_tx_csv: u16 = Readable::read(reader)?; let commitment_secrets = Readable::read(reader)?; @@ -2474,7 +2487,7 @@ impl Readable for (BlockHash, ChannelMonitor channel_value_satoshis, their_cur_revocation_points, - their_to_self_delay, + on_local_tx_csv, commitment_secrets, remote_claimable_outpoints,