diff --git a/zcash_client_sqlite/src/chain.rs b/zcash_client_sqlite/src/chain.rs index 4e94bee7c..49e52c8bf 100644 --- a/zcash_client_sqlite/src/chain.rs +++ b/zcash_client_sqlite/src/chain.rs @@ -52,7 +52,7 @@ //! // At this point, the cache and scanned data are locally consistent (though not //! // necessarily consistent with the latest chain tip - this would be discovered the //! // next time this codepath is executed after new blocks are received). -//! scan_cached_blocks(&db_cache, &db_data); +//! scan_cached_blocks(&db_cache, &db_data, None); //! ``` use protobuf::parse_from_bytes; @@ -268,7 +268,7 @@ mod tests { validate_combined_chain(db_cache, db_data).unwrap(); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Data-only chain should be valid validate_combined_chain(db_cache, db_data).unwrap(); @@ -286,7 +286,7 @@ mod tests { validate_combined_chain(db_cache, db_data).unwrap(); // Scan the cache again - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Data-only chain should be valid validate_combined_chain(db_cache, db_data).unwrap(); @@ -324,7 +324,7 @@ mod tests { insert_into_cache(db_cache, &cb2); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Data-only chain should be valid validate_combined_chain(db_cache, db_data).unwrap(); @@ -389,7 +389,7 @@ mod tests { insert_into_cache(db_cache, &cb2); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Data-only chain should be valid validate_combined_chain(db_cache, db_data).unwrap(); @@ -454,7 +454,7 @@ mod tests { insert_into_cache(db_cache, &cb2); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Account balance should reflect both received notes assert_eq!(get_balance(db_data, 0).unwrap(), value + value2); diff --git a/zcash_client_sqlite/src/scan.rs b/zcash_client_sqlite/src/scan.rs index c30abd32d..4a087fc43 100644 --- a/zcash_client_sqlite/src/scan.rs +++ b/zcash_client_sqlite/src/scan.rs @@ -30,8 +30,13 @@ struct WitnessRow { witness: IncrementalWitness, } -/// Scans new blocks added to the cache for any transactions received by the tracked -/// accounts. +/// Scans at most `limit` new blocks added to the cache for any transactions received by +/// the tracked accounts. +/// +/// This function will return without error after scanning at most `limit` new blocks, to +/// enable the caller to update their UI with scanning progress. Repeatedly calling this +/// function will process sequential ranges of blocks, and is equivalent to calling +/// `scan_cached_blocks` and passing `None` for the optional `limit` value. /// /// This function pays attention only to cached blocks with heights greater than the /// highest scanned block in `db_data`. Cached blocks with lower heights are not verified @@ -50,13 +55,14 @@ struct WitnessRow { /// ``` /// use zcash_client_sqlite::scan::scan_cached_blocks; /// -/// scan_cached_blocks("/path/to/cache.db", "/path/to/data.db"); +/// scan_cached_blocks("/path/to/cache.db", "/path/to/data.db", None); /// ``` /// /// [`init_blocks_table`]: crate::init::init_blocks_table pub fn scan_cached_blocks, Q: AsRef>( db_cache: P, db_data: Q, + limit: Option, ) -> Result<(), Error> { let cache = Connection::open(db_cache)?; let data = Connection::open(db_data)?; @@ -68,9 +74,10 @@ pub fn scan_cached_blocks, Q: AsRef>( })?; // Fetch the CompactBlocks we need to scan - let mut stmt_blocks = cache - .prepare("SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC")?; - let rows = stmt_blocks.query_map(&[last_height], |row| { + let mut stmt_blocks = cache.prepare( + "SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC LIMIT ?", + )?; + let rows = stmt_blocks.query_map(&[last_height, limit.unwrap_or(i32::max_value())], |row| { Ok(CompactBlockRow { height: row.get(0)?, data: row.get(1)?, @@ -356,7 +363,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb1); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); assert_eq!(get_balance(db_data, 0).unwrap(), value); // We cannot scan a block of height SAPLING_ACTIVATION_HEIGHT + 2 next @@ -373,7 +380,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb3); - match scan_cached_blocks(db_cache, db_data) { + match scan_cached_blocks(db_cache, db_data, None) { Ok(_) => panic!("Should have failed"), Err(e) => assert_eq!( e.to_string(), @@ -387,7 +394,7 @@ mod tests { // If we add a block of height SAPLING_ACTIVATION_HEIGHT + 1, we can now scan both insert_into_cache(db_cache, &cb2); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); assert_eq!( get_balance(db_data, 0).unwrap(), Amount::from_u64(150_000).unwrap() @@ -423,7 +430,7 @@ mod tests { insert_into_cache(db_cache, &cb); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Account balance should reflect the received note assert_eq!(get_balance(db_data, 0).unwrap(), value); @@ -434,7 +441,7 @@ mod tests { insert_into_cache(db_cache, &cb2); // Scan the cache again - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Account balance should reflect both received notes assert_eq!(get_balance(db_data, 0).unwrap(), value + value2); @@ -469,7 +476,7 @@ mod tests { insert_into_cache(db_cache, &cb); // Scan the cache - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Account balance should reflect the received note assert_eq!(get_balance(db_data, 0).unwrap(), value); @@ -491,7 +498,7 @@ mod tests { ); // Scan the cache again - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Account balance should equal the change assert_eq!(get_balance(db_data, 0).unwrap(), value - value2); diff --git a/zcash_client_sqlite/src/transact.rs b/zcash_client_sqlite/src/transact.rs index 155059bfa..d1d9346f6 100644 --- a/zcash_client_sqlite/src/transact.rs +++ b/zcash_client_sqlite/src/transact.rs @@ -468,7 +468,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Verified balance matches total balance assert_eq!(get_balance(db_data, 0).unwrap(), value); @@ -482,7 +482,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Verified balance does not include the second note assert_eq!(get_balance(db_data, 0).unwrap(), value + value); @@ -518,7 +518,7 @@ mod tests { ); insert_into_cache(db_cache, &cb); } - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Second spend still fails match create_to_address( @@ -545,7 +545,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Second spend should now succeed create_to_address( @@ -584,7 +584,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); assert_eq!(get_balance(db_data, 0).unwrap(), value); // Send some of the funds to another address @@ -629,7 +629,7 @@ mod tests { ); insert_into_cache(db_cache, &cb); } - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Second spend still fails match create_to_address( @@ -656,7 +656,7 @@ mod tests { value, ); insert_into_cache(db_cache, &cb); - scan_cached_blocks(db_cache, db_data).unwrap(); + scan_cached_blocks(db_cache, db_data, None).unwrap(); // Second spend should now succeed create_to_address(