cache pool value balances by height

This commit is contained in:
ar 2024-09-20 16:24:13 -04:00
parent 56ae48f635
commit 0ba36dd1a1
5 changed files with 27 additions and 17 deletions

View File

@ -392,7 +392,7 @@ impl ZebraDb {
spent_utxos_by_outpoint,
spent_utxos_by_out_loc,
address_balances,
self.finalized_value_pool(),
self.finalized_tip_value_pool(),
prev_note_commitment_trees,
)?;

View File

@ -60,7 +60,7 @@ pub const CHAIN_VALUE_POOLS: &str = "tip_chain_value_pool";
///
/// This constant should be used so the compiler can detect incorrectly typed accesses to the
/// column family.
pub type ChainValuePoolsCf<'cf> = TypedColumnFamily<'cf, (), ValueBalance<NonNegative>>;
pub type ChainValuePoolsCf<'cf> = TypedColumnFamily<'cf, Height, ValueBalance<NonNegative>>;
impl ZebraDb {
// Column family convenience methods
@ -154,12 +154,22 @@ impl ZebraDb {
// Value pool methods
/// Returns the stored `ValueBalance` for the best chain at the finalized tip height.
pub fn finalized_value_pool(&self) -> ValueBalance<NonNegative> {
/// Returns the stored `ValueBalance` for the best chain at the provided height.
pub fn finalized_value_pool(&self, height: Height) -> ValueBalance<NonNegative> {
let chain_value_pools_cf = self.chain_value_pools_cf();
chain_value_pools_cf
.zs_get(&())
.zs_get(&height)
.unwrap_or_else(ValueBalance::zero)
}
/// Returns the stored `ValueBalance` for the best chain at the finalized tip.
pub fn finalized_tip_value_pool(&self) -> ValueBalance<NonNegative> {
let chain_value_pools_cf = self.chain_value_pools_cf();
chain_value_pools_cf
.zs_last_key_value()
.map(|(_k, v)| v)
.unwrap_or_else(ValueBalance::zero)
}
}
@ -231,7 +241,7 @@ impl DiskWriteBatch {
.chain_value_pools_cf()
.with_batch_for_writing(self)
.zs_insert(
&(),
&finalized.height,
&value_pool.add_chain_value_pool_change(
finalized.block.chain_value_pool_change(
&utxos_spent_by_block,

View File

@ -288,7 +288,7 @@ impl NonFinalizedState {
finalized_state.sapling_tree_for_tip(),
finalized_state.orchard_tree_for_tip(),
finalized_state.history_tree(),
finalized_state.finalized_value_pool(),
finalized_state.finalized_tip_value_pool(),
);
let (height, hash) = (prepared.height, prepared.hash);

View File

@ -104,7 +104,7 @@ where
return Ok(None);
};
let value_balance = db.finalized_value_pool();
let value_balance = db.finalized_tip_value_pool();
if tip == db.tip() {
return Ok(Some((tip_height, tip_hash, value_balance)));

View File

@ -403,7 +403,7 @@ proptest! {
// We're waiting to verify each block here, so we don't need the maximum checkpoint height.
let (mut state_service, _, _, _) = StateService::new(Config::ephemeral(), &network, Height::MAX, 0);
prop_assert_eq!(state_service.read_service.db.finalized_value_pool(), ValueBalance::zero());
prop_assert_eq!(state_service.read_service.db.finalized_tip_value_pool(), ValueBalance::zero());
prop_assert_eq!(
state_service.read_service.latest_non_finalized_state().best_chain().map(|chain| chain.chain_value_pools).unwrap_or_else(ValueBalance::zero),
ValueBalance::zero()
@ -414,14 +414,14 @@ proptest! {
// the expected transparent pool value, calculated using the slow start rate
let mut expected_transparent_pool = ValueBalance::zero();
let mut expected_finalized_value_pool = Ok(ValueBalance::zero());
let mut expected_finalized_tip_value_pool = Ok(ValueBalance::zero());
for block in finalized_blocks {
// 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.iter().map(|(k, ordered_utxo)| (*k, ordered_utxo.utxo.clone())).collect();
let block_value_pool = &block.block.chain_value_pool_change(utxos, None)?;
expected_finalized_value_pool += *block_value_pool;
expected_finalized_tip_value_pool += *block_value_pool;
}
let result_receiver = state_service.queue_and_commit_to_finalized_state(block.clone());
@ -430,8 +430,8 @@ proptest! {
prop_assert!(result.is_ok(), "unexpected failed finalized block commit: {:?}", result);
prop_assert_eq!(
state_service.read_service.db.finalized_value_pool(),
expected_finalized_value_pool.clone()?.constrain()?
state_service.read_service.db.finalized_tip_value_pool(),
expected_finalized_tip_value_pool.clone()?.constrain()?
);
let transparent_value = SLOW_START_RATE * i64::from(block.height.0);
@ -439,16 +439,16 @@ proptest! {
let transparent_value = ValueBalance::from_transparent_amount(transparent_value);
expected_transparent_pool = (expected_transparent_pool + transparent_value).unwrap();
prop_assert_eq!(
state_service.read_service.db.finalized_value_pool(),
state_service.read_service.db.finalized_tip_value_pool(),
expected_transparent_pool
);
}
let mut expected_non_finalized_value_pool = Ok(expected_finalized_value_pool?);
let mut expected_non_finalized_tip_value_pool = Ok(expected_finalized_tip_value_pool?);
for block in non_finalized_blocks {
let utxos = block.new_outputs.clone();
let block_value_pool = &block.block.chain_value_pool_change(&transparent::utxos_from_ordered_utxos(utxos), None)?;
expected_non_finalized_value_pool += *block_value_pool;
expected_non_finalized_tip_value_pool += *block_value_pool;
let result_receiver = state_service.queue_and_commit_to_non_finalized_state(block.clone());
let result = result_receiver.blocking_recv();
@ -457,7 +457,7 @@ proptest! {
prop_assert_eq!(
state_service.read_service.latest_non_finalized_state().best_chain().unwrap().chain_value_pools,
expected_non_finalized_value_pool.clone()?.constrain()?
expected_non_finalized_tip_value_pool.clone()?.constrain()?
);
let transparent_value = SLOW_START_RATE * i64::from(block.height.0);