From 7dba477f33e9eb72c2b54056872605551ad436bc Mon Sep 17 00:00:00 2001 From: Sosthene00 <674694@protonmail.ch> Date: Mon, 8 Apr 2024 18:15:26 +0200 Subject: [PATCH] Refactoring --- Cargo.lock | 84 +++++++++++++-------------- src/main.rs | 164 +++++++++++++++++++++------------------------------- src/scan.rs | 30 +++++----- 3 files changed, 125 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 193a55b..437e338 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,15 +60,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.31.1" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd00f3c09b5f21fb357abe32d29946eb8bb7a0862bae62c0b5e4a692acbbe73c" +checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" dependencies = [ "base64 0.21.7", "bech32 0.10.0-beta", @@ -194,7 +194,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "856ffbee2e492c23bca715d72ea34aae80d58400f2bda26a82015d6bc2ec3662" dependencies = [ - "bitcoin 0.31.1", + "bitcoin 0.31.2", "serde", "serde_json", ] @@ -205,7 +205,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e21acea23b5ec33f912350f18adee9a08bd513dca9f66f0e2cfe9d756ef46" dependencies = [ - "bitcoin 0.31.1", + "bitcoin 0.31.2", "zmq", "zmq-sys", ] @@ -239,15 +239,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "1fd97381a8cc6493395a5afc4c691c1084b3768db713b73aa215217aa245d153" dependencies = [ "jobserver", "libc", @@ -271,9 +271,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", @@ -537,9 +537,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -678,9 +678,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -689,9 +689,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" @@ -746,9 +746,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "miniz_oxide" @@ -818,9 +818,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -896,9 +896,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -916,9 +916,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -939,9 +939,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "ring" @@ -1095,9 +1095,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -1123,7 +1123,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_derive", "serde_json", @@ -1180,9 +1180,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -1197,10 +1197,10 @@ dependencies = [ [[package]] name = "sp_backend" version = "0.1.0" -source = "git+https://github.com/Sosthene00/sp-backend?branch=sp_client#32967c214df9a25daef551a372b89c400f2369f8" +source = "git+https://github.com/Sosthene00/sp-backend?branch=sp_client#d09c92ac7718c34c9ce3ff55298140ebda0b2e1a" dependencies = [ "anyhow", - "bitcoin 0.31.1", + "bitcoin 0.31.2", "serde", "serde_json", "silentpayments", @@ -1220,9 +1220,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.53" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -1325,9 +1325,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -1401,7 +1401,7 @@ version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", diff --git a/src/main.rs b/src/main.rs index 4730f30..b55db89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ use std::{ fmt::Debug, net::SocketAddr, ops::Deref, - path::PathBuf, str::FromStr, sync::{Arc, Mutex, MutexGuard}, }; @@ -12,11 +11,6 @@ use std::{ use bitcoincore_rpc::json::{self as bitcoin_json}; use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt}; use log::{debug, error}; -use sp_backend::bitcoin::secp256k1::{ - rand::{thread_rng, Rng}, - Error as Secp256k1Error, Keypair, Message as Secp256k1Message, PublicKey, Scalar, Secp256k1, - SecretKey, ThirtyTwoByteHash, -}; use sp_backend::bitcoin::{ absolute::LockTime, consensus::deserialize, @@ -29,6 +23,14 @@ use sp_backend::bitcoin::{ XOnlyPublicKey, }; use sp_backend::spclient::OutputList; +use sp_backend::{ + bitcoin::secp256k1::{ + rand::{thread_rng, Rng}, + Error as Secp256k1Error, Keypair, Message as Secp256k1Message, PublicKey, Scalar, + Secp256k1, SecretKey, ThirtyTwoByteHash, + }, + spclient::SpWallet, +}; use sp_backend::db::{JsonFile, Storage}; use sp_backend::silentpayments::receiving::Label; @@ -73,23 +75,18 @@ impl MutexExt for Mutex { } #[derive(Debug)] -pub(crate) struct SilentPaymentWallet { - sp_client: Mutex, - sp_outputs: Mutex, +struct SilentPaymentWallet { + sp_wallet: Mutex, storage: Mutex, } impl SilentPaymentWallet { - pub fn get_client(&self) -> Result> { - self.sp_client.lock_anyhow() + pub fn get_wallet(&self) -> Result> { + self.sp_wallet.lock_anyhow() } - pub fn get_outputs(&self) -> Result> { - self.sp_outputs.lock_anyhow() - } - - pub fn get_storage(&self) -> Result> { - self.storage.lock_anyhow() + pub fn save(&self) -> Result<()> { + self.storage.lock_anyhow()?.save(&self.sp_wallet) } } @@ -227,7 +224,7 @@ fn faucet_send( let mut new_outpoints: HashMap; // do we have a sp output available ? - let available_outpoints = sp_wallet.get_outputs()?.to_spendable_list(); + let available_outpoints = sp_wallet.get_wallet()?.get_outputs().to_spendable_list(); let available_amt = available_outpoints .iter() @@ -260,16 +257,19 @@ fn faucet_send( log::debug!("fee estimate for 6 blocks: {}", fee_estimate); - let wallet = sp_wallet.get_client()?; + let wallet = sp_wallet.get_wallet()?; - let mut new_psbt = wallet.create_new_psbt(inputs.clone(), vec![recipient], None)?; + let mut new_psbt = + wallet + .get_client() + .create_new_psbt(inputs.clone(), vec![recipient], None)?; log::debug!("Created psbt: {}", new_psbt); SpClient::set_fees(&mut new_psbt, fee_estimate, sp_address.into())?; - wallet.fill_sp_outputs(&mut new_psbt)?; + wallet.get_client().fill_sp_outputs(&mut new_psbt)?; log::debug!("Definitive psbt: {}", new_psbt); let mut aux_rand = [0u8; 32]; thread_rng().fill(&mut aux_rand); - let mut signed = wallet.sign_psbt(new_psbt, &aux_rand)?; + let mut signed = wallet.get_client().sign_psbt(new_psbt, &aux_rand)?; log::debug!("signed psbt: {}", signed); SpClient::finalize_psbt(&mut signed)?; @@ -282,8 +282,11 @@ fn faucet_send( .map(|i| (i.previous_output.txid.to_string(), i.previous_output.vout)) .collect(); - let our_sp_address: SilentPaymentAddress = - wallet.sp_receiver.get_receiving_address().try_into()?; + let our_sp_address: SilentPaymentAddress = wallet + .get_client() + .sp_receiver + .get_receiving_address() + .try_into()?; let our_spend_pubkey = our_sp_address.get_spend_key(); let secp = Secp256k1::verification_only(); let input_pubkeys: Result, Secp256k1Error> = inputs @@ -296,7 +299,8 @@ fn faucet_send( let input_pubkeys = input_pubkeys?; let input_pubkeys: Vec<&PublicKey> = input_pubkeys.iter().collect(); let partial_tweak = calculate_tweak_data(&input_pubkeys, &outpoints)?; - let ecdh_shared_secret = calculate_shared_secret(partial_tweak, wallet.get_scan_key())?; + let ecdh_shared_secret = + calculate_shared_secret(partial_tweak, wallet.get_client().get_scan_key())?; let outputs_to_check: Result, Secp256k1Error> = final_tx .output @@ -305,6 +309,7 @@ fn faucet_send( .collect(); let ours = wallet + .get_client() .sp_receiver .scan_transaction(&ecdh_shared_secret, outputs_to_check?)?; @@ -351,7 +356,7 @@ fn faucet_send( .get(0) .expect("Failed to generate keys") .to_owned(); - let change_sp_address = sp_wallet.get_client()?.get_receiving_address(); + let change_sp_address = sp_wallet.get_wallet()?.get_client().get_receiving_address(); let change_output_key: XOnlyPublicKey = generate_recipient_pubkeys(vec![change_sp_address], partial_secret)? .into_values() @@ -406,17 +411,19 @@ fn faucet_send( first_tx = Some(core_tx); - let client = sp_wallet.get_client()?; + let client = sp_wallet.get_wallet()?; let input_pubkey = &keypair.public_key(); let input_pub_keys: Vec<&PublicKey> = vec![input_pubkey]; let partial_tweak = calculate_tweak_data(&input_pub_keys, &outpoints)?; - let ecdh_shared_secret = calculate_shared_secret(partial_tweak, client.get_scan_key())?; + let ecdh_shared_secret = + calculate_shared_secret(partial_tweak, client.get_client().get_scan_key())?; let p2tr_outs = vec![ext_output_key, change_output_key]; let ours = client + .get_client() .sp_receiver .scan_transaction(&ecdh_shared_secret, p2tr_outs)?; @@ -443,12 +450,13 @@ fn faucet_send( } // update our sp_client with the change output(s) - let mut outputs = sp_wallet.get_outputs()?; - - outputs.extend_from(new_outpoints); + sp_wallet + .get_wallet()? + .get_mut_outputs() + .extend_from(new_outpoints); // save to disk - sp_wallet.get_storage()?.save(outputs.deref())?; + sp_wallet.save()?; Ok(final_tx.txid()) } @@ -648,34 +656,15 @@ async fn handle_zmq( Ok(p) => p, Err(_) => continue, } - }, + } "rawblock" => { // scan the block for our outputs - match scan_blocks(shared_daemon.clone(), sp_wallet.clone(), 1) { - Ok(()) => { - let updated = match sp_wallet.get_outputs() { - Ok(sp_outputs) => sp_outputs, - Err(e) => { - log::error!("{}", e); - continue; - } - }; - match sp_wallet.get_storage() { - Ok(storage) => { - if let Err(e) = storage.save(updated.deref()) { - log::error!("{}", e); - } - } - Err(e) => { - log::error!("{}", e); - } - } - } - Err(e) => log::error!("{}", e), - }; + if let Err(e) = scan_blocks(shared_daemon.clone(), sp_wallet.clone(), 1) { + log::error!("{}", e); + } flatten_msg(&core_msg.serialize_to_vecs()) - }, + } _ => flatten_msg(&core_msg.serialize_to_vecs()), }; @@ -686,7 +675,6 @@ async fn handle_zmq( ) { log::error!("{}", e.to_string()); } - } }); } @@ -716,27 +704,12 @@ async fn main() -> Result<()> { .get_current_height()? .try_into()?; - let mut config_dir = PathBuf::from_str(&env::var("HOME")?)?; - config_dir.push(".4nk"); - let sp_client_file = JsonFile::new(&config_dir, wallet_name.clone())?; - let sp_outputs_file = JsonFile::new(&config_dir, format!("{}.db", wallet_name))?; + let mut config_dir = env::var("HOME")?; + config_dir.push_str("/.4nk"); + let sp_wallet_file = JsonFile::new(&config_dir, &wallet_name); // load an existing sp_wallet, or create a new one - let (sp_client, sp_outputs) = match >::load(&sp_client_file) { - Ok(existing) => { - if let Ok(our_outputs) = >::load(&sp_outputs_file) { - (existing, our_outputs) - } else { - let our_address = SilentPaymentAddress::try_from(existing.get_receiving_address())?; - let new_outputs = OutputList::new( - our_address.get_scan_key(), - our_address.get_spend_key(), - current_tip, - ); - sp_outputs_file.save(&new_outputs)?; - (existing, new_outputs) - } - } + let sp_wallet = match >::load(&sp_wallet_file) { Err(_) => { let mut seed = [0u8; 64]; thread_rng().fill(&mut seed); @@ -751,45 +724,42 @@ async fn main() -> Result<()> { ) .expect("Failed to create a new SpClient"); - let new_address = SilentPaymentAddress::try_from(new_client.get_receiving_address())?; + let mut wallet = SpWallet::new(new_client, None)?; - let new_outputs = OutputList::new( - new_address.get_scan_key(), - new_address.get_spend_key(), - current_tip, - ); + // set birthday to avoid unnecessary scanning + let outputs = wallet.get_mut_outputs(); + outputs.set_birthday(current_tip); + outputs.update_last_scan(current_tip); - sp_client_file.save(&new_client)?; - sp_outputs_file.save(&new_outputs)?; - - (new_client, new_outputs) + wallet } + Ok(wallet) => wallet, }; log::info!( "Using wallet {} with address {}", - sp_client.label, - sp_client.get_receiving_address() + sp_wallet.get_client().label, + sp_wallet.get_client().get_receiving_address() ); log::info!( "Found {} outputs for a total balance of {}", - sp_outputs.to_spendable_list().len(), - sp_outputs.get_balance() + sp_wallet.get_outputs().to_spendable_list().len(), + sp_wallet.get_outputs().get_balance() ); - let last_scan = sp_outputs.get_last_scan(); + let last_scan = sp_wallet.get_outputs().get_last_scan(); - let shared_sp_client = Mutex::new(sp_client); - let shared_sp_outputs = Mutex::new(sp_outputs); - let shared_outputs_storage = Mutex::new(sp_outputs_file); + let shared_sp_wallet = Mutex::new(sp_wallet); + let shared_wallet_storage = Mutex::new(sp_wallet_file); let sp_wallet = Arc::new(SilentPaymentWallet { - sp_client: shared_sp_client, - sp_outputs: shared_sp_outputs, - storage: shared_outputs_storage, + sp_wallet: shared_sp_wallet, + storage: shared_wallet_storage, }); + sp_wallet.save()?; + if last_scan < current_tip { log::info!("Scanning for our outputs"); scan_blocks( diff --git a/src/scan.rs b/src/scan.rs index 7e25403..fecb05b 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -1,5 +1,4 @@ use std::collections::HashMap; -use std::ops::Deref; use std::str::FromStr; use std::sync::Arc; @@ -10,7 +9,6 @@ use sp_backend::bitcoin::bip158::BlockFilter; use sp_backend::bitcoin::hex::DisplayHex; use sp_backend::bitcoin::secp256k1::{All, PublicKey, Scalar, Secp256k1, SecretKey}; use sp_backend::bitcoin::{BlockHash, OutPoint, Transaction, TxOut, XOnlyPublicKey}; -use sp_backend::db::Storage; use sp_backend::silentpayments::receiving::Receiver; use sp_backend::spclient::{OutputSpendStatus, OwnedOutput}; use tokio::time::Instant; @@ -184,7 +182,7 @@ pub fn scan_blocks( let core = shared_daemon.lock_anyhow()?; let secp = Secp256k1::new(); - let scan_height = sp_wallet.get_outputs()?.get_last_scan(); + let scan_height = sp_wallet.get_wallet()?.get_outputs().get_last_scan(); let tip_height: u32 = core.get_current_height()?.try_into()?; // 0 means scan to tip @@ -211,9 +209,9 @@ pub fn scan_blocks( let mut tweak_data_map = electrum_client.sp_tweaks(start as usize)?; - let scan_sk = sp_wallet.get_client()?.get_scan_key(); + let scan_sk = sp_wallet.get_wallet()?.get_client().get_scan_key(); - let sp_receiver = sp_wallet.get_client()?.sp_receiver.clone(); + let sp_receiver = sp_wallet.get_wallet()?.get_client().sp_receiver.clone(); let start_time = Instant::now(); for (blkheight, blkhash, blkfilter) in filters { @@ -229,7 +227,7 @@ pub fn scan_blocks( // check if owned inputs are spent let our_outputs: HashMap = - sp_wallet.get_outputs()?.to_outpoints_list(); + sp_wallet.get_wallet()?.get_outputs().to_outpoints_list(); let owned_spks: Result>> = our_outputs .iter() @@ -248,18 +246,22 @@ pub fn scan_blocks( let utxo_created_in_block = scan_block_outputs(&sp_receiver, &blk.txdata, blkheight.into(), spk2secret)?; if !utxo_created_in_block.is_empty() { - sp_wallet.get_outputs()?.extend_from(utxo_created_in_block); + sp_wallet + .get_wallet()? + .get_mut_outputs() + .extend_from(utxo_created_in_block); } // update the list of outputs just in case // utxos may be created and destroyed in the same block let updated_outputs: HashMap = - sp_wallet.get_outputs()?.to_outpoints_list(); + sp_wallet.get_wallet()?.get_outputs().to_outpoints_list(); // search inputs and mark as mined let utxo_destroyed_in_block = scan_block_inputs(updated_outputs, blk.txdata)?; if !utxo_destroyed_in_block.is_empty() { - let mut outputs = sp_wallet.get_outputs()?; + let mut wallet = sp_wallet.get_wallet()?; + let outputs = wallet.get_mut_outputs(); for outpoint in utxo_destroyed_in_block { outputs.mark_mined(outpoint, blkhash)?; } @@ -274,11 +276,11 @@ pub fn scan_blocks( ); // update last_scan height - let mut updated = sp_wallet.get_outputs()?; - - updated.update_last_scan(end); - - sp_wallet.get_storage()?.save(updated.deref())?; + sp_wallet + .get_wallet()? + .get_mut_outputs() + .update_last_scan(end); + sp_wallet.save()?; Ok(()) }