Merge pull request #879 from zcash/877-shardtree-migration-perf

zcash_client_sqlite: Only import recent frontiers into `ShardTree`
This commit is contained in:
str4d 2023-07-24 00:09:35 +01:00 committed by GitHub
commit 46ca3202e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 38 additions and 21 deletions

View File

@ -103,6 +103,8 @@ impl RusqliteMigration for Migration {
);",
)?;
let block_height_extrema = block_height_extrema(transaction)?;
let shard_store =
SqliteShardStore::<_, sapling::Node, SAPLING_SHARD_HEIGHT>::from_connection(
transaction,
@ -149,25 +151,40 @@ impl RusqliteMigration for Migration {
stmt_update_block_sapling_tree_size
.execute(params![block_end_tree.size(), block_height])?;
if let Some(nonempty_frontier) = block_end_tree.to_frontier().value() {
trace!(
height = block_height,
frontier = ?nonempty_frontier,
"Inserting frontier nodes",
);
shard_tree
.insert_frontier_nodes(
nonempty_frontier.clone(),
Retention::Checkpoint {
id: BlockHeight::from(block_height),
is_marked: false,
},
)
.map_err(|e| match e {
ShardTreeError::Query(e) => ShardTreeError::Query(e),
ShardTreeError::Insert(e) => ShardTreeError::Insert(e),
ShardTreeError::Storage(_) => unreachable!(),
})?
// We only need to load frontiers into the ShardTree that are close enough
// to the wallet's known chain tip to fill `PRUNING_DEPTH` checkpoints, so
// that ShardTree's witness generation will be able to correctly handle
// anchor depths. Loading frontiers further back than this doesn't add any
// useful nodes to the ShardTree (as we don't support rollbacks beyond
// `PRUNING_DEPTH`, and we won't be finding notes in earlier blocks), and
// hurts performance (as frontier importing has a significant Merkle tree
// hashing cost).
if let Some((nonempty_frontier, (_, latest_height))) = block_end_tree
.to_frontier()
.value()
.zip(block_height_extrema)
{
let block_height = BlockHeight::from(block_height);
if block_height + PRUNING_DEPTH >= latest_height {
trace!(
height = u32::from(block_height),
frontier = ?nonempty_frontier,
"Inserting frontier nodes",
);
shard_tree
.insert_frontier_nodes(
nonempty_frontier.clone(),
Retention::Checkpoint {
id: block_height,
is_marked: false,
},
)
.map_err(|e| match e {
ShardTreeError::Query(e) => ShardTreeError::Query(e),
ShardTreeError::Insert(e) => ShardTreeError::Insert(e),
ShardTreeError::Storage(_) => unreachable!(),
})?
}
}
}
}
@ -241,14 +258,14 @@ impl RusqliteMigration for Migration {
);",
)?;
if let Some((start, end)) = block_height_extrema(transaction)? {
if let Some((start, end)) = block_height_extrema {
// `ScanRange` uses an exclusive upper bound.
let chain_end = end + 1;
insert_queue_entries(
transaction,
Some(ScanRange::from_parts(
start..chain_end,
ScanPriority::Historic,
ScanPriority::Scanned,
))
.iter(),
)?;