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
|
- 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
|
account for the fact that we may start verifying blocks before all of their
|
||||||
ancestors are downloaded.
|
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:
|
The `Chain` type is defined by the following struct and API:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Chain {
|
pub struct Chain {
|
||||||
blocks: BTreeMap<block::Height, Arc<Block>>,
|
// The function `eq_internal_state` must be updated every time a field is added to [`Chain`].
|
||||||
height_by_hash: HashMap<block::Hash, block::Height>,
|
/// The configured network for this chain.
|
||||||
tx_by_hash: HashMap<transaction::Hash, (block::Height, usize)>,
|
network: Network,
|
||||||
|
|
||||||
created_utxos: HashSet<transparent::OutPoint>,
|
/// The contextually valid blocks which form this non-finalized partial chain, in height order.
|
||||||
spent_utxos: HashSet<transparent::OutPoint>,
|
pub(crate) blocks: BTreeMap<block::Height, ContextuallyValidBlock>,
|
||||||
sprout_anchors: HashSet<sprout::tree::Root>,
|
|
||||||
sapling_anchors: HashSet<sapling::tree::Root>,
|
/// An index of block heights for each block hash in `blocks`.
|
||||||
sprout_nullifiers: HashSet<sprout::Nullifier>,
|
pub height_by_hash: HashMap<block::Hash, block::Height>,
|
||||||
sapling_nullifiers: HashSet<sapling::Nullifier>,
|
|
||||||
orchard_nullifiers: HashSet<orchard::Nullifier>,
|
/// An index of [`TransactionLocation`]s for each transaction hash in `blocks`.
|
||||||
partial_cumulative_work: PartialCumulativeWork,
|
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 the block's hash to `height_by_hash`
|
||||||
- Add work to `self.partial_cumulative_work`
|
- Add work to `self.partial_cumulative_work`
|
||||||
- For each `transaction` in `block`
|
- 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 created utxos to `self.created_utxos`
|
||||||
- Add spent utxos to `self.spent_utxos`
|
- Add spent utxos to `self.spent_utxos`
|
||||||
- Add nullifiers to the appropriate `self.<version>_nullifiers`
|
- 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`
|
- Remove the block's hash from `self.height_by_hash`
|
||||||
- Subtract work from `self.partial_cumulative_work`
|
- Subtract work from `self.partial_cumulative_work`
|
||||||
- For each `transaction` in `block`
|
- 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 created utxos from `self.created_utxos`
|
||||||
- Remove spent utxos from `self.spent_utxos`
|
- Remove spent utxos from `self.spent_utxos`
|
||||||
- Remove the nullifiers from the appropriate `self.<version>_nullifiers`
|
- 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`
|
- Remove the corresponding hash from `self.height_by_hash`
|
||||||
- Subtract work from `self.partial_cumulative_work`
|
- Subtract work from `self.partial_cumulative_work`
|
||||||
- for each `transaction` in `block`
|
- 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 created utxos from `self.created_utxos`
|
||||||
- Remove spent utxos from `self.spent_utxos`
|
- Remove spent utxos from `self.spent_utxos`
|
||||||
- Remove the nullifiers from the appropriate `self.<version>_nullifiers`
|
- 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)]`.
|
handled by `#[derive(Default)]`.
|
||||||
|
|
||||||
1. initialise cumulative data members
|
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.created_utxos`, `self.spent_utxos`, `self.<version>_anchors`,
|
||||||
`self.<version>_nullifiers`
|
`self.<version>_nullifiers`
|
||||||
- Zero `self.partial_cumulative_work`
|
- Zero `self.partial_cumulative_work`
|
||||||
|
|
@ -1102,13 +1172,14 @@ Returns
|
||||||
|
|
||||||
Implemented by querying:
|
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
|
transaction) of each chain starting with the best chain, and then find
|
||||||
block that chain's `blocks` (to get the block containing the transaction
|
block that chain's `blocks` (to get the block containing the transaction
|
||||||
data)
|
data)
|
||||||
- (finalized) the `tx_by_hash` tree (to get the block that contains the
|
- (finalized) the `tx_loc_by_hash` tree (to get the block that contains the
|
||||||
transaction) and then `block_by_height` tree (to get the block containing
|
transaction) and then `block_header_by_height` tree (to get the block
|
||||||
the transaction data), if the transaction is not in any non-finalized chain
|
containing the transaction data), if the transaction is not in any
|
||||||
|
non-finalized chain
|
||||||
|
|
||||||
### `Request::Block(block::Hash)`
|
### `Request::Block(block::Hash)`
|
||||||
[request-block]: #request-block
|
[request-block]: #request-block
|
||||||
|
|
@ -1125,8 +1196,9 @@ Implemented by querying:
|
||||||
|
|
||||||
- (non-finalized) the `height_by_hash` of each chain starting with the best
|
- (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)
|
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
|
- (finalized) the `height_by_hash` tree (to get the block height) and then the
|
||||||
the `block_by_height` tree (to get the block data), if the block is not in any non-finalized chain
|
`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 }`
|
### `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;
|
pub const MAX_BLOCK_REORG_HEIGHT: u32 = MIN_TRANSPARENT_COINBASE_MATURITY - 1;
|
||||||
|
|
||||||
/// The database format version, incremented each time the database format changes.
|
/// 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,
|
/// The maximum number of blocks to check for NU5 transactions,
|
||||||
/// before we assume we are on a pre-NU5 legacy chain.
|
/// before we assume we are on a pre-NU5 legacy chain.
|
||||||
|
|
|
||||||
|
|
@ -369,29 +369,24 @@ impl DiskDb {
|
||||||
|
|
||||||
let column_families = vec![
|
let column_families = vec![
|
||||||
// Blocks
|
// 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("hash_by_height", db_options.clone()),
|
||||||
rocksdb::ColumnFamilyDescriptor::new("height_by_hash", db_options.clone()),
|
rocksdb::ColumnFamilyDescriptor::new("height_by_hash", db_options.clone()),
|
||||||
|
rocksdb::ColumnFamilyDescriptor::new("block_header_by_height", db_options.clone()),
|
||||||
// Transactions
|
// Transactions
|
||||||
rocksdb::ColumnFamilyDescriptor::new("tx_by_loc", db_options.clone()),
|
rocksdb::ColumnFamilyDescriptor::new("tx_by_loc", db_options.clone()),
|
||||||
rocksdb::ColumnFamilyDescriptor::new("hash_by_tx_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_loc_by_hash", db_options.clone()),
|
||||||
rocksdb::ColumnFamilyDescriptor::new("tx_by_hash", db_options.clone()),
|
|
||||||
// Transparent
|
// Transparent
|
||||||
rocksdb::ColumnFamilyDescriptor::new("balance_by_transparent_addr", db_options.clone()),
|
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(
|
rocksdb::ColumnFamilyDescriptor::new(
|
||||||
"tx_loc_by_transparent_addr_loc",
|
"tx_loc_by_transparent_addr_loc",
|
||||||
db_options.clone(),
|
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
|
// Sprout
|
||||||
rocksdb::ColumnFamilyDescriptor::new("sprout_nullifiers", db_options.clone()),
|
rocksdb::ColumnFamilyDescriptor::new("sprout_nullifiers", db_options.clone()),
|
||||||
rocksdb::ColumnFamilyDescriptor::new("sprout_anchors", 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
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 72
|
||||||
expression: cf_names
|
expression: cf_names
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
"balance_by_transparent_addr",
|
"balance_by_transparent_addr",
|
||||||
"block_by_height",
|
"block_header_by_height",
|
||||||
"default",
|
"default",
|
||||||
"hash_by_height",
|
"hash_by_height",
|
||||||
"hash_by_tx_loc",
|
"hash_by_tx_loc",
|
||||||
|
|
@ -20,9 +21,9 @@ expression: cf_names
|
||||||
"sprout_note_commitment_tree",
|
"sprout_note_commitment_tree",
|
||||||
"sprout_nullifiers",
|
"sprout_nullifiers",
|
||||||
"tip_chain_value_pool",
|
"tip_chain_value_pool",
|
||||||
"tx_by_hash",
|
|
||||||
"tx_by_loc",
|
"tx_by_loc",
|
||||||
|
"tx_loc_by_hash",
|
||||||
"tx_loc_by_transparent_addr_loc",
|
"tx_loc_by_transparent_addr_loc",
|
||||||
"utxo_by_outpoint",
|
"utxo_by_out_loc",
|
||||||
"utxo_loc_by_transparent_addr_loc",
|
"utxo_loc_by_transparent_addr_loc",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 154
|
||||||
expression: empty_column_families
|
expression: empty_column_families
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -13,6 +14,6 @@ expression: empty_column_families
|
||||||
"sprout_nullifiers: no entries",
|
"sprout_nullifiers: no entries",
|
||||||
"tip_chain_value_pool: no entries",
|
"tip_chain_value_pool: no entries",
|
||||||
"tx_loc_by_transparent_addr_loc: 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",
|
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 154
|
||||||
expression: empty_column_families
|
expression: empty_column_families
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
"balance_by_transparent_addr: no entries",
|
"balance_by_transparent_addr: no entries",
|
||||||
"block_by_height: no entries",
|
"block_header_by_height: no entries",
|
||||||
"hash_by_height: no entries",
|
"hash_by_height: no entries",
|
||||||
"hash_by_tx_loc: no entries",
|
"hash_by_tx_loc: no entries",
|
||||||
"height_by_hash: no entries",
|
"height_by_hash: no entries",
|
||||||
|
|
@ -19,9 +20,9 @@ expression: empty_column_families
|
||||||
"sprout_note_commitment_tree: no entries",
|
"sprout_note_commitment_tree: no entries",
|
||||||
"sprout_nullifiers: no entries",
|
"sprout_nullifiers: no entries",
|
||||||
"tip_chain_value_pool: no entries",
|
"tip_chain_value_pool: no entries",
|
||||||
"tx_by_hash: no entries",
|
|
||||||
"tx_by_loc: no entries",
|
"tx_by_loc: no entries",
|
||||||
|
"tx_loc_by_hash: no entries",
|
||||||
"tx_loc_by_transparent_addr_loc: 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",
|
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 154
|
||||||
expression: empty_column_families
|
expression: empty_column_families
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -13,6 +14,6 @@ expression: empty_column_families
|
||||||
"sprout_nullifiers: no entries",
|
"sprout_nullifiers: no entries",
|
||||||
"tip_chain_value_pool: no entries",
|
"tip_chain_value_pool: no entries",
|
||||||
"tx_loc_by_transparent_addr_loc: 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",
|
"utxo_loc_by_transparent_addr_loc: no entries",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
source: zebra-state/src/service/finalized_state/disk_format/tests/snapshot.rs
|
||||||
|
assertion_line: 144
|
||||||
expression: cf_data
|
expression: cf_data
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -86,7 +86,7 @@ impl ZebraDb {
|
||||||
#[allow(clippy::unwrap_in_result)]
|
#[allow(clippy::unwrap_in_result)]
|
||||||
pub fn block(&self, hash_or_height: HashOrHeight) -> Option<Arc<Block>> {
|
pub fn block(&self, hash_or_height: HashOrHeight) -> Option<Arc<Block>> {
|
||||||
// Blocks
|
// 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_by_hash = self.db.cf_handle("height_by_hash").unwrap();
|
||||||
|
|
||||||
let height =
|
let height =
|
||||||
|
|
@ -174,7 +174,7 @@ impl ZebraDb {
|
||||||
/// if it exists in the finalized chain.
|
/// if it exists in the finalized chain.
|
||||||
#[allow(clippy::unwrap_in_result)]
|
#[allow(clippy::unwrap_in_result)]
|
||||||
pub fn transaction_location(&self, hash: transaction::Hash) -> Option<TransactionLocation> {
|
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)
|
self.db.zs_get(&tx_loc_by_hash, &hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -422,14 +422,14 @@ impl DiskWriteBatch {
|
||||||
finalized: &FinalizedBlock,
|
finalized: &FinalizedBlock,
|
||||||
) -> Result<(), BoxError> {
|
) -> Result<(), BoxError> {
|
||||||
// Blocks
|
// 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 hash_by_height = db.cf_handle("hash_by_height").unwrap();
|
||||||
let height_by_hash = db.cf_handle("height_by_hash").unwrap();
|
let height_by_hash = db.cf_handle("height_by_hash").unwrap();
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
let tx_by_loc = db.cf_handle("tx_by_loc").unwrap();
|
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 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 {
|
let FinalizedBlock {
|
||||||
block,
|
block,
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ impl ZebraDb {
|
||||||
&self,
|
&self,
|
||||||
output_location: OutputLocation,
|
output_location: OutputLocation,
|
||||||
) -> Option<transparent::OrderedUtxo> {
|
) -> 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)?;
|
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>,
|
new_outputs_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
|
||||||
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
||||||
) -> Result<(), BoxError> {
|
) -> 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 =
|
let utxo_loc_by_transparent_addr_loc =
|
||||||
db.cf_handle("utxo_loc_by_transparent_addr_loc").unwrap();
|
db.cf_handle("utxo_loc_by_transparent_addr_loc").unwrap();
|
||||||
let tx_loc_by_transparent_addr_loc =
|
let tx_loc_by_transparent_addr_loc =
|
||||||
|
|
@ -501,7 +501,7 @@ impl DiskWriteBatch {
|
||||||
spent_utxos_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
|
spent_utxos_by_out_loc: &BTreeMap<OutputLocation, transparent::Utxo>,
|
||||||
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
address_balances: &mut HashMap<transparent::Address, AddressBalanceLocation>,
|
||||||
) -> Result<(), BoxError> {
|
) -> 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 =
|
let utxo_loc_by_transparent_addr_loc =
|
||||||
db.cf_handle("utxo_loc_by_transparent_addr_loc").unwrap();
|
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>,
|
pub height_by_hash: HashMap<block::Hash, block::Height>,
|
||||||
|
|
||||||
/// An index of [`TransactionLocation`]s for each transaction hash in `blocks`.
|
/// 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`.
|
/// The [`transparent::Utxo`]s created by `blocks`.
|
||||||
///
|
///
|
||||||
|
|
@ -135,7 +135,7 @@ impl Chain {
|
||||||
network,
|
network,
|
||||||
blocks: Default::default(),
|
blocks: Default::default(),
|
||||||
height_by_hash: Default::default(),
|
height_by_hash: Default::default(),
|
||||||
tx_by_hash: Default::default(),
|
tx_loc_by_hash: Default::default(),
|
||||||
created_utxos: Default::default(),
|
created_utxos: Default::default(),
|
||||||
sprout_note_commitment_tree,
|
sprout_note_commitment_tree,
|
||||||
sapling_note_commitment_tree,
|
sapling_note_commitment_tree,
|
||||||
|
|
@ -177,7 +177,7 @@ impl Chain {
|
||||||
// blocks, heights, hashes
|
// blocks, heights, hashes
|
||||||
self.blocks == other.blocks &&
|
self.blocks == other.blocks &&
|
||||||
self.height_by_hash == other.height_by_hash &&
|
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
|
// transparent UTXOs
|
||||||
self.created_utxos == other.created_utxos &&
|
self.created_utxos == other.created_utxos &&
|
||||||
|
|
@ -355,7 +355,7 @@ impl Chain {
|
||||||
&self,
|
&self,
|
||||||
hash: transaction::Hash,
|
hash: transaction::Hash,
|
||||||
) -> Option<(&Arc<Transaction>, block::Height)> {
|
) -> 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()],
|
&self.blocks[&tx_loc.height].block.transactions[tx_loc.index.as_usize()],
|
||||||
tx_loc.height,
|
tx_loc.height,
|
||||||
|
|
@ -625,7 +625,9 @@ impl Chain {
|
||||||
query_height_range: RangeInclusive<Height>,
|
query_height_range: RangeInclusive<Height>,
|
||||||
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
||||||
self.partial_transparent_indexes(addresses)
|
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()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -646,7 +648,7 @@ impl Chain {
|
||||||
network: self.network,
|
network: self.network,
|
||||||
blocks: self.blocks.clone(),
|
blocks: self.blocks.clone(),
|
||||||
height_by_hash: self.height_by_hash.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(),
|
created_utxos: self.created_utxos.clone(),
|
||||||
spent_utxos: self.spent_utxos.clone(),
|
spent_utxos: self.spent_utxos.clone(),
|
||||||
sprout_note_commitment_tree,
|
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 transaction_location = TransactionLocation::from_usize(height, transaction_index);
|
||||||
let prior_pair = self
|
let prior_pair = self
|
||||||
.tx_by_hash
|
.tx_loc_by_hash
|
||||||
.insert(transaction_hash, transaction_location);
|
.insert(transaction_hash, transaction_location);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
prior_pair, None,
|
prior_pair, None,
|
||||||
|
|
@ -927,9 +929,9 @@ impl UpdateWith<ContextuallyValidBlock> for Chain {
|
||||||
// reset the utxos this consumed
|
// reset the utxos this consumed
|
||||||
self.revert_chain_with(&(inputs, transaction_hash, spent_outputs), position);
|
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!(
|
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"
|
"transactions must be present if block was added to chain"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,24 +236,24 @@ impl TransparentTransfers {
|
||||||
///
|
///
|
||||||
/// The transactions are returned in chain order.
|
/// 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.
|
/// [`Chain`][1] containing this index.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # 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.
|
/// index.
|
||||||
///
|
///
|
||||||
/// [1]: super::super::Chain
|
/// [1]: super::super::Chain
|
||||||
pub fn tx_ids(
|
pub fn tx_ids(
|
||||||
&self,
|
&self,
|
||||||
chain_tx_by_hash: &HashMap<transaction::Hash, TransactionLocation>,
|
chain_tx_loc_by_hash: &HashMap<transaction::Hash, TransactionLocation>,
|
||||||
query_height_range: RangeInclusive<Height>,
|
query_height_range: RangeInclusive<Height>,
|
||||||
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
) -> BTreeMap<TransactionLocation, transaction::Hash> {
|
||||||
self.tx_ids
|
self.tx_ids
|
||||||
.distinct_elements()
|
.distinct_elements()
|
||||||
.filter_map(|tx_hash| {
|
.filter_map(|tx_hash| {
|
||||||
let tx_loc = *chain_tx_by_hash
|
let tx_loc = *chain_tx_loc_by_hash
|
||||||
.get(tx_hash)
|
.get(tx_hash)
|
||||||
.expect("all hashes are indexed");
|
.expect("all hashes are indexed");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -592,7 +592,7 @@ fn different_blocks_different_chains() -> Result<()> {
|
||||||
// blocks, heights, hashes
|
// blocks, heights, hashes
|
||||||
chain1.blocks = chain2.blocks.clone();
|
chain1.blocks = chain2.blocks.clone();
|
||||||
chain1.height_by_hash = chain2.height_by_hash.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
|
// transparent UTXOs
|
||||||
chain1.created_utxos = chain2.created_utxos.clone();
|
chain1.created_utxos = chain2.created_utxos.clone();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue