From: Matt Corallo Date: Sat, 13 Jun 2020 21:33:21 +0000 (-0400) Subject: Make ChainWatchInterface::filter_block return only idxes, not refs X-Git-Tag: v0.0.12~54^2~3 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=882db714deb1a6de349ac13ddf3cb3adf8bb8704;p=rust-lightning Make ChainWatchInterface::filter_block return only idxes, not refs Instead of making the filter_block fn in the ChainWatchInterface trait return both a list of indexes of transaction positions within the block and references to the transactions themselves, return only the list of indexes and then build the reference list at the callsite. While this may be slightly less effecient from a memory locality perspective, it shouldn't be materially different. This should make it more practical to generate bindings for filter_block as it no longer needs to reference Rust Transaction objects that are contained in a Rust Block object (which we'd otherwise just pass over the FFI in fully-serialized form). --- diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index f388399ab..c79ebb7b4 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -76,8 +76,8 @@ impl ChainWatchInterface for DummyChainWatcher { fn install_watch_tx(&self, _txid: &Txid, _script_pub_key: &Script) { } fn install_watch_outpoint(&self, _outpoint: (Txid, u32), _out_script: &Script) { } fn watch_all_txn(&self) { } - fn filter_block<'a>(&self, _block: &'a Block) -> (Vec<&'a Transaction>, Vec) { - (Vec::new(), Vec::new()) + fn filter_block(&self, _block: &Block) -> Vec { + Vec::new() } fn reentered(&self) -> usize { 0 } diff --git a/lightning/src/chain/chaininterface.rs b/lightning/src/chain/chaininterface.rs index 5cd87c49f..7c215f363 100644 --- a/lightning/src/chain/chaininterface.rs +++ b/lightning/src/chain/chaininterface.rs @@ -53,9 +53,9 @@ pub trait ChainWatchInterface: Sync + Send { /// final two the output within the transaction. fn get_chain_utxo(&self, genesis_hash: BlockHash, unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError>; - /// Gets the list of transactions and transaction indices that the ChainWatchInterface is + /// Gets the list of transaction indices within a given block that the ChainWatchInterface is /// watching for. - fn filter_block<'a>(&self, block: &'a Block) -> (Vec<&'a Transaction>, Vec); + fn filter_block(&self, block: &Block) -> Vec; /// Returns a usize that changes when the ChainWatchInterface's watched data is modified. /// Users of `filter_block` should pre-save a copy of `reentered`'s return value and use it to @@ -277,8 +277,12 @@ impl<'a, CL: Deref + 'a, C: Deref> BlockNotifier<'a pub fn block_connected(&self, block: &Block, height: u32) { let mut reentered = true; while reentered { - let (matched, matched_index) = self.chain_monitor.filter_block(block); - reentered = self.block_connected_checked(&block.header, height, matched.as_slice(), matched_index.as_slice()); + let matched_indexes = self.chain_monitor.filter_block(block); + let mut matched_txn = Vec::new(); + for index in matched_indexes.iter() { + matched_txn.push(&block.txdata[*index as usize]); + } + reentered = self.block_connected_checked(&block.header, height, matched_txn.as_slice(), matched_indexes.as_slice()); } } @@ -357,19 +361,17 @@ impl ChainWatchInterface for ChainWatchInterfaceUtil { Err(ChainError::NotSupported) } - fn filter_block<'a>(&self, block: &'a Block) -> (Vec<&'a Transaction>, Vec) { - let mut matched = Vec::new(); + fn filter_block(&self, block: &Block) -> Vec { let mut matched_index = Vec::new(); { let watched = self.watched.lock().unwrap(); for (index, transaction) in block.txdata.iter().enumerate() { if self.does_match_tx_unguarded(transaction, &watched) { - matched.push(transaction); matched_index.push(index as u32); } } } - (matched, matched_index) + matched_index } fn reentered(&self) -> usize { diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index c6302b906..145465ef4 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -371,8 +371,8 @@ impl ChainWatchInterface for TestChainWatcher { fn install_watch_tx(&self, _txid: &Txid, _script_pub_key: &Script) { } fn install_watch_outpoint(&self, _outpoint: (Txid, u32), _out_script: &Script) { } fn watch_all_txn(&self) { } - fn filter_block<'a>(&self, _block: &'a Block) -> (Vec<&'a Transaction>, Vec) { - (Vec::new(), Vec::new()) + fn filter_block<'a>(&self, _block: &'a Block) -> Vec { + Vec::new() } fn reentered(&self) -> usize { 0 }