Skip to content

Commit 3ac0396

Browse files
committed
zcash_client_sqlite: Add a test for external transparent address gap limit handling.
1 parent d316591 commit 3ac0396

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

zcash_client_sqlite/src/wallet/transparent.rs

+74-1
Original file line numberDiff line numberDiff line change
@@ -1248,13 +1248,21 @@ pub(crate) fn queue_transparent_spend_detection<P: consensus::Parameters>(
12481248

12491249
#[cfg(test)]
12501250
mod tests {
1251+
use std::collections::BTreeMap;
1252+
12511253
use secrecy::Secret;
12521254
use transparent::keys::NonHardenedChildIndex;
12531255
use zcash_client_backend::{
1254-
data_api::{testing::TestBuilder, Account as _, WalletWrite},
1256+
data_api::{
1257+
testing::{AddressType, TestBuilder},
1258+
wallet::decrypt_and_store_transaction,
1259+
Account as _, WalletRead, WalletWrite,
1260+
},
12551261
wallet::TransparentAddressMetadata,
12561262
};
1263+
use zcash_keys::address::Address;
12571264
use zcash_primitives::block::BlockHash;
1265+
use zcash_protocol::value::Zatoshis;
12581266

12591267
use crate::{
12601268
error::SqliteClientError,
@@ -1290,6 +1298,71 @@ mod tests {
12901298
);
12911299
}
12921300

1301+
#[test]
1302+
fn gap_limits() {
1303+
let mut st = TestBuilder::new()
1304+
.with_data_store_factory(TestDbFactory::default())
1305+
.with_block_cache(BlockCache::new())
1306+
.with_account_from_sapling_activation(BlockHash([0; 32]))
1307+
.build();
1308+
1309+
let test_account = st.test_account().cloned().unwrap();
1310+
let account_uuid = test_account.account().id();
1311+
let ufvk = test_account.account().ufvk().unwrap().clone();
1312+
1313+
let external_taddrs = st
1314+
.wallet()
1315+
.get_transparent_receivers(account_uuid, false, false)
1316+
.unwrap();
1317+
assert_eq!(external_taddrs.len(), 20); //20 external
1318+
let external_taddrs_sorted = external_taddrs
1319+
.into_iter()
1320+
.filter_map(|(addr, meta)| meta.map(|m| (m.address_index(), addr)))
1321+
.collect::<BTreeMap<_, _>>();
1322+
1323+
let all_taddrs = st
1324+
.wallet()
1325+
.get_transparent_receivers(account_uuid, true, true)
1326+
.unwrap();
1327+
assert_eq!(all_taddrs.len(), 30); //20 external, 5 internal, 5 ephemeral
1328+
1329+
// Add some funds to the wallet
1330+
let (h0, _, _) = st.generate_next_block(
1331+
&ufvk.orchard().unwrap(),
1332+
AddressType::DefaultExternal,
1333+
Zatoshis::const_from_u64(1000000),
1334+
);
1335+
st.scan_cached_blocks(h0, 1);
1336+
1337+
let to = Address::from(
1338+
*external_taddrs_sorted
1339+
.get(&NonHardenedChildIndex::from_index(9).unwrap())
1340+
.expect("An address exists at index 9."),
1341+
)
1342+
.to_zcash_address(st.network());
1343+
1344+
// Create a transaction & scan the block. Since the txid corresponds to one our wallet
1345+
// generated, this should cause the gap limit to be bumped (generating addresses with index
1346+
// 20..30
1347+
let txids = st
1348+
.create_standard_transaction(&test_account, to, Zatoshis::const_from_u64(20000))
1349+
.unwrap();
1350+
let (h1, _) = st.generate_next_block_including(txids.head);
1351+
st.scan_cached_blocks(h1, 1);
1352+
1353+
// use `decrypt_and_store_transaction` to ensure that the wallet sees the transaction as
1354+
// mined (since transparent handling doesn't get this from `scan_cached_blocks`)
1355+
let tx = st.wallet().get_transaction(txids.head).unwrap().unwrap();
1356+
decrypt_and_store_transaction(&st.network().clone(), st.wallet_mut(), &tx, Some(h1))
1357+
.unwrap();
1358+
1359+
let external_taddrs = st
1360+
.wallet()
1361+
.get_transparent_receivers(account_uuid, false, false)
1362+
.unwrap();
1363+
assert_eq!(external_taddrs.len(), 30);
1364+
}
1365+
12931366
#[test]
12941367
fn ephemeral_address_management() {
12951368
let mut st = TestBuilder::new()

0 commit comments

Comments
 (0)