Skip to content

Commit

Permalink
Adds new column family for [spent_out_loc] -> [spending_tx_loc] with …
Browse files Browse the repository at this point in the history
…a read method and an update to `prepare_spending_transparent_tx_ids_batch()` for maintaining it when committing blocks to the finalized state.

Adds TODOs for remaining production changes needed for issue #8837.
  • Loading branch information
arya2 committed Nov 22, 2024
1 parent 4f0746a commit e9b3930
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 7 deletions.
2 changes: 2 additions & 0 deletions zebra-state/src/service/finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::{
};

use zebra_chain::{block, parallel::tree::NoteCommitmentTrees, parameters::Network};
use zebra_db::transparent::TX_LOC_BY_SPENT_OUT_LOC;

use crate::{
constants::{state_database_format_version_in_code, STATE_DATABASE_KIND},
Expand Down Expand Up @@ -77,6 +78,7 @@ pub const STATE_COLUMN_FAMILIES_IN_CODE: &[&str] = &[
"tx_loc_by_transparent_addr_loc",
"utxo_by_out_loc",
"utxo_loc_by_transparent_addr_loc",
TX_LOC_BY_SPENT_OUT_LOC,
// Sprout
"sprout_nullifiers",
"sprout_anchors",
Expand Down
9 changes: 8 additions & 1 deletion zebra-state/src/service/finalized_state/zebra_db/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ impl ZebraDb {
.iter()
.map(|(outpoint, _output_loc, utxo)| (*outpoint, utxo.clone()))
.collect();
let out_loc_by_outpoint: HashMap<transparent::OutPoint, OutputLocation> = spent_utxos
.iter()
.map(|(outpoint, out_loc, _utxo)| (*outpoint, *out_loc))
.collect();
let spent_utxos_by_out_loc: BTreeMap<OutputLocation, transparent::Utxo> = spent_utxos
.into_iter()
.map(|(_outpoint, out_loc, utxo)| (out_loc, utxo))
Expand Down Expand Up @@ -392,6 +396,7 @@ impl ZebraDb {
new_outputs_by_out_loc,
spent_utxos_by_outpoint,
spent_utxos_by_out_loc,
out_loc_by_outpoint,
address_balances,
self.finalized_value_pool(),
prev_note_commitment_trees,
Expand Down Expand Up @@ -448,6 +453,7 @@ impl DiskWriteBatch {
new_outputs_by_out_loc: BTreeMap<OutputLocation, transparent::Utxo>,
spent_utxos_by_outpoint: HashMap<transparent::OutPoint, transparent::Utxo>,
spent_utxos_by_out_loc: BTreeMap<OutputLocation, transparent::Utxo>,
out_loc_by_outpoint: HashMap<transparent::OutPoint, OutputLocation>,
address_balances: HashMap<transparent::Address, AddressBalanceLocation>,
value_pool: ValueBalance<NonNegative>,
prev_note_commitment_trees: Option<NoteCommitmentTrees>,
Expand Down Expand Up @@ -479,12 +485,13 @@ impl DiskWriteBatch {
if !finalized.height.is_min() {
// Commit transaction indexes
self.prepare_transparent_transaction_batch(
db,
zebra_db,
network,
finalized,
&new_outputs_by_out_loc,
&spent_utxos_by_outpoint,
&spent_utxos_by_out_loc,
&out_loc_by_outpoint,
address_balances,
)?;

Expand Down
59 changes: 53 additions & 6 deletions zebra-state/src/service/finalized_state/zebra_db/transparent.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Provides high-level access to database:
//! - unspent [`transparent::Output`]s (UTXOs), and
//! - unspent [`transparent::Output`]s (UTXOs),
//! - spent [`transparent::Output`]s, and
//! - transparent address indexes.
//!
//! This module makes sure that:
Expand Down Expand Up @@ -37,12 +38,44 @@ use crate::{
},
zebra_db::ZebraDb,
},
BoxError,
BoxError, TypedColumnFamily,
};

/// The name of the transaction hash by spent outpoints column family.
///
/// This constant should be used so the compiler can detect typos.
pub const TX_LOC_BY_SPENT_OUT_LOC: &str = "tx_loc_by_spent_out_loc";

/// The type for reading value pools from the database.
///
/// This constant should be used so the compiler can detect incorrectly typed accesses to the
/// column family.
pub type TransactionLocationBySpentOutputLocationCf<'cf> =
TypedColumnFamily<'cf, OutputLocation, TransactionLocation>;

impl ZebraDb {
// Column family convenience methods

/// Returns a typed handle to the transaction location by spent output location column family.
pub(crate) fn tx_loc_by_spent_output_loc_cf(
&self,
) -> TransactionLocationBySpentOutputLocationCf {
TransactionLocationBySpentOutputLocationCf::new(&self.db, TX_LOC_BY_SPENT_OUT_LOC)
.expect("column family was created when database was created")
}

// Read transparent methods

/// Returns the [`TransactionLocation`] for a transaction that spent the output
/// at the provided [`OutputLocation`], if it is in the finalized state.
#[allow(clippy::unwrap_in_result)]
pub fn tx_loc_by_spent_output_loc(
&self,
output_location: &OutputLocation,
) -> Option<TransactionLocation> {
self.tx_loc_by_spent_output_loc_cf().zs_get(output_location)
}

/// Returns the [`AddressBalanceLocation`] for a [`transparent::Address`],
/// if it is in the finalized state.
#[allow(clippy::unwrap_in_result)]
Expand Down Expand Up @@ -342,14 +375,16 @@ impl DiskWriteBatch {
#[allow(clippy::too_many_arguments)]
pub fn prepare_transparent_transaction_batch(
&mut self,
db: &DiskDb,
zebra_db: &ZebraDb,
network: &Network,
finalized: &FinalizedBlock,
new_outputs_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
spent_utxos_by_outpoint: &HashMap<transparent::OutPoint, transparent::Utxo>,
spent_utxos_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
out_loc_by_outpoint: &HashMap<transparent::OutPoint, OutputLocation>,
mut address_balances: HashMap<transparent::Address, AddressBalanceLocation>,
) -> Result<(), BoxError> {
let db = &zebra_db.db;
let FinalizedBlock { block, height, .. } = finalized;

// Update created and spent transparent outputs
Expand All @@ -371,11 +406,12 @@ impl DiskWriteBatch {
let spending_tx_location = TransactionLocation::from_usize(*height, tx_index);

self.prepare_spending_transparent_tx_ids_batch(
db,
zebra_db,
network,
spending_tx_location,
transaction,
spent_utxos_by_outpoint,
out_loc_by_outpoint,
&address_balances,
)?;
}
Expand Down Expand Up @@ -531,16 +567,18 @@ impl DiskWriteBatch {
/// # Errors
///
/// - This method doesn't currently return any errors, but it might in future
#[allow(clippy::unwrap_in_result)]
#[allow(clippy::unwrap_in_result, clippy::too_many_arguments)]
pub fn prepare_spending_transparent_tx_ids_batch(
&mut self,
db: &DiskDb,
zebra_db: &ZebraDb,
network: &Network,
spending_tx_location: TransactionLocation,
transaction: &Transaction,
spent_utxos_by_outpoint: &HashMap<transparent::OutPoint, transparent::Utxo>,
out_loc_by_outpoint: &HashMap<transparent::OutPoint, OutputLocation>,
address_balances: &HashMap<transparent::Address, AddressBalanceLocation>,
) -> Result<(), BoxError> {
let db = &zebra_db.db;
let tx_loc_by_transparent_addr_loc =
db.cf_handle("tx_loc_by_transparent_addr_loc").unwrap();

Expand Down Expand Up @@ -569,6 +607,15 @@ impl DiskWriteBatch {
AddressTransaction::new(sending_address_location, spending_tx_location);
self.zs_insert(&tx_loc_by_transparent_addr_loc, address_transaction, ());
}

let spent_output_location = out_loc_by_outpoint
.get(&spent_outpoint)
.expect("spent outpoints must already have output locations");

let _ = zebra_db
.tx_loc_by_spent_output_loc_cf()
.with_batch_for_writing(self)
.zs_insert(spent_output_location, &spending_tx_location);
}

Ok(())
Expand Down
9 changes: 9 additions & 0 deletions zebra-state/src/service/non_finalized_state/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ pub struct ChainInner {
/// including those created by earlier transactions or blocks in the chain.
pub(crate) spent_utxos: HashSet<transparent::OutPoint>,

// TODO:
// - Add a field for tracking spending tx ids by spent outpoint
// - Update the field when committing blocks to non-finalized chain
// - Add a read fn for querying tx ids by spent outpoint
// - Add a db format upgrade for indexing spending tx ids (transaction locations) by
// spent outpoints (output locations) in the finalized state
// - Add ReadRequest & ReadResponse variants for querying spending tx ids by
// spent outpoints and handle them in the ReadStateService

// Note commitment trees
//
/// The Sprout note commitment tree for each anchor.
Expand Down

0 comments on commit e9b3930

Please sign in to comment.