X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmonitor.rs;h=33cc869efe8aeed5168acec5aaf56d6f5ddee8d5;hb=c61b9202b6a4f51dec4146a4babb18925e4debd9;hp=6d10fdb4f05f049d2d035873d1b986514a0335b4;hpb=2087032e7a823f6c63a64dac951e0f4843bc4667;p=rust-lightning diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index 6d10fdb4..33cc869e 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -183,27 +183,32 @@ impl = matched_indexes.iter().map(|index| txdata[*index]).collect(); + let last_seen = self.chain_monitor.reentered(); + { + let mut monitors = self.monitors.lock().unwrap(); + for monitor in monitors.values_mut() { + let txn_outputs = monitor.block_connected(header, &matched_txn, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger); + + for (ref txid, ref outputs) in txn_outputs { + for (idx, output) in outputs.iter().enumerate() { + self.chain_monitor.install_watch_outpoint((txid.clone(), idx as u32), &output.script_pubkey); + } } } } + reentered = last_seen != self.chain_monitor.reentered(); } } fn block_disconnected(&self, header: &BlockHeader, disconnected_height: u32) { - 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, &*self.logger); + monitor.block_disconnected(header, disconnected_height, &*self.broadcaster, &*self.fee_estimator, &*self.logger); } } } @@ -235,12 +240,15 @@ impl return Err(MonitorUpdateError("Channel monitor for given key is already present")), hash_map::Entry::Vacant(e) => e, }; - 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() { - for (idx, script) in outputs.iter().enumerate() { - self.chain_monitor.install_watch_outpoint((*txid, idx as u32), script); + { + let funding_txo = monitor.get_funding_txo(); + log_trace!(self.logger, "Got new Channel Monitor for channel {}", log_bytes!(funding_txo.0.to_channel_id()[..])); + self.chain_monitor.install_watch_tx(&funding_txo.0.txid, &funding_txo.1); + self.chain_monitor.install_watch_outpoint((funding_txo.0.txid, funding_txo.0.index as u32), &funding_txo.1); + for (txid, outputs) in monitor.get_outputs_to_watch().iter() { + for (idx, script) in outputs.iter().enumerate() { + self.chain_monitor.install_watch_outpoint((*txid, idx as u32), script); + } } } entry.insert(monitor); @@ -366,7 +374,7 @@ struct LocalSignedTx { b_htlc_key: PublicKey, delayed_payment_key: PublicKey, per_commitment_point: PublicKey, - feerate_per_kw: u64, + feerate_per_kw: u32, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>, } @@ -1028,7 +1036,7 @@ impl ChannelMonitor { writer.write_all(&$local_tx.delayed_payment_key.serialize())?; writer.write_all(&$local_tx.per_commitment_point.serialize())?; - writer.write_all(&byte_utils::be64_to_array($local_tx.feerate_per_kw))?; + writer.write_all(&byte_utils::be32_to_array($local_tx.feerate_per_kw))?; writer.write_all(&byte_utils::be64_to_array($local_tx.htlc_outputs.len() as u64))?; for &(ref htlc_output, ref sig, ref htlc_source) in $local_tx.htlc_outputs.iter() { serialize_htlc_in_commitment!(htlc_output); @@ -1408,8 +1416,8 @@ impl ChannelMonitor { } /// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for. - pub fn get_funding_txo(&self) -> OutPoint { - self.funding_info.0 + pub fn get_funding_txo(&self) -> &(OutPoint, Script) { + &self.funding_info } /// Gets a list of txids, with their output scripts (in the order they appear in the @@ -1641,7 +1649,7 @@ impl ChannelMonitor { self.remote_payment_script = { // Note that the Network here is ignored as we immediately drop the address for the // script_pubkey version - let payment_hash160 = WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &self.keys.payment_key()).serialize()); + let payment_hash160 = WPubkeyHash::hash(&self.keys.pubkeys().payment_point.serialize()); Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script() }; @@ -1867,12 +1875,12 @@ impl ChannelMonitor { /// 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: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)-> Vec<(Txid, Vec)> + fn block_connected(&mut self, header: &BlockHeader, txn_matched: &[(usize, &Transaction)], height: u32, broadcaster: B, fee_estimator: F, logger: L)-> Vec<(Txid, Vec)> where B::Target: BroadcasterInterface, F::Target: FeeEstimator, L::Target: Logger, { - for tx in txn_matched { + for &(_, tx) in txn_matched { let mut output_val = 0; for out in tx.output.iter() { if out.value > 21_000_000_0000_0000 { panic!("Value-overflowing transaction provided to block connected"); } @@ -1881,10 +1889,12 @@ impl ChannelMonitor { } } + let block_hash = header.bitcoin_hash(); 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 { + for &(_, tx) in txn_matched { if tx.input.len() == 1 { // Assuming our keys were not leaked (in which case we're screwed no matter what), // commitment transactions and HTLC transactions will all only ever have one input, @@ -1958,7 +1968,7 @@ impl ChannelMonitor { } self.onchain_tx_handler.block_connected(txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator, &*logger); - self.last_block_hash = block_hash.clone(); + self.last_block_hash = block_hash; for &(ref txid, ref output_scripts) in watch_outputs.iter() { self.outputs_to_watch.insert(txid.clone(), output_scripts.iter().map(|o| o.script_pubkey.clone()).collect()); } @@ -1966,12 +1976,14 @@ impl ChannelMonitor { watch_outputs } - fn block_disconnected(&mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L) + fn block_disconnected(&mut self, header: &BlockHeader, height: u32, broadcaster: B, fee_estimator: F, logger: L) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, L::Target: Logger, { + let block_hash = header.bitcoin_hash(); 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 @@ -1980,7 +1992,7 @@ impl ChannelMonitor { self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator, logger); - self.last_block_hash = block_hash.clone(); + self.last_block_hash = block_hash; } pub(super) fn would_broadcast_at_height(&self, height: u32, logger: &L) -> bool where L::Target: Logger { @@ -2367,7 +2379,7 @@ impl Readable for (BlockHash, ChannelMonitor let b_htlc_key = Readable::read(reader)?; let delayed_payment_key = Readable::read(reader)?; let per_commitment_point = Readable::read(reader)?; - let feerate_per_kw: u64 = Readable::read(reader)?; + let feerate_per_kw: u32 = Readable::read(reader)?; let htlcs_len: u64 = Readable::read(reader)?; let mut htlcs = Vec::with_capacity(cmp::min(htlcs_len as usize, MAX_ALLOC_SIZE / 128)); @@ -2544,7 +2556,6 @@ mod tests { use util::test_utils::TestLogger; use bitcoin::secp256k1::key::{SecretKey,PublicKey}; use bitcoin::secp256k1::Secp256k1; - use rand::{thread_rng,Rng}; use std::sync::Arc; use chain::keysinterface::InMemoryChannelKeys; @@ -2558,10 +2569,8 @@ mod tests { let mut preimages = Vec::new(); { - let mut rng = thread_rng(); - for _ in 0..20 { - let mut preimage = PaymentPreimage([0; 32]); - rng.fill_bytes(&mut preimage.0[..]); + for i in 0..20 { + let preimage = PaymentPreimage([i; 32]); let hash = PaymentHash(Sha256::hash(&preimage.0[..]).into_inner()); preimages.push((preimage, hash)); }