diff --git a/zcash_client_sqlite/src/chain.rs b/zcash_client_sqlite/src/chain.rs index 4e94bee7cb..49e52c8bfd 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 70ab368dbb..56b174721d 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 @@ -57,6 +62,7 @@ struct WitnessRow { 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)?, @@ -357,7 +364,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 @@ -374,7 +381,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(), @@ -388,7 +395,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() @@ -424,7 +431,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); @@ -435,7 +442,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); @@ -470,7 +477,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); @@ -492,7 +499,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 0047d9308a..ec99563df0 100644 --- a/zcash_client_sqlite/src/transact.rs +++ b/zcash_client_sqlite/src/transact.rs @@ -462,7 +462,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); @@ -476,7 +476,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); @@ -512,7 +512,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( @@ -539,7 +539,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( @@ -578,7 +578,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 @@ -623,7 +623,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( @@ -650,7 +650,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(