From 367bb7a80cc71130995672c853d4a6e0134721d6 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 28 Feb 2024 13:00:00 +0300 Subject: [PATCH 1/2] wallet: Avoid updating `ReserveDestination::nIndex` when `GetReservedDestination` fails --- src/wallet/wallet.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 26c5256f6fb..3ac09430d83 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2607,8 +2607,10 @@ util::Result ReserveDestination::GetReservedDestination(bool int if (nIndex == -1) { CKeyPool keypool; - auto op_address = m_spk_man->GetReservedDestination(type, internal, nIndex, keypool); + int64_t index; + auto op_address = m_spk_man->GetReservedDestination(type, internal, index, keypool); if (!op_address) return op_address; + nIndex = index; address = *op_address; fInternal = keypool.fInternal; } From e073f1dfda7a2a2cb2be9fe2a1d576f122596021 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 28 Feb 2024 13:04:48 +0300 Subject: [PATCH 2/2] test: make sure keypool sizes do not change on `getrawchangeaddress`/`getnewaddress` failures --- test/functional/wallet_keypool.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py index d2341fb12e0..6ed8572347d 100755 --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -103,11 +103,18 @@ class KeyPoolTest(BitcoinTestFramework): nodes[0].getrawchangeaddress() nodes[0].getrawchangeaddress() nodes[0].getrawchangeaddress() - addr = set() + # remember keypool sizes + wi = nodes[0].getwalletinfo() + kp_size_before = [wi['keypoolsize_hd_internal'], wi['keypoolsize']] # the next one should fail assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getrawchangeaddress) + # check that keypool sizes did not change + wi = nodes[0].getwalletinfo() + kp_size_after = [wi['keypoolsize_hd_internal'], wi['keypoolsize']] + assert_equal(kp_size_before, kp_size_after) # drain the external keys + addr = set() addr.add(nodes[0].getnewaddress(address_type="bech32")) addr.add(nodes[0].getnewaddress(address_type="bech32")) addr.add(nodes[0].getnewaddress(address_type="bech32")) @@ -115,8 +122,15 @@ class KeyPoolTest(BitcoinTestFramework): addr.add(nodes[0].getnewaddress(address_type="bech32")) addr.add(nodes[0].getnewaddress(address_type="bech32")) assert len(addr) == 6 + # remember keypool sizes + wi = nodes[0].getwalletinfo() + kp_size_before = [wi['keypoolsize_hd_internal'], wi['keypoolsize']] # the next one should fail assert_raises_rpc_error(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress) + # check that keypool sizes did not change + wi = nodes[0].getwalletinfo() + kp_size_after = [wi['keypoolsize_hd_internal'], wi['keypoolsize']] + assert_equal(kp_size_before, kp_size_after) # refill keypool with three new addresses nodes[0].walletpassphrase('test', 1)