From 443ad173dd770eafff632ae9ad03f6c002e4f310 Mon Sep 17 00:00:00 2001 From: Willem Olding Date: Mon, 30 Sep 2024 13:39:00 -0400 Subject: [PATCH 1/2] remove the legacy sync algo --- Cargo.toml | 1 - justfile | 10 +-- src/bindgen/wallet.rs | 23 +----- src/wallet.rs | 137 +--------------------------------- tests/message-board-sync.rs | 18 +---- tests/simple-sync-and-send.rs | 16 +--- 6 files changed, 17 insertions(+), 188 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3881961..ac92dd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,6 @@ native = ["tonic/channel", "tonic/gzip", "tonic/tls-webpki-roots", "tokio/macros sqlite-db = ["dep:zcash_client_sqlite"] console_error_panic_hook = ["dep:console_error_panic_hook"] no-bundler = ["wasm-bindgen-rayon?/no-bundler", "wasm_thread/no-bundler"] -sync2 = [] [dependencies] ## Web dependencies diff --git a/justfile b/justfile index 1c62999..46ea915 100644 --- a/justfile +++ b/justfile @@ -2,26 +2,26 @@ default: just --list build *features: - wasm-pack build --no-opt -t web --scope webzjs --release --out-dir ./packages/webz-core --no-default-features --features="wasm wasm-parallel sync2 {{features}}" -Z build-std="panic_abort,std" + wasm-pack build --no-opt -t web --scope webzjs --release --out-dir ./packages/webz-core --no-default-features --features="wasm wasm-parallel {{features}}" -Z build-std="panic_abort,std" # All Wasm Tests test-web *features: WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --firefox --no-default-features --features "wasm no-bundler {{features}}" -Z build-std="panic_abort,std" -# sync message board in the web: addigional args: sync2 +# sync message board in the web: addigional args: test-message-board-web *features: WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --chrome --no-default-features --features "wasm no-bundler {{features}}" -Z build-std="panic_abort,std" --test message-board-sync -# simple example in the web: additional args: sync2 +# simple example in the web: additional args: test-simple-web *features: WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --chrome --no-default-features --features "wasm no-bundler {{features}}" -Z build-std="panic_abort,std" --test simple-sync-and-send -# simple example: additional args: sync2, sqlite-db +# simple example: additional args:, sqlite-db example-simple *features: RUST_LOG="info,zcash_client_backend::sync=debug" cargo run -r --example simple-sync --features "native {{features}}" -# sync the message board: additional args: sync2, sqlite-db +# sync the message board: additional args:, sqlite-db example-message-board *features: RUST_LOG=info,zcash_client_backend::sync=debug cargo run -r --example message-board-sync --features "native {{features}}" diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 0d0b1e7..400175b 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -117,31 +117,14 @@ impl WebWallet { self.inner.suggest_scan_ranges().await } - /// Synchronize the wallet with the blockchain up to the tip - /// The passed callback will be called for every batch of blocks processed with the current progress - pub async fn sync(&self, callback: &js_sys::Function) -> Result<(), Error> { - let callback = move |scanned_to: BlockHeight, tip: BlockHeight| { - let this = JsValue::null(); - let _ = callback.call2( - &this, - &JsValue::from(Into::::into(scanned_to)), - &JsValue::from(Into::::into(tip)), - ); - }; - - self.inner.sync(callback).await?; - - Ok(()) - } - /// Synchronize the wallet with the blockchain up to the tip using zcash_client_backend's algo - pub async fn sync2(&self) -> Result<(), Error> { + pub async fn sync(&self) -> Result<(), Error> { assert!(!thread::is_web_worker_thread()); let db = self.inner.clone(); let sync_handler = thread::Builder::new() - .name("sync2".to_string()) + .name("sync".to_string()) .spawn_async(|| async { assert!(thread::is_web_worker_thread()); tracing::debug!( @@ -150,7 +133,7 @@ impl WebWallet { ); let db = db; - db.sync2().await.unwrap_throw(); + db.sync().await.unwrap_throw(); }) .unwrap_throw() .join_async(); diff --git a/src/wallet.rs b/src/wallet.rs index 71cc1cc..63d385f 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -1,7 +1,6 @@ use std::num::NonZeroU32; use bip0039::{English, Mnemonic}; -use futures_util::{StreamExt, TryStreamExt}; use nonempty::NonEmpty; use secrecy::{ExposeSecret, SecretVec, Zeroize}; use tonic::{ @@ -22,23 +21,21 @@ use zcash_address::ZcashAddress; use zcash_client_backend::data_api::wallet::{ create_proposed_transactions, input_selection::GreedyInputSelector, propose_transfer, }; -use zcash_client_backend::data_api::{scanning::ScanRange, WalletCommitmentTrees}; +use zcash_client_backend::data_api::WalletCommitmentTrees; use zcash_client_backend::data_api::{ - AccountBirthday, AccountPurpose, InputSource, NullifierQuery, WalletRead, WalletSummary, - WalletWrite, + AccountBirthday, AccountPurpose, InputSource, WalletRead, WalletSummary, WalletWrite, }; use zcash_client_backend::fees::zip317::SingleOutputChangeStrategy; use zcash_client_backend::proposal::Proposal; use zcash_client_backend::proto::service::{ self, compact_tx_streamer_client::CompactTxStreamerClient, }; -use zcash_client_backend::scanning::{scan_block, Nullifiers, ScanningKeys}; use zcash_client_backend::wallet::OvkPolicy; use zcash_client_backend::zip321::{Payment, TransactionRequest}; use zcash_client_backend::ShieldedProtocol; use zcash_client_memory::{MemBlockCache, MemoryWalletDb}; use zcash_keys::keys::{UnifiedFullViewingKey, UnifiedSpendingKey}; -use zcash_primitives::consensus::{self, BlockHeight, Network}; +use zcash_primitives::consensus::{self, Network}; use zcash_primitives::transaction::components::amount::NonNegativeAmount; use zcash_primitives::transaction::fees::zip317::FeeRule; use zcash_primitives::transaction::TxId; @@ -228,7 +225,7 @@ where })?) } - pub async fn sync2(&self) -> Result<(), Error> { + pub async fn sync(&self) -> Result<(), Error> { let mut client = self.client.clone(); // TODO: This should be held in the Wallet struct so we can download in parallel let db_cache = MemBlockCache::new(); @@ -245,113 +242,6 @@ where .map_err(Into::into) } - /// Synchronize the wallet with the blockchain up to the tip - /// The passed callback will be called for every batch of blocks processed with the current progress - pub async fn sync(&self, callback: impl Fn(BlockHeight, BlockHeight)) -> Result<(), Error> { - let tip = self.update_chain_tip().await?; - - tracing::info!("Retrieving suggested scan ranges from wallet"); - let scan_ranges = self.db.read().await.suggest_scan_ranges()?; - tracing::info!("Suggested scan ranges: {:?}", scan_ranges); - - // TODO: Ensure wallet's view of the chain tip as of the previous wallet session is valid. - // See https://github.com/Electric-Coin-Company/zec-sqlite-cli/blob/8c2e49f6d3067ec6cc85248488915278c3cb1c5a/src/commands/sync.rs#L157 - - // Download and process all blocks in the requested ranges - // Split each range into BATCH_SIZE chunks to avoid requesting too many blocks at once - for scan_range in scan_ranges.into_iter().flat_map(|r| { - // Limit the number of blocks we download and scan at any one time. - (0..).scan(r, |acc, _| { - if acc.is_empty() { - None - } else if let Some((cur, next)) = acc.split_at(acc.block_range().start + BATCH_SIZE) - { - *acc = next; - Some(cur) - } else { - let cur = acc.clone(); - let end = acc.block_range().end; - *acc = ScanRange::from_parts(end..end, acc.priority()); - Some(cur) - } - }) - }) { - self.fetch_and_scan_range( - scan_range.block_range().start.into(), - scan_range.block_range().end.into(), - ) - .await?; - callback(scan_range.block_range().end, tip); - } - - Ok(()) - } - - /// Download and process all blocks in the given range - async fn fetch_and_scan_range(&self, start: u32, end: u32) -> Result<(), Error> { - let mut client = self.client.clone(); - // get the chainstate prior to the range - let tree_state = client - .get_tree_state(service::BlockId { - height: (start - 1).into(), - ..Default::default() - }) - .await?; - let chainstate = tree_state.into_inner().to_chain_state()?; - - // Get the scanning keys from the DB - let account_ufvks = self.db.read().await.get_unified_full_viewing_keys()?; - let scanning_keys = ScanningKeys::from_account_ufvks(account_ufvks); - - // Get the nullifiers for the unspent notes we are tracking - let nullifiers = Nullifiers::new( - self.db - .read() - .await - .get_sapling_nullifiers(NullifierQuery::Unspent)?, - self.db - .read() - .await - .get_orchard_nullifiers(NullifierQuery::Unspent)?, - ); - - let range = service::BlockRange { - start: Some(service::BlockId { - height: start.into(), - ..Default::default() - }), - end: Some(service::BlockId { - height: (end - 1).into(), - ..Default::default() - }), - }; - - tracing::info!("Scanning block range: {:?} to {:?}", start, end); - - let scanned_blocks = client - .get_block_range(range) - .await? - .into_inner() - .map(|compact_block| { - scan_block( - &self.network, - compact_block.unwrap(), - &scanning_keys, - &nullifiers, - None, - ) - }) - .try_collect() - .await?; - - self.db - .write() - .await - .put_blocks(&chainstate, scanned_blocks)?; - - Ok(()) - } - pub async fn get_wallet_summary(&self) -> Result>, Error> { Ok(self .db @@ -360,25 +250,6 @@ where .get_wallet_summary(self.min_confirmations.into())?) } - pub(crate) async fn update_chain_tip(&self) -> Result { - tracing::info!("Retrieving chain tip from lightwalletd"); - - let tip_height = self - .client - .clone() - .get_latest_block(service::ChainSpec::default()) - .await? - .get_ref() - .height - .try_into() - .unwrap(); - - tracing::info!("Latest block height is {}", tip_height); - self.db.write().await.update_chain_tip(tip_height)?; - - Ok(tip_height) - } - /// /// Create a transaction proposal to send funds from the wallet to a given address /// diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs index 829bb7a..8163e54 100644 --- a/tests/message-board-sync.rs +++ b/tests/message-board-sync.rs @@ -39,21 +39,9 @@ async fn test_message_board() { let id = w.import_ufvk(&ufvk_str, Some(2477329)).await.unwrap(); tracing::info!("Created account with id: {}", id); - #[cfg(not(feature = "sync2"))] - { - tracing::info!("Syncing wallet with our sync impl"); - w.sync(&js_sys::Function::new_with_args( - "scanned_to, tip", - "console.log('Scanned: ', scanned_to, '/', tip)", - )) - .await - .unwrap(); - } - #[cfg(feature = "sync2")] - { - tracing::info!("Syncing wallet with sync2"); - w.sync2().await.unwrap(); - } + tracing::info!("Syncing wallet with our sync impl"); + w.sync().await.unwrap(); + tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().await.unwrap(); diff --git a/tests/simple-sync-and-send.rs b/tests/simple-sync-and-send.rs index 68b48c7..b5f2e1f 100644 --- a/tests/simple-sync-and-send.rs +++ b/tests/simple-sync-and-send.rs @@ -33,20 +33,8 @@ async fn test_get_and_scan_range() { let w_clone = w.clone(); let w = w_clone; - #[cfg(not(feature = "sync2"))] - { - w.sync(&js_sys::Function::new_with_args( - "scanned_to, tip", - "console.log('Scanned: ', scanned_to, '/', tip)", - )) - .await - .unwrap(); - } - #[cfg(feature = "sync2")] - { - tracing::info!("Syncing wallet with sync2"); - w.sync2().await.unwrap(); - } + w.sync().await.unwrap(); + tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().await.unwrap(); From 6a1dee7f90f81f50369ec0dba4ad5913ab6a41b8 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Tue, 1 Oct 2024 16:03:41 -0400 Subject: [PATCH 2/2] clippy --- src/bindgen/wallet.rs | 2 +- src/wallet.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 38e6398..3917963 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -17,7 +17,7 @@ use zcash_client_backend::proto::service::{ }; use zcash_client_memory::MemoryWalletDb; use zcash_keys::keys::UnifiedFullViewingKey; -use zcash_primitives::consensus::{self, BlockHeight}; +use zcash_primitives::consensus; use zcash_primitives::transaction::TxId; pub type MemoryWallet = Wallet, T>; diff --git a/src/wallet.rs b/src/wallet.rs index 920160f..22bb521 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -23,8 +23,7 @@ use zcash_client_backend::data_api::wallet::{ }; use zcash_client_backend::data_api::WalletCommitmentTrees; use zcash_client_backend::data_api::{ - Account, AccountBirthday, AccountPurpose, InputSource, NullifierQuery, WalletRead, - WalletSummary, WalletWrite, + Account, AccountBirthday, AccountPurpose, InputSource, WalletRead, WalletSummary, WalletWrite, }; use zcash_client_backend::fees::zip317::SingleOutputChangeStrategy; use zcash_client_backend::proposal::Proposal;