Skip to content

Commit 8af835a

Browse files
committed
Merge #16796: wallet: Fix segfault in CreateWalletFromFile
fa73460 wallet: Fix segmentation fault in CreateWalletFromFile (MarcoFalke) fab3c34 test: Print both messages on failure in assert_raises_message (MarcoFalke) faa1353 wallet: Fix documentation around WalletParameterInteraction (MarcoFalke) Pull request description: Comes with a test to aid review. The test should fail without the fix to bitcoind The following `CreateWalletFromFile` issues are fixed: * `walletFile` refers to freed memory and will thus corrupt the debug.log and/or crash the node if read * `WalletParameterInteraction` was moved to `CreateWalletFromFile` and `WalletInit::ParameterInteraction` without updating the documentation ACKs for top commit: promag: ACK fa73460. darosior: ACK fa73460 meshcollider: LGTM, code-read ACK fa73460 Tree-SHA512: 2aceb63a3f25b90a840cfa08d37f5874aad4eb3df8c2ebf94e2ed18b55809b185e6920bdb345b988bff1fcea5e68a214fe06c361f7da2c01a3cc29e0cc421cb4
2 parents 5b4e688 + fa73460 commit 8af835a

File tree

8 files changed

+34
-5
lines changed

8 files changed

+34
-5
lines changed

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ bool AppInitParameterInteraction()
11061106
if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) {
11071107
return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", "")).translated);
11081108
}
1109-
// High fee check is done afterward in WalletParameterInteraction()
1109+
// High fee check is done afterward in CWallet::CreateWalletFromFile()
11101110
::minRelayTxFee = CFeeRate(n);
11111111
} else if (incrementalRelayFee > ::minRelayTxFee) {
11121112
// Allow only setting incrementalRelayFee to control both

src/wallet/load.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Chain;
1717

1818
//! Responsible for reading and validating the -wallet arguments and verifying the wallet database.
1919
//! This function will perform salvage on the wallet if requested, as long as only one wallet is
20-
//! being loaded (WalletParameterInteraction forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet).
20+
//! being loaded (WalletInit::ParameterInteraction() forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet).
2121
bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files);
2222

2323
//! Load wallet databases.

src/wallet/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4254,7 +4254,7 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
42544254

42554255
std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags)
42564256
{
4257-
const std::string& walletFile = WalletDataFilePath(location.GetPath()).string();
4257+
const std::string walletFile = WalletDataFilePath(location.GetPath()).string();
42584258

42594259
// needed to restore wallet transaction meta data after -zapwallettxes
42604260
std::vector<CWalletTx> vWtx;

test/functional/data/wallets/high_minversion/.walletlock

Whitespace-only changes.

test/functional/data/wallets/high_minversion/db.log

Whitespace-only changes.
Binary file not shown.

test/functional/test_framework/util.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ def assert_raises_message(exc, message, fun, *args, **kwds):
5656
raise AssertionError("Use assert_raises_rpc_error() to test RPC failures")
5757
except exc as e:
5858
if message is not None and message not in e.error['message']:
59-
raise AssertionError("Expected substring not found:" + e.error['message'])
59+
raise AssertionError(
60+
"Expected substring not found in error message:\nsubstring: '{}'\nerror message: '{}'.".format(
61+
message, e.error['message']))
6062
except Exception as e:
6163
raise AssertionError("Unexpected exception raised: " + type(e).__name__)
6264
else:
@@ -116,7 +118,9 @@ def try_rpc(code, message, fun, *args, **kwds):
116118
if (code is not None) and (code != e.error["code"]):
117119
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
118120
if (message is not None) and (message not in e.error['message']):
119-
raise AssertionError("Expected substring not found:" + e.error['message'])
121+
raise AssertionError(
122+
"Expected substring not found in error message:\nsubstring: '{}'\nerror message: '{}'.".format(
123+
message, e.error['message']))
120124
return True
121125
except Exception as e:
122126
raise AssertionError("Unexpected exception raised: " + type(e).__name__)

test/functional/wallet_multiwallet.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
assert_raises_rpc_error,
1818
)
1919

20+
FEATURE_LATEST = 169900
21+
2022

2123
class MultiWalletTest(BitcoinTestFramework):
2224
def set_test_params(self):
@@ -27,6 +29,13 @@ def set_test_params(self):
2729
def skip_test_if_missing_module(self):
2830
self.skip_if_no_wallet()
2931

32+
def add_options(self, parser):
33+
parser.add_argument(
34+
'--data_wallets_dir',
35+
default=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/wallets/'),
36+
help='Test data with wallet directories (default: %(default)s)',
37+
)
38+
3039
def run_test(self):
3140
node = self.nodes[0]
3241

@@ -323,6 +332,22 @@ def wallet_file(name):
323332
self.nodes[0].unloadwallet(wallet)
324333
self.nodes[1].loadwallet(wallet)
325334

335+
# Fail to load if wallet is downgraded
336+
shutil.copytree(os.path.join(self.options.data_wallets_dir, 'high_minversion'), wallet_dir('high_minversion'))
337+
self.restart_node(0, extra_args=['-upgradewallet={}'.format(FEATURE_LATEST)])
338+
assert {'name': 'high_minversion'} in self.nodes[0].listwalletdir()['wallets']
339+
self.log.info("Fail -upgradewallet that results in downgrade")
340+
assert_raises_rpc_error(
341+
-4,
342+
"Wallet loading failed.",
343+
lambda: self.nodes[0].loadwallet(filename='high_minversion'),
344+
)
345+
self.stop_node(
346+
i=0,
347+
expected_stderr='Error: Error loading {}: Wallet requires newer version of Bitcoin Core'.format(
348+
wallet_dir('high_minversion', 'wallet.dat')),
349+
)
350+
326351

327352
if __name__ == '__main__':
328353
MultiWalletTest().main()

0 commit comments

Comments
 (0)