@@ -1248,13 +1248,21 @@ pub(crate) fn queue_transparent_spend_detection<P: consensus::Parameters>(
1248
1248
1249
1249
#[ cfg( test) ]
1250
1250
mod tests {
1251
+ use std:: collections:: BTreeMap ;
1252
+
1251
1253
use secrecy:: Secret ;
1252
1254
use transparent:: keys:: NonHardenedChildIndex ;
1253
1255
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
+ } ,
1255
1261
wallet:: TransparentAddressMetadata ,
1256
1262
} ;
1263
+ use zcash_keys:: address:: Address ;
1257
1264
use zcash_primitives:: block:: BlockHash ;
1265
+ use zcash_protocol:: value:: Zatoshis ;
1258
1266
1259
1267
use crate :: {
1260
1268
error:: SqliteClientError ,
@@ -1290,6 +1298,71 @@ mod tests {
1290
1298
) ;
1291
1299
}
1292
1300
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
+
1293
1366
#[ test]
1294
1367
fn ephemeral_address_management ( ) {
1295
1368
let mut st = TestBuilder :: new ( )
0 commit comments