merge bitcoin#16796: Fix segfault in CreateWalletFromFile

This commit is contained in:
Kittywhiskers Van Gogh 2021-12-12 18:57:02 +05:30
parent d7281c82ef
commit fc6e35060d
8 changed files with 35 additions and 6 deletions

View File

@ -1469,7 +1469,7 @@ bool AppInitParameterInteraction()
if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) {
return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", "")));
} }
// High fee check is done afterward in WalletParameterInteraction() // High fee check is done afterward in CWallet::CreateWalletFromFile()
::minRelayTxFee = CFeeRate(n); ::minRelayTxFee = CFeeRate(n);
} else if (incrementalRelayFee > ::minRelayTxFee) { } else if (incrementalRelayFee > ::minRelayTxFee) {
// Allow only setting incrementalRelayFee to control both // Allow only setting incrementalRelayFee to control both

View File

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

View File

@ -4885,7 +4885,7 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags) std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags)
{ {
const std::string& walletFile = WalletDataFilePath(location.GetPath()).string(); const std::string walletFile = WalletDataFilePath(location.GetPath()).string();
// needed to restore wallet transaction meta data after -zapwallettxes // needed to restore wallet transaction meta data after -zapwallettxes
std::vector<CWalletTx> vWtx; std::vector<CWalletTx> vWtx;

View File

@ -68,7 +68,9 @@ def assert_raises_message(exc, message, fun, *args, **kwds):
raise AssertionError("Use assert_raises_rpc_error() to test RPC failures") raise AssertionError("Use assert_raises_rpc_error() to test RPC failures")
except exc as e: except exc as e:
if message is not None and message not in e.error['message']: if message is not None and message not in e.error['message']:
raise AssertionError("Expected substring not found:" + e.error['message']) raise AssertionError(
"Expected substring not found in error message:\nsubstring: '{}'\nerror message: '{}'.".format(
message, e.error['message']))
except Exception as e: except Exception as e:
raise AssertionError("Unexpected exception raised: " + type(e).__name__) raise AssertionError("Unexpected exception raised: " + type(e).__name__)
else: else:
@ -128,7 +130,9 @@ def try_rpc(code, message, fun, *args, **kwds):
if (code is not None) and (code != e.error["code"]): if (code is not None) and (code != e.error["code"]):
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"]) raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
if (message is not None) and (message not in e.error['message']): if (message is not None) and (message not in e.error['message']):
raise AssertionError("Expected substring not found:" + e.error['message']) raise AssertionError(
"Expected substring not found in error message:\nsubstring: '{}'\nerror message: '{}'.".format(
message, e.error['message']))
return True return True
except Exception as e: except Exception as e:
raise AssertionError("Unexpected exception raised: " + type(e).__name__) raise AssertionError("Unexpected exception raised: " + type(e).__name__)

View File

@ -17,6 +17,8 @@ from test_framework.util import (
assert_raises_rpc_error, assert_raises_rpc_error,
) )
FEATURE_LATEST = 120200
class MultiWalletTest(BitcoinTestFramework): class MultiWalletTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
@ -27,6 +29,13 @@ class MultiWalletTest(BitcoinTestFramework):
def skip_test_if_missing_module(self): def skip_test_if_missing_module(self):
self.skip_if_no_wallet() self.skip_if_no_wallet()
def add_options(self, parser):
parser.add_argument(
'--data_wallets_dir',
default=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/wallets/'),
help='Test data with wallet directories (default: %(default)s)',
)
def run_test(self): def run_test(self):
node = self.nodes[0] node = self.nodes[0]
@ -328,6 +337,22 @@ class MultiWalletTest(BitcoinTestFramework):
self.nodes[0].unloadwallet(wallet) self.nodes[0].unloadwallet(wallet)
self.nodes[1].loadwallet(wallet) self.nodes[1].loadwallet(wallet)
# Fail to load if wallet is downgraded
shutil.copytree(os.path.join(self.options.data_wallets_dir, 'high_minversion'), wallet_dir('high_minversion'))
self.restart_node(0, extra_args=['-upgradewallet={}'.format(FEATURE_LATEST)])
assert {'name': 'high_minversion'} in self.nodes[0].listwalletdir()['wallets']
self.log.info("Fail -upgradewallet that results in downgrade")
assert_raises_rpc_error(
-4,
"Wallet loading failed.",
lambda: self.nodes[0].loadwallet(filename='high_minversion'),
)
self.stop_node(
i=0,
expected_stderr='Error: Error loading {}: Wallet requires newer version of Dash Core'.format(
wallet_dir('high_minversion', 'wallet.dat')),
)
if __name__ == '__main__': if __name__ == '__main__':
MultiWalletTest().main() MultiWalletTest().main()