mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
Change check_repair + certain functions to lock more granularly (#252)
* Rename check-repair -> scan, make lock logic more granular * rustfmt * update owner api implementations where to allow granular locking where required * rustfmt * store init state on startup to determine whether full utxo scan is required for new wallets * rustfmt * fix for init status persist * add start height argument to scan * rustfmt
This commit is contained in:
+35
-30
@@ -21,7 +21,6 @@ use std::io::{Read, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::path::Path;
|
||||
|
||||
use failure::ResultExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::blake2::blake2b::{Blake2b, Blake2bResult};
|
||||
@@ -31,10 +30,9 @@ use crate::store::{self, option_to_not_found, to_key, to_key_u64};
|
||||
|
||||
use crate::core::core::Transaction;
|
||||
use crate::core::ser;
|
||||
use crate::libwallet::{check_repair, restore};
|
||||
use crate::libwallet::{
|
||||
AcctPathMapping, Context, Error, ErrorKind, NodeClient, OutputData, ScannedBlockInfo,
|
||||
TxLogEntry, WalletBackend, WalletOutputBatch,
|
||||
TxLogEntry, WalletBackend, WalletInitStatus, WalletOutputBatch,
|
||||
};
|
||||
use crate::util::secp::constants::SECRET_KEY_SIZE;
|
||||
use crate::util::secp::key::SecretKey;
|
||||
@@ -55,6 +53,8 @@ const TX_LOG_ID_PREFIX: u8 = 'i' as u8;
|
||||
const ACCOUNT_PATH_MAPPING_PREFIX: u8 = 'a' as u8;
|
||||
const LAST_SCANNED_BLOCK: u8 = 'l' as u8;
|
||||
const LAST_SCANNED_KEY: &str = "LAST_SCANNED_KEY";
|
||||
const WALLET_INIT_STATUS: u8 = 'w' as u8;
|
||||
const WALLET_INIT_STATUS_KEY: &str = "WALLET_INIT_STATUS";
|
||||
|
||||
/// test to see if database files exist in the current directory. If so,
|
||||
/// use a DB backend for all operations
|
||||
@@ -397,6 +397,14 @@ where
|
||||
}))
|
||||
}
|
||||
|
||||
fn batch_no_mask<'a>(&'a mut self) -> Result<Box<dyn WalletOutputBatch<K> + 'a>, Error> {
|
||||
Ok(Box::new(Batch {
|
||||
_store: self,
|
||||
db: RefCell::new(Some(self.db.batch()?)),
|
||||
keychain: None,
|
||||
}))
|
||||
}
|
||||
|
||||
fn current_child_index<'a>(&mut self, parent_key_id: &Identifier) -> Result<u32, Error> {
|
||||
let index = {
|
||||
let batch = self.db.batch()?;
|
||||
@@ -460,33 +468,17 @@ where
|
||||
Ok(last_scanned_block)
|
||||
}
|
||||
|
||||
fn restore(
|
||||
&mut self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
to_height: u64,
|
||||
) -> Result<Option<ScannedBlockInfo>, Error> {
|
||||
let res = restore(self, keychain_mask, to_height).context(ErrorKind::Restore)?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn check_repair(
|
||||
&mut self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
delete_unconfirmed: bool,
|
||||
start_height: u64,
|
||||
end_height: u64,
|
||||
status_fn: fn(&str),
|
||||
) -> Result<ScannedBlockInfo, Error> {
|
||||
let res = check_repair(
|
||||
self,
|
||||
keychain_mask,
|
||||
delete_unconfirmed,
|
||||
start_height,
|
||||
end_height,
|
||||
status_fn,
|
||||
)
|
||||
.context(ErrorKind::Restore)?;
|
||||
Ok(res)
|
||||
fn init_status<'a>(&mut self) -> Result<WalletInitStatus, Error> {
|
||||
let batch = self.db.batch()?;
|
||||
let init_status_key = to_key(
|
||||
WALLET_INIT_STATUS,
|
||||
&mut WALLET_INIT_STATUS_KEY.as_bytes().to_vec(),
|
||||
);
|
||||
let status = match batch.get_ser(&init_status_key)? {
|
||||
Some(s) => s,
|
||||
None => WalletInitStatus::InitComplete,
|
||||
};
|
||||
Ok(status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,6 +610,19 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_init_status(&mut self, value: WalletInitStatus) -> Result<(), Error> {
|
||||
let init_status_key = to_key(
|
||||
WALLET_INIT_STATUS,
|
||||
&mut WALLET_INIT_STATUS_KEY.as_bytes().to_vec(),
|
||||
);
|
||||
self.db
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.put_ser(&init_status_key, &value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_child_index(&mut self, parent_id: &Identifier, child_n: u32) -> Result<(), Error> {
|
||||
let deriv_key = to_key(DERIV_PREFIX, &mut parent_id.to_bytes().to_vec());
|
||||
self.db
|
||||
|
||||
@@ -19,7 +19,9 @@ use crate::config::{
|
||||
};
|
||||
use crate::core::global;
|
||||
use crate::keychain::Keychain;
|
||||
use crate::libwallet::{Error, ErrorKind, NodeClient, WalletBackend, WalletLCProvider};
|
||||
use crate::libwallet::{
|
||||
Error, ErrorKind, NodeClient, WalletBackend, WalletInitStatus, WalletLCProvider,
|
||||
};
|
||||
use crate::lifecycle::seed::WalletSeed;
|
||||
use crate::util::secp::key::SecretKey;
|
||||
use crate::util::ZeroingString;
|
||||
@@ -181,9 +183,9 @@ where
|
||||
return Err(ErrorKind::WalletSeedExists(msg))?;
|
||||
}
|
||||
}
|
||||
let _ = WalletSeed::init_file(&data_dir_name, mnemonic_length, mnemonic, password);
|
||||
let _ = WalletSeed::init_file(&data_dir_name, mnemonic_length, mnemonic.clone(), password);
|
||||
info!("Wallet seed file created");
|
||||
let _wallet: LMDBBackend<'a, C, K> =
|
||||
let mut wallet: LMDBBackend<'a, C, K> =
|
||||
match LMDBBackend::new(&data_dir_name, self.node_client.clone()) {
|
||||
Err(e) => {
|
||||
let msg = format!("Error creating wallet: {}, Data Dir: {}", e, &data_dir_name);
|
||||
@@ -192,6 +194,13 @@ where
|
||||
}
|
||||
Ok(d) => d,
|
||||
};
|
||||
// Save init status of this wallet, to determine whether it needs a full UTXO scan
|
||||
let mut batch = wallet.batch_no_mask()?;
|
||||
match mnemonic {
|
||||
Some(_) => batch.save_init_status(WalletInitStatus::InitNeedsScanning)?,
|
||||
None => batch.save_init_status(WalletInitStatus::InitNoScanning)?,
|
||||
};
|
||||
batch.commit()?;
|
||||
info!("Wallet database backend created at {}", data_dir_name);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -243,10 +243,8 @@ where
|
||||
C: NodeClient + 'a,
|
||||
K: keychain::Keychain + 'a,
|
||||
{
|
||||
let mut w_lock = wallet.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
let (wallet_refreshed, wallet_info) =
|
||||
owner::retrieve_summary_info(&mut **w, keychain_mask, true, 1)?;
|
||||
owner::retrieve_summary_info(wallet, keychain_mask, true, 1)?;
|
||||
assert!(wallet_refreshed);
|
||||
Ok(wallet_info)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user