From abcabd1931a73bc03d554d42335603987a8803bf Mon Sep 17 00:00:00 2001 From: Marek Date: Tue, 20 Jun 2023 00:48:59 +0200 Subject: [PATCH] Use `OrderedUtxo` in `CheckpointVerifiedBlock` (#6971) --- zebra-state/src/arbitrary.rs | 3 ++- zebra-state/src/request.rs | 6 +++--- zebra-state/src/service.rs | 3 ++- .../service/finalized_state/zebra_db/block.rs | 18 ++++++++++++++---- zebra-state/src/service/pending_utxos.rs | 8 -------- zebra-state/src/service/queued_blocks.rs | 5 +++-- zebra-state/src/service/tests.rs | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/zebra-state/src/arbitrary.rs b/zebra-state/src/arbitrary.rs index f151e2c4..2a8eaa5e 100644 --- a/zebra-state/src/arbitrary.rs +++ b/zebra-state/src/arbitrary.rs @@ -183,7 +183,8 @@ impl CheckpointVerifiedBlock { height: block::Height, ) -> Self { let transaction_hashes: Arc<[_]> = block.transactions.iter().map(|tx| tx.hash()).collect(); - let new_outputs = transparent::new_outputs_with_height(&block, height, &transaction_hashes); + let new_outputs = + transparent::new_ordered_outputs_with_height(&block, height, &transaction_hashes); Self { block, diff --git a/zebra-state/src/request.rs b/zebra-state/src/request.rs index 6ffa7d3e..dbff9102 100644 --- a/zebra-state/src/request.rs +++ b/zebra-state/src/request.rs @@ -235,7 +235,7 @@ pub struct CheckpointVerifiedBlock { /// earlier transaction. /// /// This field can also contain unrelated outputs, which are ignored. - pub(crate) new_outputs: HashMap, + pub(crate) new_outputs: HashMap, /// A precomputed list of the hashes of the transactions in this block, /// in the same order as `block.transactions`. pub transaction_hashes: Arc<[transaction::Hash]>, @@ -369,7 +369,7 @@ impl CheckpointVerifiedBlock { .coinbase_height() .expect("coinbase height was already checked"); let transaction_hashes: Arc<[_]> = block.transactions.iter().map(|tx| tx.hash()).collect(); - let new_outputs = transparent::new_outputs(&block, &transaction_hashes); + let new_outputs = transparent::new_ordered_outputs(&block, &transaction_hashes); Self { block, @@ -405,7 +405,7 @@ impl From for CheckpointVerifiedBlock { block, hash, height, - new_outputs: utxos_from_ordered_utxos(new_outputs), + new_outputs, transaction_hashes, } } diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index 75d1f0ac..f88cd281 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -976,7 +976,8 @@ impl Service for StateService { // even though it is redundant for most finalized blocks. // (Finalized blocks are verified using block hash checkpoints // and transaction merkle tree block header commitments.) - self.pending_utxos.check_against(&finalized.new_outputs); + self.pending_utxos + .check_against_ordered(&finalized.new_outputs); // # Performance // diff --git a/zebra-state/src/service/finalized_state/zebra_db/block.rs b/zebra-state/src/service/finalized_state/zebra_db/block.rs index 8edc89e0..61e19100 100644 --- a/zebra-state/src/service/finalized_state/zebra_db/block.rs +++ b/zebra-state/src/service/finalized_state/zebra_db/block.rs @@ -305,10 +305,10 @@ impl ZebraDb { let new_outputs_by_out_loc: BTreeMap = finalized .new_outputs .iter() - .map(|(outpoint, utxo)| { + .map(|(outpoint, ordered_utxo)| { ( lookup_out_loc(finalized.height, outpoint, &tx_hash_indexes), - utxo.clone(), + ordered_utxo.utxo.clone(), ) }) .collect(); @@ -331,7 +331,12 @@ impl ZebraDb { }), self.utxo(&outpoint) .map(|ordered_utxo| ordered_utxo.utxo) - .or_else(|| finalized.new_outputs.get(&outpoint).cloned()) + .or_else(|| { + finalized + .new_outputs + .get(&outpoint) + .map(|ordered_utxo| ordered_utxo.utxo.clone()) + }) .expect("already checked UTXO was in state or block"), ) }) @@ -350,7 +355,12 @@ impl ZebraDb { // Get the transparent addresses with changed balances/UTXOs let changed_addresses: HashSet = spent_utxos_by_out_loc .values() - .chain(finalized.new_outputs.values()) + .chain( + finalized + .new_outputs + .values() + .map(|ordered_utxo| &ordered_utxo.utxo), + ) .filter_map(|utxo| utxo.output.address(network)) .unique() .collect(); diff --git a/zebra-state/src/service/pending_utxos.rs b/zebra-state/src/service/pending_utxos.rs index 953aba4a..c6071982 100644 --- a/zebra-state/src/service/pending_utxos.rs +++ b/zebra-state/src/service/pending_utxos.rs @@ -60,14 +60,6 @@ impl PendingUtxos { } } - /// Check the list of pending UTXO requests against the supplied [`transparent::Utxo`] index. - #[inline] - pub fn check_against(&mut self, utxos: &HashMap) { - for (outpoint, utxo) in utxos.iter() { - self.respond(outpoint, utxo.clone()) - } - } - /// Scan the set of waiting utxo requests for channels where all receivers /// have been dropped and remove the corresponding sender. pub fn prune(&mut self) { diff --git a/zebra-state/src/service/queued_blocks.rs b/zebra-state/src/service/queued_blocks.rs index 7a009605..41e93812 100644 --- a/zebra-state/src/service/queued_blocks.rs +++ b/zebra-state/src/service/queued_blocks.rs @@ -279,8 +279,9 @@ impl SentHashes { let outpoints = block .new_outputs .iter() - .map(|(outpoint, utxo)| { - self.known_utxos.insert(*outpoint, utxo.clone()); + .map(|(outpoint, ordered_utxo)| { + self.known_utxos + .insert(*outpoint, ordered_utxo.utxo.clone()); outpoint }) .cloned() diff --git a/zebra-state/src/service/tests.rs b/zebra-state/src/service/tests.rs index 5adfaabd..b7e55b9a 100644 --- a/zebra-state/src/service/tests.rs +++ b/zebra-state/src/service/tests.rs @@ -419,7 +419,7 @@ proptest! { // the genesis block has a zero-valued transparent output, // which is not included in the UTXO set if block.height > block::Height(0) { - let utxos = &block.new_outputs; + let utxos = &block.new_outputs.iter().map(|(k, ordered_utxo)| (*k, ordered_utxo.utxo.clone())).collect(); let block_value_pool = &block.block.chain_value_pool_change(utxos)?; expected_finalized_value_pool += *block_value_pool; }