Added a limit value for scanning.

This provides a way to expose a more fine grained measure of scan progress. For example, by scanning in batches of 100 blocks, rather than everything that is pending.
This commit is contained in:
Kevin Gorham 2020-02-04 11:40:50 -05:00 committed by Jack Grigg
parent c8074d42b8
commit 9363ec36d9
3 changed files with 33 additions and 26 deletions

View File

@ -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);

View File

@ -30,8 +30,13 @@ struct WitnessRow {
witness: IncrementalWitness<Node>,
}
/// 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<P: AsRef<Path>, Q: AsRef<Path>>(
db_cache: P,
db_data: Q,
limit: Option<i32>,
) -> Result<(), Error> {
let cache = Connection::open(db_cache)?;
let data = Connection::open(db_data)?;
@ -68,9 +74,10 @@ pub fn scan_cached_blocks<P: AsRef<Path>, Q: AsRef<Path>>(
})?;
// 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);

View File

@ -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(