fix(state): Update column family names to match Zebra's database design (#4639)
* Rename `block_by_height` to `block_header_by_height` in fin state * Rename `tx_by_hash` to `tx_loc_by_hash` in both (non & fin) states * Rename `utxo_by_outpoint` to `utxo_by_out_loc` in finalized state * Reorder the column families so that they match the docs * Update `struct Chain` in the RFCs * Increment `DATABASE_FORMAT_VERSION` to 25 * Remove obsolete docs from `0004-asynchronous-script-verification.md` * Remove an obsolete `TODO` from `disk_db.rs` * Delete unused snapshots Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
11dcc13b84
commit
32faa94fb4
|
@ -422,16 +422,3 @@ cleaner and the cost is probably not too large.
|
|||
- We need to pick a timeout for UTXO lookup. This should be long enough to
|
||||
account for the fact that we may start verifying blocks before all of their
|
||||
ancestors are downloaded.
|
||||
|
||||
These optimisations can be delayed until after the initial implementation is
|
||||
complete, and covered by tests:
|
||||
|
||||
- Should we stop storing heights for non-coinbase UTXOs? (#2455)
|
||||
|
||||
- Should we avoid storing any extra data for UTXOs, and just lookup the coinbase
|
||||
flag and height using `outpoint.hash` and `tx_by_hash`? (#2455)
|
||||
|
||||
- The maturity check can be skipped for UTXOs from the finalized state,
|
||||
because Zebra only finalizes mature UTXOs. We could implement this
|
||||
optimisation by adding a `Utxo::MatureCoinbase { output: transparent::Output }`
|
||||
variant, which only performs the spend checks. (#2455)
|
||||
|
|
|
@ -268,20 +268,90 @@ is completely empty.
|
|||
The `Chain` type is defined by the following struct and API:
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Default, Clone)]
|
||||
struct Chain {
|
||||
blocks: BTreeMap<block::Height, Arc<Block>>,
|
||||
height_by_hash: HashMap<block::Hash, block::Height>,
|
||||
tx_by_hash: HashMap<transaction::Hash, (block::Height, usize)>,
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Chain {
|
||||
// The function `eq_internal_state` must be updated every time a field is added to [`Chain`].
|
||||
/// The configured network for this chain.
|
||||
network: Network,
|
||||
|
||||
created_utxos: HashSet<transparent::OutPoint>,
|
||||
spent_utxos: HashSet<transparent::OutPoint>,
|
||||
sprout_anchors: HashSet<sprout::tree::Root>,
|
||||
sapling_anchors: HashSet<sapling::tree::Root>,
|
||||
sprout_nullifiers: HashSet<sprout::Nullifier>,
|
||||
sapling_nullifiers: HashSet<sapling::Nullifier>,
|
||||
orchard_nullifiers: HashSet<orchard::Nullifier>,
|
||||
partial_cumulative_work: PartialCumulativeWork,
|
||||
/// The contextually valid blocks which form this non-finalized partial chain, in height order.
|
||||
pub(crate) blocks: BTreeMap<block::Height, ContextuallyValidBlock>,
|
||||
|
||||
/// An index of block heights for each block hash in `blocks`.
|
||||
pub height_by_hash: HashMap<block::Hash, block::Height>,
|
||||
|
||||
/// An index of [`TransactionLocation`]s for each transaction hash in `blocks`.
|
||||
pub tx_loc_by_hash: HashMap<transaction::Hash, TransactionLocation>,
|
||||
|
||||
/// The [`transparent::Utxo`]s created by `blocks`.
|
||||
///
|
||||
/// Note that these UTXOs may not be unspent.
|
||||
/// Outputs can be spent by later transactions or blocks in the chain.
|
||||
//
|
||||
// TODO: replace OutPoint with OutputLocation?
|
||||
pub(crate) created_utxos: HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
|
||||
/// The [`transparent::OutPoint`]s spent by `blocks`,
|
||||
/// including those created by earlier transactions or blocks in the chain.
|
||||
pub(crate) spent_utxos: HashSet<transparent::OutPoint>,
|
||||
|
||||
/// The Sprout note commitment tree of the tip of this [`Chain`],
|
||||
/// including all finalized notes, and the non-finalized notes in this chain.
|
||||
pub(super) sprout_note_commitment_tree: sprout::tree::NoteCommitmentTree,
|
||||
/// The Sprout note commitment tree for each anchor.
|
||||
/// This is required for interstitial states.
|
||||
pub(crate) sprout_trees_by_anchor:
|
||||
HashMap<sprout::tree::Root, sprout::tree::NoteCommitmentTree>,
|
||||
/// The Sapling note commitment tree of the tip of this [`Chain`],
|
||||
/// including all finalized notes, and the non-finalized notes in this chain.
|
||||
pub(super) sapling_note_commitment_tree: sapling::tree::NoteCommitmentTree,
|
||||
/// The Sapling note commitment tree for each height.
|
||||
pub(crate) sapling_trees_by_height: BTreeMap<block::Height, sapling::tree::NoteCommitmentTree>,
|
||||
/// The Orchard note commitment tree of the tip of this [`Chain`],
|
||||
/// including all finalized notes, and the non-finalized notes in this chain.
|
||||
pub(super) orchard_note_commitment_tree: orchard::tree::NoteCommitmentTree,
|
||||
/// The Orchard note commitment tree for each height.
|
||||
pub(crate) orchard_trees_by_height: BTreeMap<block::Height, orchard::tree::NoteCommitmentTree>,
|
||||
/// The ZIP-221 history tree of the tip of this [`Chain`],
|
||||
/// including all finalized blocks, and the non-finalized `blocks` in this chain.
|
||||
pub(crate) history_tree: HistoryTree,
|
||||
|
||||
/// The Sprout anchors created by `blocks`.
|
||||
pub(crate) sprout_anchors: MultiSet<sprout::tree::Root>,
|
||||
/// The Sprout anchors created by each block in `blocks`.
|
||||
pub(crate) sprout_anchors_by_height: BTreeMap<block::Height, sprout::tree::Root>,
|
||||
/// The Sapling anchors created by `blocks`.
|
||||
pub(crate) sapling_anchors: MultiSet<sapling::tree::Root>,
|
||||
/// The Sapling anchors created by each block in `blocks`.
|
||||
pub(crate) sapling_anchors_by_height: BTreeMap<block::Height, sapling::tree::Root>,
|
||||
/// The Orchard anchors created by `blocks`.
|
||||
pub(crate) orchard_anchors: MultiSet<orchard::tree::Root>,
|
||||
/// The Orchard anchors created by each block in `blocks`.
|
||||
pub(crate) orchard_anchors_by_height: BTreeMap<block::Height, orchard::tree::Root>,
|
||||
|
||||
/// The Sprout nullifiers revealed by `blocks`.
|
||||
pub(super) sprout_nullifiers: HashSet<sprout::Nullifier>,
|
||||
/// The Sapling nullifiers revealed by `blocks`.
|
||||
pub(super) sapling_nullifiers: HashSet<sapling::Nullifier>,
|
||||
/// The Orchard nullifiers revealed by `blocks`.
|
||||
pub(super) orchard_nullifiers: HashSet<orchard::Nullifier>,
|
||||
|
||||
/// Partial transparent address index data from `blocks`.
|
||||
pub(super) partial_transparent_transfers: HashMap<transparent::Address, TransparentTransfers>,
|
||||
|
||||
/// The cumulative work represented by `blocks`.
|
||||
///
|
||||
/// Since the best chain is determined by the largest cumulative work,
|
||||
/// the work represented by finalized blocks can be ignored,
|
||||
/// because they are common to all non-finalized chains.
|
||||
pub(super) partial_cumulative_work: PartialCumulativeWork,
|
||||
|
||||
/// The chain value pool balances of the tip of this [`Chain`],
|
||||
/// including the block value pool changes from all finalized blocks,
|
||||
/// and the non-finalized blocks in this chain.
|
||||
///
|
||||
/// When a new chain is created from the finalized tip,
|
||||
/// it is initialized with the finalized tip chain value pool balances.
|
||||
pub(crate) chain_value_pools: ValueBalance<NonNegative>,
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -293,7 +363,7 @@ Push a block into a chain as the new tip
|
|||
- Add the block's hash to `height_by_hash`
|
||||
- Add work to `self.partial_cumulative_work`
|
||||
- For each `transaction` in `block`
|
||||
- Add key: `transaction.hash` and value: `(height, tx_index)` to `tx_by_hash`
|
||||
- Add key: `transaction.hash` and value: `(height, tx_index)` to `tx_loc_by_hash`
|
||||
- Add created utxos to `self.created_utxos`
|
||||
- Add spent utxos to `self.spent_utxos`
|
||||
- Add nullifiers to the appropriate `self.<version>_nullifiers`
|
||||
|
@ -310,7 +380,7 @@ Remove the lowest height block of the non-finalized portion of a chain.
|
|||
- Remove the block's hash from `self.height_by_hash`
|
||||
- Subtract work from `self.partial_cumulative_work`
|
||||
- For each `transaction` in `block`
|
||||
- Remove `transaction.hash` from `tx_by_hash`
|
||||
- Remove `transaction.hash` from `tx_loc_by_hash`
|
||||
- Remove created utxos from `self.created_utxos`
|
||||
- Remove spent utxos from `self.spent_utxos`
|
||||
- Remove the nullifiers from the appropriate `self.<version>_nullifiers`
|
||||
|
@ -340,7 +410,7 @@ Remove the highest height block of the non-finalized portion of a chain.
|
|||
- Remove the corresponding hash from `self.height_by_hash`
|
||||
- Subtract work from `self.partial_cumulative_work`
|
||||
- for each `transaction` in `block`
|
||||
- remove `transaction.hash` from `tx_by_hash`
|
||||
- remove `transaction.hash` from `tx_loc_by_hash`
|
||||
- Remove created utxos from `self.created_utxos`
|
||||
- Remove spent utxos from `self.spent_utxos`
|
||||
- Remove the nullifiers from the appropriate `self.<version>_nullifiers`
|
||||
|
@ -365,7 +435,7 @@ parent block is the tip of the finalized state. This implementation should be
|
|||
handled by `#[derive(Default)]`.
|
||||
|
||||
1. initialise cumulative data members
|
||||
- Construct an empty `self.blocks`, `height_by_hash`, `tx_by_hash`,
|
||||
- Construct an empty `self.blocks`, `height_by_hash`, `tx_loc_by_hash`,
|
||||
`self.created_utxos`, `self.spent_utxos`, `self.<version>_anchors`,
|
||||
`self.<version>_nullifiers`
|
||||
- Zero `self.partial_cumulative_work`
|
||||
|
@ -1102,13 +1172,14 @@ Returns
|
|||
|
||||
Implemented by querying:
|
||||
|
||||
- (non-finalized) the `tx_by_hash` map (to get the block that contains the
|
||||
- (non-finalized) the `tx_loc_by_hash` map (to get the block that contains the
|
||||
transaction) of each chain starting with the best chain, and then find
|
||||
block that chain's `blocks` (to get the block containing the transaction
|
||||
data)
|
||||
- (finalized) the `tx_by_hash` tree (to get the block that contains the
|
||||
transaction) and then `block_by_height` tree (to get the block containing
|
||||
the transaction data), if the transaction is not in any non-finalized chain
|
||||
- (finalized) the `tx_loc_by_hash` tree (to get the block that contains the
|
||||
transaction) and then `block_header_by_height` tree (to get the block
|
||||
containing the transaction data), if the transaction is not in any
|
||||
non-finalized chain
|
||||
|
||||
### `Request::Block(block::Hash)`
|
||||
[request-block]: #request-block
|
||||
|
@ -1125,8 +1196,9 @@ Implemented by querying:
|
|||
|
||||
- (non-finalized) the `height_by_hash` of each chain starting with the best
|
||||
chain, then find block that chain's `blocks` (to get the block data)
|
||||
- (finalized) the `height_by_hash` tree (to get the block height) and then
|
||||
the `block_by_height` tree (to get the block data), if the block is not in any non-finalized chain
|
||||
- (finalized) the `height_by_hash` tree (to get the block height) and then the
|
||||
`block_header_by_height` tree (to get the block data), if the block is not in
|
||||
any non-finalized chain
|
||||
|
||||
### `Request::AwaitSpendableUtxo { outpoint: OutPoint, spend_height: Height, spend_restriction: SpendRestriction }`
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ pub use zebra_chain::transparent::MIN_TRANSPARENT_COINBASE_MATURITY;
|
|||
pub const MAX_BLOCK_REORG_HEIGHT: u32 = MIN_TRANSPARENT_COINBASE_MATURITY - 1;
|
||||
|
||||
/// The database format version, incremented each time the database format changes.
|
||||
pub const DATABASE_FORMAT_VERSION: u32 = 24;
|
||||
pub const DATABASE_FORMAT_VERSION: u32 = 25;
|
||||
|
||||
/// The maximum number of blocks to check for NU5 transactions,
|
||||
/// before we assume we are on a pre-NU5 legacy chain.
|
||||
|
|
|
@ -369,29 +369,24 @@ impl DiskDb {
|
|||
|
||||
let column_families = vec![
|
||||
// Blocks
|
||||
// TODO: rename to block_header_by_height (#3151)
|
||||
rocksdb::ColumnFamilyDescriptor::new("block_by_height", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("hash_by_height", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("height_by_hash", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("block_header_by_height", db_options.clone()),
|
||||
// Transactions
|
||||
rocksdb::ColumnFamilyDescriptor::new("tx_by_loc", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("hash_by_tx_loc", db_options.clone()),
|
||||
// TODO: rename to tx_loc_by_hash (#3950)
|
||||
rocksdb::ColumnFamilyDescriptor::new("tx_by_hash", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("tx_loc_by_hash", db_options.clone()),
|
||||
// Transparent
|
||||
rocksdb::ColumnFamilyDescriptor::new("balance_by_transparent_addr", db_options.clone()),
|
||||
// TODO: #3951
|
||||
//rocksdb::ColumnFamilyDescriptor::new("tx_by_transparent_addr_loc", db_options.clone()),
|
||||
// TODO: rename to utxo_by_out_loc (#3952)
|
||||
rocksdb::ColumnFamilyDescriptor::new("utxo_by_outpoint", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new(
|
||||
"utxo_loc_by_transparent_addr_loc",
|
||||
db_options.clone(),
|
||||
),
|
||||
rocksdb::ColumnFamilyDescriptor::new(
|
||||
"tx_loc_by_transparent_addr_loc",
|
||||
db_options.clone(),
|
||||
),
|
||||
rocksdb::ColumnFamilyDescriptor::new("utxo_by_out_loc", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new(
|
||||
"utxo_loc_by_transparent_addr_loc",
|
||||
db_options.clone(),
|
||||
),
|
||||
// Sprout
|
||||
rocksdb::ColumnFamilyDescriptor::new("sprout_nullifiers", db_options.clone()),
|
||||
rocksdb::ColumnFamilyDescriptor::new("sprout_anchors", db_options.clone()),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 72
|
||||
expression: cf_names
|
||||
---
|
||||
[
|
||||
"balance_by_transparent_addr",
|
||||
"block_by_height",
|
||||
"block_header_by_height",
|
||||
"default",
|
||||
"hash_by_height",
|
||||
"hash_by_tx_loc",
|
||||
|
@ -20,9 +21,9 @@ expression: cf_names
|
|||
"sprout_note_commitment_tree",
|
||||
"sprout_nullifiers",
|
||||
"tip_chain_value_pool",
|
||||
"tx_by_hash",
|
||||
"tx_by_loc",
|
||||
"tx_loc_by_hash",
|
||||
"tx_loc_by_transparent_addr_loc",
|
||||
"utxo_by_outpoint",
|
||||
"utxo_by_out_loc",
|
||||
"utxo_loc_by_transparent_addr_loc",
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 154
|
||||
expression: empty_column_families
|
||||
---
|
||||
[
|
||||
|
@ -13,6 +14,6 @@ expression: empty_column_families
|
|||
"sprout_nullifiers: no entries",
|
||||
"tip_chain_value_pool: no entries",
|
||||
"tx_loc_by_transparent_addr_loc: no entries",
|
||||
"utxo_by_outpoint: no entries",
|
||||
"utxo_by_out_loc: no entries",
|
||||
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||
]
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 154
|
||||
expression: empty_column_families
|
||||
---
|
||||
[
|
||||
"balance_by_transparent_addr: no entries",
|
||||
"block_by_height: no entries",
|
||||
"block_header_by_height: no entries",
|
||||
"hash_by_height: no entries",
|
||||
"hash_by_tx_loc: no entries",
|
||||
"height_by_hash: no entries",
|
||||
|
@ -19,9 +20,9 @@ expression: empty_column_families
|
|||
"sprout_note_commitment_tree: no entries",
|
||||
"sprout_nullifiers: no entries",
|
||||
"tip_chain_value_pool: no entries",
|
||||
"tx_by_hash: no entries",
|
||||
"tx_by_loc: no entries",
|
||||
"tx_loc_by_hash: no entries",
|
||||
"tx_loc_by_transparent_addr_loc: no entries",
|
||||
"utxo_by_outpoint: no entries",
|
||||
"utxo_by_out_loc: no entries",
|
||||
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 154
|
||||
expression: empty_column_families
|
||||
---
|
||||
[
|
||||
|
@ -13,6 +14,6 @@ expression: empty_column_families
|
|||
"sprout_nullifiers: no entries",
|
||||
"tip_chain_value_pool: no entries",
|
||||
"tx_loc_by_transparent_addr_loc: no entries",
|
||||
"utxo_by_outpoint: no entries",
|
||||
"utxo_by_out_loc: no entries",
|
||||
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||
assertion_line: 144
|
||||
expression: cf_data
|
||||
---
|
||||
[
|
|
@ -86,7 +86,7 @@ impl ZebraDb {
|
|||
#[allow(clippy::unwrap_in_result)]
|
||||
pub fn block(&self, hash_or_height: HashOrHeight) -> Option<Arc<Block>> {
|
||||
// Blocks
|
||||
let block_header_by_height = self.db.cf_handle("block_by_height").unwrap();
|
||||
let block_header_by_height = self.db.cf_handle("block_header_by_height").unwrap();
|
||||
let height_by_hash = self.db.cf_handle("height_by_hash").unwrap();
|
||||
|
||||
let height =
|
||||
|
@ -174,7 +174,7 @@ impl ZebraDb {
|
|||
/// if it exists in the finalized chain.
|
||||
#[allow(clippy::unwrap_in_result)]
|
||||
pub fn transaction_location(&self, hash: transaction::Hash) -> Option<TransactionLocation> {
|
||||
let tx_loc_by_hash = self.db.cf_handle("tx_by_hash").unwrap();
|
||||
let tx_loc_by_hash = self.db.cf_handle("tx_loc_by_hash").unwrap();
|
||||
self.db.zs_get(&tx_loc_by_hash, &hash)
|
||||
}
|
||||
|
||||
|
@ -422,14 +422,14 @@ impl DiskWriteBatch {
|
|||
finalized: &FinalizedBlock,
|
||||
) -> Result<(), BoxError> {
|
||||
// Blocks
|
||||
let block_header_by_height = db.cf_handle("block_by_height").unwrap();
|
||||
let block_header_by_height = db.cf_handle("block_header_by_height").unwrap();
|
||||
let hash_by_height = db.cf_handle("hash_by_height").unwrap();
|
||||
let height_by_hash = db.cf_handle("height_by_hash").unwrap();
|
||||
|
||||
// Transactions
|
||||
let tx_by_loc = db.cf_handle("tx_by_loc").unwrap();
|
||||
let hash_by_tx_loc = db.cf_handle("hash_by_tx_loc").unwrap();
|
||||
let tx_loc_by_hash = db.cf_handle("tx_by_hash").unwrap();
|
||||
let tx_loc_by_hash = db.cf_handle("tx_loc_by_hash").unwrap();
|
||||
|
||||
let FinalizedBlock {
|
||||
block,
|
||||
|
|
|
@ -95,7 +95,7 @@ impl ZebraDb {
|
|||
&self,
|
||||
output_location: OutputLocation,
|
||||
) -> Option<transparent::OrderedUtxo> {
|
||||
let utxo_by_out_loc = self.db.cf_handle("utxo_by_outpoint").unwrap();
|
||||
let utxo_by_out_loc = self.db.cf_handle("utxo_by_out_loc").unwrap();
|
||||
|
||||
let output = self.db.zs_get(&utxo_by_out_loc, &output_location)?;
|
||||
|
||||
|
@ -425,7 +425,7 @@ impl DiskWriteBatch {
|
|||
new_outputs_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
|
||||
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
||||
) -> Result<(), BoxError> {
|
||||
let utxo_by_out_loc = db.cf_handle("utxo_by_outpoint").unwrap();
|
||||
let utxo_by_out_loc = db.cf_handle("utxo_by_out_loc").unwrap();
|
||||
let utxo_loc_by_transparent_addr_loc =
|
||||
db.cf_handle("utxo_loc_by_transparent_addr_loc").unwrap();
|
||||
let tx_loc_by_transparent_addr_loc =
|
||||
|
@ -501,7 +501,7 @@ impl DiskWriteBatch {
|
|||
spent_utxos_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
|
||||
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
||||
) -> Result<(), BoxError> {
|
||||
let utxo_by_out_loc = db.cf_handle("utxo_by_outpoint").unwrap();
|
||||
let utxo_by_out_loc = db.cf_handle("utxo_by_out_loc").unwrap();
|
||||
let utxo_loc_by_transparent_addr_loc =
|
||||
db.cf_handle("utxo_loc_by_transparent_addr_loc").unwrap();
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ pub struct Chain {
|
|||
pub height_by_hash: HashMap<block::Hash, block::Height>,
|
||||
|
||||
/// An index of [`TransactionLocation`]s for each transaction hash in `blocks`.
|
||||
pub tx_by_hash: HashMap<transaction::Hash, TransactionLocation>,
|
||||
pub tx_loc_by_hash: HashMap<transaction::Hash, TransactionLocation>,
|
||||
|
||||
/// The [`transparent::Utxo`]s created by `blocks`.
|
||||
///
|
||||
|
@ -135,7 +135,7 @@ impl Chain {
|
|||
network,
|
||||
blocks: Default::default(),
|
||||
height_by_hash: Default::default(),
|
||||
tx_by_hash: Default::default(),
|
||||
tx_loc_by_hash: Default::default(),
|
||||
created_utxos: Default::default(),
|
||||
sprout_note_commitment_tree,
|
||||
sapling_note_commitment_tree,
|
||||
|
@ -177,7 +177,7 @@ impl Chain {
|
|||
// blocks, heights, hashes
|
||||
self.blocks == other.blocks &&
|
||||
self.height_by_hash == other.height_by_hash &&
|
||||
self.tx_by_hash == other.tx_by_hash &&
|
||||
self.tx_loc_by_hash == other.tx_loc_by_hash &&
|
||||
|
||||
// transparent UTXOs
|
||||
self.created_utxos == other.created_utxos &&
|
||||
|
@ -355,7 +355,7 @@ impl Chain {
|
|||
&self,
|
||||
hash: transaction::Hash,
|
||||
) -> Option<(&Arc<Transaction>, block::Height)> {
|
||||
self.tx_by_hash.get(&hash).map(|tx_loc| {
|
||||
self.tx_loc_by_hash.get(&hash).map(|tx_loc| {
|
||||
(
|
||||
&self.blocks[&tx_loc.height].block.transactions[tx_loc.index.as_usize()],
|
||||
tx_loc.height,
|
||||
|
@ -625,7 +625,9 @@ impl Chain {
|
|||
query_height_range: RangeInclusive<Height>,
|
||||
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
||||
self.partial_transparent_indexes(addresses)
|
||||
.flat_map(|transfers| transfers.tx_ids(&self.tx_by_hash, query_height_range.clone()))
|
||||
.flat_map(|transfers| {
|
||||
transfers.tx_ids(&self.tx_loc_by_hash, query_height_range.clone())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -646,7 +648,7 @@ impl Chain {
|
|||
network: self.network,
|
||||
blocks: self.blocks.clone(),
|
||||
height_by_hash: self.height_by_hash.clone(),
|
||||
tx_by_hash: self.tx_by_hash.clone(),
|
||||
tx_loc_by_hash: self.tx_loc_by_hash.clone(),
|
||||
created_utxos: self.created_utxos.clone(),
|
||||
spent_utxos: self.spent_utxos.clone(),
|
||||
sprout_note_commitment_tree,
|
||||
|
@ -784,10 +786,10 @@ impl UpdateWith<ContextuallyValidBlock> for Chain {
|
|||
),
|
||||
};
|
||||
|
||||
// add key `transaction.hash` and value `(height, tx_index)` to `tx_by_hash`
|
||||
// add key `transaction.hash` and value `(height, tx_index)` to `tx_loc_by_hash`
|
||||
let transaction_location = TransactionLocation::from_usize(height, transaction_index);
|
||||
let prior_pair = self
|
||||
.tx_by_hash
|
||||
.tx_loc_by_hash
|
||||
.insert(transaction_hash, transaction_location);
|
||||
assert_eq!(
|
||||
prior_pair, None,
|
||||
|
@ -927,9 +929,9 @@ impl UpdateWith<ContextuallyValidBlock> for Chain {
|
|||
// reset the utxos this consumed
|
||||
self.revert_chain_with(&(inputs, transaction_hash, spent_outputs), position);
|
||||
|
||||
// remove `transaction.hash` from `tx_by_hash`
|
||||
// remove `transaction.hash` from `tx_loc_by_hash`
|
||||
assert!(
|
||||
self.tx_by_hash.remove(transaction_hash).is_some(),
|
||||
self.tx_loc_by_hash.remove(transaction_hash).is_some(),
|
||||
"transactions must be present if block was added to chain"
|
||||
);
|
||||
|
||||
|
|
|
@ -236,24 +236,24 @@ impl TransparentTransfers {
|
|||
///
|
||||
/// The transactions are returned in chain order.
|
||||
///
|
||||
/// `chain_tx_by_hash` should be the `tx_by_hash` field from the
|
||||
/// `chain_tx_loc_by_hash` should be the `tx_loc_by_hash` field from the
|
||||
/// [`Chain`][1] containing this index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If `chain_tx_by_hash` is missing some transaction hashes from this
|
||||
/// If `chain_tx_loc_by_hash` is missing some transaction hashes from this
|
||||
/// index.
|
||||
///
|
||||
/// [1]: super::super::Chain
|
||||
pub fn tx_ids(
|
||||
&self,
|
||||
chain_tx_by_hash: &HashMap<transaction::Hash, TransactionLocation>,
|
||||
chain_tx_loc_by_hash: &HashMap<transaction::Hash, TransactionLocation>,
|
||||
query_height_range: RangeInclusive<Height>,
|
||||
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
||||
self.tx_ids
|
||||
.distinct_elements()
|
||||
.filter_map(|tx_hash| {
|
||||
let tx_loc = *chain_tx_by_hash
|
||||
let tx_loc = *chain_tx_loc_by_hash
|
||||
.get(tx_hash)
|
||||
.expect("all hashes are indexed");
|
||||
|
||||
|
|
|
@ -592,7 +592,7 @@ fn different_blocks_different_chains() -> Result<()> {
|
|||
// blocks, heights, hashes
|
||||
chain1.blocks = chain2.blocks.clone();
|
||||
chain1.height_by_hash = chain2.height_by_hash.clone();
|
||||
chain1.tx_by_hash = chain2.tx_by_hash.clone();
|
||||
chain1.tx_loc_by_hash = chain2.tx_loc_by_hash.clone();
|
||||
|
||||
// transparent UTXOs
|
||||
chain1.created_utxos = chain2.created_utxos.clone();
|
||||
|
|
Loading…
Reference in New Issue