Make ChainWatchInterface::filter_block return only idxes, not refs
authorMatt Corallo <git@bluematt.me>
Sat, 13 Jun 2020 21:33:21 +0000 (17:33 -0400)
committerMatt Corallo <git@bluematt.me>
Tue, 23 Jun 2020 20:12:55 +0000 (16:12 -0400)
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).

fuzz/src/router.rs
lightning/src/chain/chaininterface.rs
lightning/src/util/test_utils.rs

index f388399ab8ab3750e1c63566a89c0e06976f34d3..c79ebb7b4e35712c44ec6083ff0d74375b712fab 100644 (file)
@@ -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<u32>) {
-               (Vec::new(), Vec::new())
+       fn filter_block(&self, _block: &Block) -> Vec<u32> {
+               Vec::new()
        }
        fn reentered(&self) -> usize { 0 }
 
index 5cd87c49f6df717f017802363782e348bc1664f7..7c215f3635c88c17045d2c61aa71f585f3aab2f7 100644 (file)
@@ -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<u32>);
+       fn filter_block(&self, block: &Block) -> Vec<u32>;
 
        /// 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<Target = ChainListener + 'a> + '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<u32>) {
-               let mut matched = Vec::new();
+       fn filter_block(&self, block: &Block) -> Vec<u32> {
                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 {
index c6302b9062d8525bf2d1b7b974e8f45415676ba8..145465ef40b80cb710915011f8b5ff54128cd4f8 100644 (file)
@@ -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<u32>) {
-               (Vec::new(), Vec::new())
+       fn filter_block<'a>(&self, _block: &'a Block) -> Vec<u32> {
+               Vec::new()
        }
        fn reentered(&self) -> usize { 0 }