Always take number of confirmations as a parameter.

This commit is contained in:
Kris Nuttycombe 2021-08-27 13:45:36 -06:00
parent edd7471d90
commit 2053d7f57b
4 changed files with 44 additions and 13 deletions

View File

@ -19,7 +19,6 @@ use zcash_primitives::{
use crate::{
address::RecipientAddress,
data_api::wallet::ANCHOR_OFFSET,
decrypt::DecryptedOutput,
proto::compact_formats::CompactBlock,
wallet::{AccountId, SpendableNote, WalletTx},
@ -68,6 +67,7 @@ pub trait WalletRead {
/// This will return `Ok(None)` if no block data is present in the database.
fn get_target_and_anchor_heights(
&self,
min_confirmations: u32,
) -> Result<Option<(BlockHeight, BlockHeight)>, Self::Error> {
self.block_height_extrema().map(|heights| {
heights.map(|(min_height, max_height)| {
@ -76,7 +76,7 @@ pub trait WalletRead {
// Select an anchor ANCHOR_OFFSET back from the target block,
// unless that would be before the earliest block we have.
let anchor_height = BlockHeight::from(cmp::max(
u32::from(target_height).saturating_sub(ANCHOR_OFFSET),
u32::from(target_height).saturating_sub(min_confirmations),
u32::from(min_height),
));

View File

@ -27,8 +27,6 @@ use zcash_primitives::{legacy::Script, transaction::components::TxOut};
#[cfg(feature = "transparent-inputs")]
use crate::keys::derive_transparent_address_from_secret_key;
pub const ANCHOR_OFFSET: u32 = 10;
/// Scans a [`Transaction`] for any information that can be decrypted by the accounts in
/// the wallet, and saves it to the wallet.
pub fn decrypt_and_store_transaction<N, E, P, D>(
@ -169,6 +167,7 @@ pub fn create_spend_to_address<E, N, P, D, R>(
amount: Amount,
memo: Option<MemoBytes>,
ovk_policy: OvkPolicy,
min_confirmations: u32,
) -> Result<R, E>
where
E: From<Error<N>>,
@ -187,7 +186,16 @@ where
}],
};
spend(wallet_db, params, prover, account, extsk, &req, ovk_policy)
spend(
wallet_db,
params,
prover,
account,
extsk,
&req,
ovk_policy,
min_confirmations,
)
}
pub fn spend<E, N, P, D, R>(
@ -198,6 +206,7 @@ pub fn spend<E, N, P, D, R>(
extsk: &ExtendedSpendingKey,
request: &TransactionRequest,
ovk_policy: OvkPolicy,
min_confirmations: u32,
) -> Result<R, E>
where
E: From<Error<N>>,
@ -221,7 +230,7 @@ where
// Target the next block, assuming we are up-to-date.
let (height, anchor_height) = wallet_db
.get_target_and_anchor_heights()
.get_target_and_anchor_heights(min_confirmations)
.and_then(|x| x.ok_or_else(|| Error::ScanRequired.into()))?;
let value = request
@ -337,7 +346,7 @@ pub fn shield_funds<E, N, P, D, R>(
sk: &secp256k1::SecretKey,
extsk: &ExtendedSpendingKey,
memo: &MemoBytes,
confirmations: u32,
min_confirmations: u32,
) -> Result<D::TxRef, E>
where
E: From<Error<N>>,
@ -346,7 +355,7 @@ where
D: WalletWrite<Error = E, TxRef = R>,
{
let (latest_scanned_height, latest_anchor) = wallet_db
.get_target_and_anchor_heights()
.get_target_and_anchor_heights(min_confirmations)
.and_then(|x| x.ok_or_else(|| Error::ScanRequired.into()))?;
// derive the corresponding t-address
@ -360,7 +369,7 @@ where
let ovk = exfvk.fvk.ovk;
// get UTXOs from DB
let utxos = wallet_db.get_unspent_transparent_utxos(&taddr, latest_anchor - confirmations)?;
let utxos = wallet_db.get_unspent_transparent_utxos(&taddr, latest_anchor)?;
let total_amount = utxos
.iter()
.map(|utxo| utxo.value)

View File

@ -1128,7 +1128,7 @@ mod tests {
assert_eq!(get_balance(&db_data, AccountId(0)).unwrap(), Amount::zero());
// We can't get an anchor height, as we have not scanned any blocks.
assert_eq!((&db_data).get_target_and_anchor_heights().unwrap(), None);
assert_eq!((&db_data).get_target_and_anchor_heights(10).unwrap(), None);
// An invalid account has zero balance
assert!(get_address(&db_data, AccountId(1)).is_err());

View File

@ -222,6 +222,7 @@ mod tests {
Amount::from_u64(1).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(e.to_string(), "Incorrect ExtendedSpendingKey for account 0"),
@ -237,6 +238,7 @@ mod tests {
Amount::from_u64(1).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(e.to_string(), "Incorrect ExtendedSpendingKey for account 1"),
@ -268,6 +270,7 @@ mod tests {
Amount::from_u64(1).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(e.to_string(), "Must scan blocks first"),
@ -310,6 +313,7 @@ mod tests {
Amount::from_u64(1).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(
@ -348,7 +352,10 @@ mod tests {
scan_cached_blocks(&tests::network(), &db_cache, &mut db_write, None).unwrap();
// Verified balance matches total balance
let (_, anchor_height) = (&db_data).get_target_and_anchor_heights().unwrap().unwrap();
let (_, anchor_height) = (&db_data)
.get_target_and_anchor_heights(10)
.unwrap()
.unwrap();
assert_eq!(get_balance(&db_data, AccountId(0)).unwrap(), value);
assert_eq!(
get_balance_at(&db_data, AccountId(0), anchor_height).unwrap(),
@ -366,7 +373,10 @@ mod tests {
scan_cached_blocks(&tests::network(), &db_cache, &mut db_write, None).unwrap();
// Verified balance does not include the second note
let (_, anchor_height2) = (&db_data).get_target_and_anchor_heights().unwrap().unwrap();
let (_, anchor_height2) = (&db_data)
.get_target_and_anchor_heights(10)
.unwrap()
.unwrap();
assert_eq!(
get_balance(&db_data, AccountId(0)).unwrap(),
(value + value).unwrap()
@ -389,6 +399,7 @@ mod tests {
Amount::from_u64(70000).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(
@ -421,6 +432,7 @@ mod tests {
Amount::from_u64(70000).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(
@ -446,6 +458,7 @@ mod tests {
Amount::from_u64(70000).unwrap(),
None,
OvkPolicy::Sender,
10,
)
.unwrap();
}
@ -492,6 +505,7 @@ mod tests {
Amount::from_u64(15000).unwrap(),
None,
OvkPolicy::Sender,
10,
)
.unwrap();
@ -506,6 +520,7 @@ mod tests {
Amount::from_u64(2000).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(
@ -538,6 +553,7 @@ mod tests {
Amount::from_u64(2000).unwrap(),
None,
OvkPolicy::Sender,
10,
) {
Ok(_) => panic!("Should have failed"),
Err(e) => assert_eq!(
@ -567,6 +583,7 @@ mod tests {
Amount::from_u64(2000).unwrap(),
None,
OvkPolicy::Sender,
10,
)
.unwrap();
}
@ -616,6 +633,7 @@ mod tests {
Amount::from_u64(15000).unwrap(),
None,
ovk_policy,
10,
)
.unwrap();
@ -707,7 +725,10 @@ mod tests {
scan_cached_blocks(&tests::network(), &db_cache, &mut db_write, None).unwrap();
// Verified balance matches total balance
let (_, anchor_height) = (&db_data).get_target_and_anchor_heights().unwrap().unwrap();
let (_, anchor_height) = (&db_data)
.get_target_and_anchor_heights(10)
.unwrap()
.unwrap();
assert_eq!(get_balance(&db_data, AccountId(0)).unwrap(), value);
assert_eq!(
get_balance_at(&db_data, AccountId(0), anchor_height).unwrap(),
@ -725,6 +746,7 @@ mod tests {
Amount::from_u64(50000).unwrap(),
None,
OvkPolicy::Sender,
10,
)
.unwrap();
}