feat(scanner): Don't scan and log if we are below sapling height (#8121)
* do not scan and notify if we are below sapling height * separate tip logic check into its own loop
This commit is contained in:
parent
141ea89aad
commit
085bfdc067
|
@ -63,6 +63,19 @@ pub async fn start(
|
|||
storage: Storage,
|
||||
) -> Result<(), Report> {
|
||||
let network = storage.network();
|
||||
let sapling_activation_height = storage.min_sapling_birthday_height();
|
||||
|
||||
// Do not scan and notify if we are below sapling activation height.
|
||||
loop {
|
||||
let tip_height = tip_height(state.clone()).await?;
|
||||
if tip_height < sapling_activation_height {
|
||||
info!("scanner is waiting for sapling activation. Current tip: {}, Sapling activation: {}", tip_height.0, sapling_activation_height.0);
|
||||
tokio::time::sleep(CHECK_INTERVAL).await;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Read keys from the storage on disk, which can block async execution.
|
||||
let key_storage = storage.clone();
|
||||
let key_heights = tokio::task::spawn_blocking(move || key_storage.sapling_keys_last_heights())
|
||||
|
@ -70,7 +83,7 @@ pub async fn start(
|
|||
.await;
|
||||
let key_heights = Arc::new(key_heights);
|
||||
|
||||
let mut height = get_min_height(&key_heights).unwrap_or(storage.min_sapling_birthday_height());
|
||||
let mut height = get_min_height(&key_heights).unwrap_or(sapling_activation_height);
|
||||
|
||||
// Parse and convert keys once, then use them to scan all blocks.
|
||||
// There is some cryptography here, but it should be fast even with thousands of keys.
|
||||
|
@ -149,7 +162,7 @@ pub async fn scan_height_and_store_results(
|
|||
let block = match block {
|
||||
zebra_state::Response::Block(Some(block)) => block,
|
||||
zebra_state::Response::Block(None) => return Ok(None),
|
||||
_ => unreachable!("unmatched response to a state::Tip request"),
|
||||
_ => unreachable!("unmatched response to a state::Block request"),
|
||||
};
|
||||
|
||||
// Scan it with all the keys.
|
||||
|
@ -400,3 +413,20 @@ fn scanned_block_to_db_result<Nf>(
|
|||
fn get_min_height(map: &HashMap<String, Height>) -> Option<Height> {
|
||||
map.values().cloned().min()
|
||||
}
|
||||
|
||||
/// Get tip height or return genesis block height if no tip is available.
|
||||
async fn tip_height(mut state: State) -> Result<Height, Report> {
|
||||
let tip = state
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?
|
||||
.call(zebra_state::Request::Tip)
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?;
|
||||
|
||||
match tip {
|
||||
zebra_state::Response::Tip(Some((height, _hash))) => Ok(height),
|
||||
zebra_state::Response::Tip(None) => Ok(Height(0)),
|
||||
_ => unreachable!("unmatched response to a state::Tip request"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2820,39 +2820,36 @@ async fn fully_synced_rpc_z_getsubtreesbyindex_snapshot_test() -> Result<()> {
|
|||
#[cfg(feature = "shielded-scan")]
|
||||
fn scan_task_starts() -> Result<()> {
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use zebra_scan::tests::ZECPAGES_SAPLING_VIEWING_KEY;
|
||||
|
||||
let _init_guard = zebra_test::init();
|
||||
|
||||
let test_type = TestType::LaunchWithEmptyState {
|
||||
launches_lightwalletd: false,
|
||||
};
|
||||
let mut config = default_test_config(Mainnet)?;
|
||||
let mut keys = IndexMap::new();
|
||||
keys.insert(ZECPAGES_SAPLING_VIEWING_KEY.to_string(), 1);
|
||||
config.shielded_scan.sapling_keys_to_scan = keys;
|
||||
|
||||
let testdir = testdir()?.with_config(&mut config)?;
|
||||
let testdir = &testdir;
|
||||
// Start zebra with the config.
|
||||
let mut zebrad = testdir()?
|
||||
.with_exact_config(&config)?
|
||||
.spawn_child(args!["start"])?
|
||||
.with_timeout(test_type.zebrad_timeout());
|
||||
|
||||
let mut child = testdir.spawn_child(args!["start"])?;
|
||||
// Check scanner was started.
|
||||
zebrad.expect_stdout_line_matches("loaded Zebra scanner cache")?;
|
||||
|
||||
// Run the program and kill it after the scanner starts and the first scanning is done.
|
||||
std::thread::sleep(LAUNCH_DELAY * 2);
|
||||
child.kill(false)?;
|
||||
// Look for 2 scanner notices indicating we are below sapling activation.
|
||||
zebrad.expect_stdout_line_matches("scanner is waiting for sapling activation. Current tip: [0-9]{1,4}, Sapling activation: 419200")?;
|
||||
zebrad.expect_stdout_line_matches("scanner is waiting for sapling activation. Current tip: [0-9]{1,4}, Sapling activation: 419200")?;
|
||||
|
||||
// Kill the node.
|
||||
zebrad.kill(false)?;
|
||||
|
||||
// Check that scan task started and the first scanning is done.
|
||||
let output = child.wait_with_output()?;
|
||||
|
||||
output.stdout_line_contains("spawning shielded scanner with configured viewing keys")?;
|
||||
/*
|
||||
TODO: these lines only happen when we reach sapling activation height
|
||||
output.stdout_line_contains("Scanning the blockchain: now at block")?;
|
||||
output.stdout_line_contains(
|
||||
format!(
|
||||
"Scanning the blockchain for key 0, started at block",
|
||||
)
|
||||
.as_str(),
|
||||
)?;
|
||||
*/
|
||||
let output = zebrad.wait_with_output()?;
|
||||
|
||||
// Make sure the command was killed
|
||||
output.assert_was_killed()?;
|
||||
|
@ -2878,7 +2875,7 @@ fn scan_task_starts() -> Result<()> {
|
|||
#[cfg(feature = "shielded-scan")]
|
||||
fn scan_start_where_left() -> Result<()> {
|
||||
use indexmap::IndexMap;
|
||||
use zebra_scan::storage::db::SCANNER_DATABASE_KIND;
|
||||
use zebra_scan::{storage::db::SCANNER_DATABASE_KIND, tests::ZECPAGES_SAPLING_VIEWING_KEY};
|
||||
|
||||
let _init_guard = zebra_test::init();
|
||||
|
||||
|
@ -2886,10 +2883,9 @@ fn scan_start_where_left() -> Result<()> {
|
|||
let test_type = TestType::UpdateZebraCachedStateNoRpc;
|
||||
if let Some(cache_dir) = test_type.zebrad_state_path("scan test") {
|
||||
// Add a key to the config
|
||||
const ZECPAGES_VIEWING_KEY: &str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz";
|
||||
let mut config = default_test_config(Mainnet)?;
|
||||
let mut keys = IndexMap::new();
|
||||
keys.insert(ZECPAGES_VIEWING_KEY.to_string(), 1);
|
||||
keys.insert(ZECPAGES_SAPLING_VIEWING_KEY.to_string(), 1);
|
||||
config.shielded_scan.sapling_keys_to_scan = keys;
|
||||
|
||||
// Add the cache dir to shielded scan, make it the same as the zebrad cache state.
|
||||
|
|
Loading…
Reference in New Issue