From ef5dba4792accb68ae2262b5b67901f52406601a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 9 Mar 2024 17:51:51 +0000 Subject: [PATCH] zcash_client_sqlite: Track Orchard commitment tree sizes in `TestState` --- zcash_client_sqlite/src/chain.rs | 1 + zcash_client_sqlite/src/testing.rs | 49 ++++++++++++++++++---- zcash_client_sqlite/src/testing/pool.rs | 9 ++++ zcash_client_sqlite/src/wallet.rs | 2 + zcash_client_sqlite/src/wallet/scanning.rs | 35 +++++++++++++--- 5 files changed, 83 insertions(+), 13 deletions(-) diff --git a/zcash_client_sqlite/src/chain.rs b/zcash_client_sqlite/src/chain.rs index 7585720383..38b32d3c1b 100644 --- a/zcash_client_sqlite/src/chain.rs +++ b/zcash_client_sqlite/src/chain.rs @@ -414,6 +414,7 @@ mod tests { AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(8), 2, + 2, ); st.generate_next_block( &dfvk, diff --git a/zcash_client_sqlite/src/testing.rs b/zcash_client_sqlite/src/testing.rs index 5d6111b542..785fb37406 100644 --- a/zcash_client_sqlite/src/testing.rs +++ b/zcash_client_sqlite/src/testing.rs @@ -170,6 +170,7 @@ pub(crate) struct CachedBlock { height: BlockHeight, hash: BlockHash, sapling_end_size: u32, + orchard_end_size: u32, } impl CachedBlock { @@ -178,14 +179,21 @@ impl CachedBlock { height: sapling_activation_height, hash: BlockHash([0; 32]), sapling_end_size: 0, + orchard_end_size: 0, } } - fn at(height: BlockHeight, hash: BlockHash, sapling_tree_size: u32) -> Self { + fn at( + height: BlockHeight, + hash: BlockHash, + sapling_tree_size: u32, + orchard_tree_size: u32, + ) -> Self { Self { height, hash, sapling_end_size: sapling_tree_size, + orchard_end_size: orchard_tree_size, } } @@ -196,6 +204,8 @@ impl CachedBlock { hash: cb.hash(), sapling_end_size: self.sapling_end_size + cb.vtx.iter().map(|tx| tx.outputs.len() as u32).sum::(), + orchard_end_size: self.orchard_end_size + + cb.vtx.iter().map(|tx| tx.actions.len() as u32).sum::(), } } } @@ -249,6 +259,7 @@ where req, value, cached_block.sapling_end_size, + cached_block.orchard_end_size, ); assert!(self.latest_cached_block.is_some()); @@ -268,6 +279,7 @@ where req: AddressType, value: NonNegativeAmount, initial_sapling_tree_size: u32, + initial_orchard_tree_size: u32, ) -> (Cache::InsertResult, Fvk::Nullifier) { let (cb, nf) = fake_compact_block( &self.network(), @@ -277,11 +289,18 @@ where req, value, initial_sapling_tree_size, + initial_orchard_tree_size, ); let res = self.cache.insert(&cb); self.latest_cached_block = Some( - CachedBlock::at(height - 1, cb.hash(), initial_sapling_tree_size).roll_forward(&cb), + CachedBlock::at( + height - 1, + cb.hash(), + initial_sapling_tree_size, + initial_orchard_tree_size, + ) + .roll_forward(&cb), ); (res, nf) @@ -311,6 +330,7 @@ where to.into(), value, cached_block.sapling_end_size, + cached_block.orchard_end_size, ); let res = self.cache.insert(&cb); @@ -361,7 +381,7 @@ where tx_index, tx, cached_block.sapling_end_size, - 0, + cached_block.orchard_end_size, ); let res = self.cache.insert(&cb); @@ -424,10 +444,12 @@ where self.cache .block_source() .with_blocks::<_, Infallible>(None, None, |block: CompactBlock| { + let chain_metadata = block.chain_metadata.unwrap(); self.latest_cached_block = Some(CachedBlock::at( BlockHeight::from_u32(block.height.try_into().unwrap()), BlockHash::from_slice(block.hash.as_slice()), - block.chain_metadata.unwrap().sapling_commitment_tree_size, + chain_metadata.sapling_commitment_tree_size, + chain_metadata.orchard_commitment_tree_size, )); Ok(()) }) @@ -1103,6 +1125,7 @@ fn fake_compact_block( req: AddressType, value: NonNegativeAmount, initial_sapling_tree_size: u32, + initial_orchard_tree_size: u32, ) -> (CompactBlock, Fvk::Nullifier) { // Create a fake Note for the account let mut rng = OsRng; @@ -1119,8 +1142,13 @@ fn fake_compact_block( &mut rng, ); - let cb = - fake_compact_block_from_compact_tx(ctx, height, prev_hash, initial_sapling_tree_size, 0); + let cb = fake_compact_block_from_compact_tx( + ctx, + height, + prev_hash, + initial_sapling_tree_size, + initial_orchard_tree_size, + ); (cb, nf) } @@ -1177,6 +1205,7 @@ fn fake_compact_block_spending( to: Address, value: NonNegativeAmount, initial_sapling_tree_size: u32, + initial_orchard_tree_size: u32, ) -> CompactBlock { let mut rng = OsRng; let mut ctx = fake_compact_tx(&mut rng); @@ -1254,7 +1283,13 @@ fn fake_compact_block_spending( } } - fake_compact_block_from_compact_tx(ctx, height, prev_hash, initial_sapling_tree_size, 0) + fake_compact_block_from_compact_tx( + ctx, + height, + prev_hash, + initial_sapling_tree_size, + initial_orchard_tree_size, + ) } fn fake_compact_block_from_compact_tx( diff --git a/zcash_client_sqlite/src/testing/pool.rs b/zcash_client_sqlite/src/testing/pool.rs index bda6a2c391..4043241a1b 100644 --- a/zcash_client_sqlite/src/testing/pool.rs +++ b/zcash_client_sqlite/src/testing/pool.rs @@ -1252,6 +1252,13 @@ pub(crate) fn birthday_in_anchor_shard() { u64::from(birthday.sapling_frontier().value().unwrap().position() + 1) .try_into() .unwrap(); + #[cfg(feature = "orchard")] + let initial_orchard_tree_size = + u64::from(birthday.orchard_frontier().value().unwrap().position() + 1) + .try_into() + .unwrap(); + #[cfg(not(feature = "orchard"))] + let initial_orchard_tree_size = 0; // Generate 9 blocks that have no value for us, starting at the birthday height. let not_our_key = T::sk_to_fvk(&T::sk(&[])); @@ -1263,6 +1270,7 @@ pub(crate) fn birthday_in_anchor_shard() { AddressType::DefaultExternal, not_our_value, initial_sapling_tree_size, + initial_orchard_tree_size, ); for _ in 1..9 { st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); @@ -1341,6 +1349,7 @@ pub(crate) fn checkpoint_gaps() { AddressType::DefaultExternal, not_our_value, st.latest_cached_block().unwrap().sapling_end_size, + st.latest_cached_block().unwrap().orchard_end_size, ); // Scan the block diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index 0a8a02a4e3..6648c7fb38 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -2645,6 +2645,7 @@ mod tests { AddressType::DefaultExternal, not_our_value, 17, + 17, ); st.scan_cached_blocks(end_height, 1); @@ -2661,6 +2662,7 @@ mod tests { AddressType::DefaultExternal, not_our_value, 0, + 0, ); st.scan_cached_blocks(start_height, 1); diff --git a/zcash_client_sqlite/src/wallet/scanning.rs b/zcash_client_sqlite/src/wallet/scanning.rs index 78656fd5be..aaf241f3a9 100644 --- a/zcash_client_sqlite/src/wallet/scanning.rs +++ b/zcash_client_sqlite/src/wallet/scanning.rs @@ -608,7 +608,9 @@ pub(crate) mod tests { // We'll start inserting leaf notes 5 notes after the end of the third subtree, with a gap // of 10 blocks. After `scan_cached_blocks`, the scan queue should have a requested scan // range of 300..310 with `FoundNote` priority, 310..320 with `Scanned` priority. + // We set both Sapling and Orchard to the same initial tree size for simplicity. let initial_sapling_tree_size = (0x1 << 16) * 3 + 5; + let initial_orchard_tree_size = (0x1 << 16) * 3 + 5; let initial_height = sapling_activation_height + 310; let value = NonNegativeAmount::const_from_u64(50000); @@ -619,6 +621,7 @@ pub(crate) mod tests { AddressType::DefaultExternal, value, initial_sapling_tree_size, + initial_orchard_tree_size, ); for _ in 1..=10 { @@ -921,6 +924,17 @@ pub(crate) mod tests { assert_eq!(actual, expected); // Now, scan the max scanned block. + let initial_sapling_tree_size = + u64::from(birthday.sapling_frontier().value().unwrap().position() + 1) + .try_into() + .unwrap(); + #[cfg(feature = "orchard")] + let initial_orchard_tree_size = + u64::from(birthday.orchard_frontier().value().unwrap().position() + 1) + .try_into() + .unwrap(); + #[cfg(not(feature = "orchard"))] + let initial_orchard_tree_size = 0; st.generate_block_at( max_scanned, BlockHash([0u8; 32]), @@ -928,9 +942,8 @@ pub(crate) mod tests { AddressType::DefaultExternal, // 1235 notes into into the second shard NonNegativeAmount::const_from_u64(10000), - u64::from(birthday.sapling_frontier().value().unwrap().position() + 1) - .try_into() - .unwrap(), + initial_sapling_tree_size, + initial_orchard_tree_size, ); st.scan_cached_blocks(max_scanned, 1); @@ -1041,15 +1054,25 @@ pub(crate) mod tests { assert_eq!(actual, expected); // Now, scan the max scanned block. + let initial_sapling_tree_size = + u64::from(birthday.sapling_frontier().value().unwrap().position() + 1) + .try_into() + .unwrap(); + #[cfg(feature = "orchard")] + let initial_orchard_tree_size = + u64::from(birthday.orchard_frontier().value().unwrap().position() + 1) + .try_into() + .unwrap(); + #[cfg(not(feature = "orchard"))] + let initial_orchard_tree_size = 0; st.generate_block_at( max_scanned, BlockHash([0u8; 32]), &dfvk, AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(10000), - u64::from(birthday.sapling_frontier().value().unwrap().position() + 1) - .try_into() - .unwrap(), + initial_sapling_tree_size, + initial_orchard_tree_size, ); st.scan_cached_blocks(max_scanned, 1);