aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/chain.h11
-rw-r--r--src/node/interfaces.cpp26
-rw-r--r--src/wallet/load.cpp2
-rw-r--r--src/wallet/test/wallet_tests.cpp15
4 files changed, 30 insertions, 24 deletions
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index be596b1765..7bc2d11b60 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -356,15 +356,22 @@ public:
virtual common::SettingsValue getRwSetting(const std::string& name) = 0;
//! Updates a setting in <datadir>/settings.json.
+ //! Null can be passed to erase the setting. There is intentionally no
+ //! support for writing null values to settings.json.
//! Depending on the action returned by the update function, this will either
//! update the setting in memory or write the updated settings to disk.
virtual bool updateRwSetting(const std::string& name, const SettingsUpdate& update_function) = 0;
//! Replace a setting in <datadir>/settings.json with a new value.
- virtual bool overwriteRwSetting(const std::string& name, common::SettingsValue& value, bool write = true) = 0;
+ //! Null can be passed to erase the setting.
+ //! This method provides a simpler alternative to updateRwSetting when
+ //! atomically reading and updating the setting is not required.
+ virtual bool overwriteRwSetting(const std::string& name, common::SettingsValue value, SettingsAction action = SettingsAction::WRITE) = 0;
//! Delete a given setting in <datadir>/settings.json.
- virtual bool deleteRwSettings(const std::string& name, bool write = true) = 0;
+ //! This method provides a simpler alternative to overwriteRwSetting when
+ //! erasing a setting, for ease of use and readability.
+ virtual bool deleteRwSettings(const std::string& name, SettingsAction action = SettingsAction::WRITE) = 0;
//! Synchronously send transactionAddedToMempool notifications about all
//! current mempool transactions to the specified handler and return after
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 510541dfda..0e418c58bb 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -820,29 +820,29 @@ public:
{
std::optional<interfaces::SettingsAction> action;
args().LockSettings([&](common::Settings& settings) {
- auto* ptr_value = common::FindKey(settings.rw_settings, name);
- // Create value if it doesn't exist
- auto& value = ptr_value ? *ptr_value : settings.rw_settings[name];
- action = update_settings_func(value);
+ if (auto* value = common::FindKey(settings.rw_settings, name)) {
+ action = update_settings_func(*value);
+ if (value->isNull()) settings.rw_settings.erase(name);
+ } else {
+ UniValue new_value;
+ action = update_settings_func(new_value);
+ if (!new_value.isNull()) settings.rw_settings[name] = std::move(new_value);
+ }
});
if (!action) return false;
// Now dump value to disk if requested
- return *action == interfaces::SettingsAction::SKIP_WRITE || args().WriteSettingsFile();
+ return *action != interfaces::SettingsAction::WRITE || args().WriteSettingsFile();
}
- bool overwriteRwSetting(const std::string& name, common::SettingsValue& value, bool write) override
+ bool overwriteRwSetting(const std::string& name, common::SettingsValue value, interfaces::SettingsAction action) override
{
- if (value.isNull()) return deleteRwSettings(name, write);
return updateRwSetting(name, [&](common::SettingsValue& settings) {
settings = std::move(value);
- return write ? interfaces::SettingsAction::WRITE : interfaces::SettingsAction::SKIP_WRITE;
+ return action;
});
}
- bool deleteRwSettings(const std::string& name, bool write) override
+ bool deleteRwSettings(const std::string& name, interfaces::SettingsAction action) override
{
- args().LockSettings([&](common::Settings& settings) {
- settings.rw_settings.erase(name);
- });
- return !write || args().WriteSettingsFile();
+ return overwriteRwSetting(name, {}, action);
}
void requestMempoolTransactions(Notifications& notifications) override
{
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 81f5e30082..2b5c021cda 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -69,7 +69,7 @@ bool VerifyWallets(WalletContext& context)
// Pass write=false because no need to write file and probably
// better not to. If unnamed wallet needs to be added next startup
// and the setting is empty, this code will just run again.
- chain.overwriteRwSetting("wallet", wallets, /*write=*/false);
+ chain.overwriteRwSetting("wallet", std::move(wallets), interfaces::SettingsAction::SKIP_WRITE);
}
}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 5a520cbfe9..b5de4b4b3d 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -334,12 +334,11 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
// concurrently, ensuring no race conditions occur during either process.
BOOST_FIXTURE_TEST_CASE(write_wallet_settings_concurrently, TestingSetup)
{
- WalletContext context;
- context.chain = m_node.chain.get();
+ auto chain = m_node.chain.get();
const auto NUM_WALLETS{5};
// Since we're counting the number of wallets, ensure we start without any.
- BOOST_REQUIRE(context.chain->getRwSetting("wallet").isNull());
+ BOOST_REQUIRE(chain->getRwSetting("wallet").isNull());
const auto& check_concurrent_wallet = [&](const auto& settings_function, int num_expected_wallets) {
std::vector<std::thread> threads;
@@ -347,19 +346,19 @@ BOOST_FIXTURE_TEST_CASE(write_wallet_settings_concurrently, TestingSetup)
for (auto i{0}; i < NUM_WALLETS; ++i) threads.emplace_back(settings_function, i);
for (auto& t : threads) t.join();
- auto wallets = context.chain->getRwSetting("wallet");
+ auto wallets = chain->getRwSetting("wallet");
BOOST_CHECK_EQUAL(wallets.getValues().size(), num_expected_wallets);
};
// Add NUM_WALLETS wallets concurrently, ensure we end up with NUM_WALLETS stored.
- check_concurrent_wallet([&context](int i) {
- Assert(AddWalletSetting(*context.chain, strprintf("wallet_%d", i)));
+ check_concurrent_wallet([&chain](int i) {
+ Assert(AddWalletSetting(*chain, strprintf("wallet_%d", i)));
},
/*num_expected_wallets=*/NUM_WALLETS);
// Remove NUM_WALLETS wallets concurrently, ensure we end up with 0 wallets.
- check_concurrent_wallet([&context](int i) {
- Assert(RemoveWalletSetting(*context.chain, strprintf("wallet_%d", i)));
+ check_concurrent_wallet([&chain](int i) {
+ Assert(RemoveWalletSetting(*chain, strprintf("wallet_%d", i)));
},
/*num_expected_wallets=*/0);
}