@@ -298,18 +298,19 @@ fn create_wallet(chain_config: Arc<ChainConfig>) -> DefaultWallet {
298298}
299299
300300#[ track_caller]
301- fn create_block < B , P > (
301+ fn create_block_with_address_reward < B , P > (
302302 chain_config : & Arc < ChainConfig > ,
303303 wallet : & mut Wallet < B , P > ,
304304 transactions : Vec < SignedTransaction > ,
305305 reward : Amount ,
306306 block_height : u64 ,
307+ address : Destination ,
307308) -> ( Address < Destination > , Block )
308309where
309310 B : storage:: Backend + ' static ,
310311 P : SignerProvider ,
311312{
312- let address = wallet . get_new_address ( DEFAULT_ACCOUNT_INDEX ) . unwrap ( ) . 1 ;
313+ let address = Address :: new ( chain_config , address ) . unwrap ( ) ;
313314
314315 let block1 = Block :: new (
315316 transactions,
@@ -327,6 +328,29 @@ where
327328 ( address, block1)
328329}
329330
331+ #[ track_caller]
332+ fn create_block < B , P > (
333+ chain_config : & Arc < ChainConfig > ,
334+ wallet : & mut Wallet < B , P > ,
335+ transactions : Vec < SignedTransaction > ,
336+ reward : Amount ,
337+ block_height : u64 ,
338+ ) -> ( Address < Destination > , Block )
339+ where
340+ B : storage:: Backend + ' static ,
341+ P : SignerProvider ,
342+ {
343+ let address = wallet. get_new_address ( DEFAULT_ACCOUNT_INDEX ) . unwrap ( ) . 1 ;
344+ create_block_with_address_reward (
345+ chain_config,
346+ wallet,
347+ transactions,
348+ reward,
349+ block_height,
350+ address. into_object ( ) ,
351+ )
352+ }
353+
330354#[ track_caller]
331355fn test_balance_from_genesis (
332356 chain_type : ChainType ,
@@ -1251,6 +1275,112 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) {
12511275 . unwrap ( ) ;
12521276 }
12531277}
1278+
1279+ #[ rstest]
1280+ #[ trace]
1281+ #[ case( Seed :: from_entropy( ) ) ]
1282+ fn locked_wallet_standalone_keys ( #[ case] seed : Seed ) {
1283+ let mut rng = make_seedable_rng ( seed) ;
1284+ let chain_config = Arc :: new ( create_mainnet ( ) ) ;
1285+
1286+ let mut wallet = create_wallet ( chain_config. clone ( ) ) ;
1287+
1288+ let coin_balance = get_coin_balance ( & wallet) ;
1289+ assert_eq ! ( coin_balance, Amount :: ZERO ) ;
1290+
1291+ let ( standalone_sk, standalone_pk) =
1292+ PrivateKey :: new_from_rng ( & mut rng, KeyKind :: Secp256k1Schnorr ) ;
1293+ wallet
1294+ . add_standalone_private_key ( DEFAULT_ACCOUNT_INDEX , standalone_sk, None )
1295+ . unwrap ( ) ;
1296+
1297+ // Generate a new block which sends reward to the wallet
1298+ let block1_amount = Amount :: from_atoms ( rng. gen_range ( NETWORK_FEE + 1 ..NETWORK_FEE + 10000 ) ) ;
1299+ let _ = create_block_with_address_reward (
1300+ & chain_config,
1301+ & mut wallet,
1302+ vec ! [ ] ,
1303+ block1_amount,
1304+ 0 ,
1305+ Destination :: PublicKey ( standalone_pk) ,
1306+ ) ;
1307+
1308+ let password = Some ( gen_random_password ( & mut rng) ) ;
1309+ wallet. encrypt_wallet ( & password) . unwrap ( ) ;
1310+ wallet. lock_wallet ( ) . unwrap ( ) ;
1311+
1312+ let coin_balance = get_coin_balance ( & wallet) ;
1313+ assert_eq ! ( coin_balance, block1_amount) ;
1314+
1315+ let new_output = TxOutput :: Transfer (
1316+ OutputValue :: Coin ( Amount :: from_atoms (
1317+ rng. gen_range ( 1 ..=block1_amount. into_atoms ( ) - NETWORK_FEE ) ,
1318+ ) ) ,
1319+ Destination :: AnyoneCanSpend ,
1320+ ) ;
1321+
1322+ assert_eq ! (
1323+ wallet. create_transaction_to_addresses(
1324+ DEFAULT_ACCOUNT_INDEX ,
1325+ [ new_output. clone( ) ] ,
1326+ SelectedInputs :: Utxos ( vec![ ] ) ,
1327+ BTreeMap :: new( ) ,
1328+ FeeRate :: from_amount_per_kb( Amount :: ZERO ) ,
1329+ FeeRate :: from_amount_per_kb( Amount :: ZERO ) ,
1330+ TxAdditionalInfo :: new( ) ,
1331+ ) ,
1332+ Err ( WalletError :: DatabaseError (
1333+ wallet_storage:: Error :: WalletLocked
1334+ ) )
1335+ ) ;
1336+
1337+ // success after unlock
1338+ wallet. unlock_wallet ( & password. unwrap ( ) ) . unwrap ( ) ;
1339+ if rng. gen :: < bool > ( ) {
1340+ wallet
1341+ . create_transaction_to_addresses (
1342+ DEFAULT_ACCOUNT_INDEX ,
1343+ [ new_output] ,
1344+ SelectedInputs :: Utxos ( vec ! [ ] ) ,
1345+ BTreeMap :: new ( ) ,
1346+ FeeRate :: from_amount_per_kb ( Amount :: ZERO ) ,
1347+ FeeRate :: from_amount_per_kb ( Amount :: ZERO ) ,
1348+ TxAdditionalInfo :: new ( ) ,
1349+ )
1350+ . unwrap ( ) ;
1351+ } else {
1352+ // check if we remove the password it should fail to lock
1353+ wallet. encrypt_wallet ( & None ) . unwrap ( ) ;
1354+
1355+ let err = wallet. lock_wallet ( ) . unwrap_err ( ) ;
1356+ assert_eq ! (
1357+ err,
1358+ WalletError :: DatabaseError ( wallet_storage:: Error :: WalletLockedWithoutAPassword )
1359+ ) ;
1360+
1361+ // check that the kdf challenge has been deleted
1362+ assert ! ( wallet
1363+ . db
1364+ . transaction_ro( )
1365+ . unwrap( )
1366+ . get_encryption_key_kdf_challenge( )
1367+ . unwrap( )
1368+ . is_none( ) ) ;
1369+
1370+ wallet
1371+ . create_transaction_to_addresses (
1372+ DEFAULT_ACCOUNT_INDEX ,
1373+ [ new_output] ,
1374+ SelectedInputs :: Utxos ( vec ! [ ] ) ,
1375+ BTreeMap :: new ( ) ,
1376+ FeeRate :: from_amount_per_kb ( Amount :: ZERO ) ,
1377+ FeeRate :: from_amount_per_kb ( Amount :: ZERO ) ,
1378+ TxAdditionalInfo :: new ( ) ,
1379+ )
1380+ . unwrap ( ) ;
1381+ }
1382+ }
1383+
12541384#[ rstest]
12551385#[ trace]
12561386#[ case( Seed :: from_entropy( ) ) ]
@@ -5363,7 +5493,7 @@ fn test_add_standalone_private_key(#[case] seed: Seed) {
53635493
53645494 // Check amount is still zero
53655495 let coin_balance = get_coin_balance ( & wallet) ;
5366- assert_eq ! ( coin_balance, Amount :: ZERO ) ;
5496+ assert_eq ! ( coin_balance, block1_amount ) ;
53675497
53685498 // but the transaction has been added to the wallet
53695499 let tx_data = wallet
0 commit comments