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:
parent
c8074d42b8
commit
9363ec36d9
|
@ -52,7 +52,7 @@
|
||||||
//! // At this point, the cache and scanned data are locally consistent (though not
|
//! // 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
|
//! // necessarily consistent with the latest chain tip - this would be discovered the
|
||||||
//! // next time this codepath is executed after new blocks are received).
|
//! // 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;
|
use protobuf::parse_from_bytes;
|
||||||
|
@ -268,7 +268,7 @@ mod tests {
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Data-only chain should be valid
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
@ -286,7 +286,7 @@ mod tests {
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
|
||||||
// Scan the cache again
|
// 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
|
// Data-only chain should be valid
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
@ -324,7 +324,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb2);
|
insert_into_cache(db_cache, &cb2);
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Data-only chain should be valid
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
@ -389,7 +389,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb2);
|
insert_into_cache(db_cache, &cb2);
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Data-only chain should be valid
|
||||||
validate_combined_chain(db_cache, db_data).unwrap();
|
validate_combined_chain(db_cache, db_data).unwrap();
|
||||||
|
@ -454,7 +454,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb2);
|
insert_into_cache(db_cache, &cb2);
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Account balance should reflect both received notes
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value + value2);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value + value2);
|
||||||
|
|
|
@ -30,8 +30,13 @@ struct WitnessRow {
|
||||||
witness: IncrementalWitness<Node>,
|
witness: IncrementalWitness<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scans new blocks added to the cache for any transactions received by the tracked
|
/// Scans at most `limit` new blocks added to the cache for any transactions received by
|
||||||
/// accounts.
|
/// 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
|
/// 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
|
/// 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;
|
/// 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
|
/// [`init_blocks_table`]: crate::init::init_blocks_table
|
||||||
pub fn scan_cached_blocks<P: AsRef<Path>, Q: AsRef<Path>>(
|
pub fn scan_cached_blocks<P: AsRef<Path>, Q: AsRef<Path>>(
|
||||||
db_cache: P,
|
db_cache: P,
|
||||||
db_data: Q,
|
db_data: Q,
|
||||||
|
limit: Option<i32>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let cache = Connection::open(db_cache)?;
|
let cache = Connection::open(db_cache)?;
|
||||||
let data = Connection::open(db_data)?;
|
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
|
// Fetch the CompactBlocks we need to scan
|
||||||
let mut stmt_blocks = cache
|
let mut stmt_blocks = cache.prepare(
|
||||||
.prepare("SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC")?;
|
"SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC LIMIT ?",
|
||||||
let rows = stmt_blocks.query_map(&[last_height], |row| {
|
)?;
|
||||||
|
let rows = stmt_blocks.query_map(&[last_height, limit.unwrap_or(i32::max_value())], |row| {
|
||||||
Ok(CompactBlockRow {
|
Ok(CompactBlockRow {
|
||||||
height: row.get(0)?,
|
height: row.get(0)?,
|
||||||
data: row.get(1)?,
|
data: row.get(1)?,
|
||||||
|
@ -356,7 +363,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb1);
|
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);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
|
||||||
// We cannot scan a block of height SAPLING_ACTIVATION_HEIGHT + 2 next
|
// We cannot scan a block of height SAPLING_ACTIVATION_HEIGHT + 2 next
|
||||||
|
@ -373,7 +380,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb3);
|
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"),
|
Ok(_) => panic!("Should have failed"),
|
||||||
Err(e) => assert_eq!(
|
Err(e) => assert_eq!(
|
||||||
e.to_string(),
|
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
|
// If we add a block of height SAPLING_ACTIVATION_HEIGHT + 1, we can now scan both
|
||||||
insert_into_cache(db_cache, &cb2);
|
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!(
|
assert_eq!(
|
||||||
get_balance(db_data, 0).unwrap(),
|
get_balance(db_data, 0).unwrap(),
|
||||||
Amount::from_u64(150_000).unwrap()
|
Amount::from_u64(150_000).unwrap()
|
||||||
|
@ -423,7 +430,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb);
|
insert_into_cache(db_cache, &cb);
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Account balance should reflect the received note
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
@ -434,7 +441,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb2);
|
insert_into_cache(db_cache, &cb2);
|
||||||
|
|
||||||
// Scan the cache again
|
// 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
|
// Account balance should reflect both received notes
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value + value2);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value + value2);
|
||||||
|
@ -469,7 +476,7 @@ mod tests {
|
||||||
insert_into_cache(db_cache, &cb);
|
insert_into_cache(db_cache, &cb);
|
||||||
|
|
||||||
// Scan the cache
|
// 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
|
// Account balance should reflect the received note
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
@ -491,7 +498,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Scan the cache again
|
// 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
|
// Account balance should equal the change
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value - value2);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value - value2);
|
||||||
|
|
|
@ -468,7 +468,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Verified balance matches total balance
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
@ -482,7 +482,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Verified balance does not include the second note
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), value + value);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value + value);
|
||||||
|
@ -518,7 +518,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Second spend still fails
|
||||||
match create_to_address(
|
match create_to_address(
|
||||||
|
@ -545,7 +545,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Second spend should now succeed
|
||||||
create_to_address(
|
create_to_address(
|
||||||
|
@ -584,7 +584,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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);
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
|
||||||
// Send some of the funds to another address
|
// Send some of the funds to another address
|
||||||
|
@ -629,7 +629,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Second spend still fails
|
||||||
match create_to_address(
|
match create_to_address(
|
||||||
|
@ -656,7 +656,7 @@ mod tests {
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
insert_into_cache(db_cache, &cb);
|
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
|
// Second spend should now succeed
|
||||||
create_to_address(
|
create_to_address(
|
||||||
|
|
Loading…
Reference in New Issue