From c8918f0c02a800d32bee8f5f633575e7fde7a8af Mon Sep 17 00:00:00 2001 From: EmelyanenkoK Date: Wed, 27 Dec 2023 15:50:09 +0300 Subject: [PATCH] Write config.json using temp file (#839) Co-authored-by: SpyCheese --- dht-server/dht-server.cpp | 17 +++++++++++++---- dht-server/dht-server.hpp | 3 +++ validator-engine/validator-engine.cpp | 17 +++++++++++++---- validator-engine/validator-engine.hpp | 5 ++++- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/dht-server/dht-server.cpp b/dht-server/dht-server.cpp index f729105f..37a158eb 100644 --- a/dht-server/dht-server.cpp +++ b/dht-server/dht-server.cpp @@ -572,6 +572,12 @@ void DhtServer::load_config(td::Promise promise) { config_file_ = db_root_ + "/config.json"; } auto conf_data_R = td::read_file(config_file_); + if (conf_data_R.is_error()) { + conf_data_R = td::read_file(temp_config_file()); + if (conf_data_R.is_ok()) { + td::rename(temp_config_file(), config_file_).ensure(); + } + } if (conf_data_R.is_error()) { auto P = td::PromiseCreator::lambda( [name = local_config_, new_name = config_file_, promise = std::move(promise)](td::Result R) { @@ -620,12 +626,15 @@ void DhtServer::load_config(td::Promise promise) { void DhtServer::write_config(td::Promise promise) { auto s = td::json_encode(td::ToJson(*config_.tl().get()), true); - auto S = td::write_file(config_file_, s); - if (S.is_ok()) { - promise.set_value(td::Unit()); - } else { + auto S = td::write_file(temp_config_file(), s); + if (S.is_error()) { + td::unlink(temp_config_file()).ignore(); promise.set_error(std::move(S)); + return; } + td::unlink(config_file_).ignore(); + TRY_STATUS_PROMISE(promise, td::rename(temp_config_file(), config_file_)); + promise.set_value(td::Unit()); } td::Promise DhtServer::get_key_promise(td::MultiPromise::InitGuard &ig) { diff --git a/dht-server/dht-server.hpp b/dht-server/dht-server.hpp index bf24d621..5b81875b 100644 --- a/dht-server/dht-server.hpp +++ b/dht-server/dht-server.hpp @@ -109,6 +109,9 @@ class DhtServer : public td::actor::Actor { std::string local_config_ = ""; std::string global_config_ = "ton-global.config"; std::string config_file_; + std::string temp_config_file() const { + return config_file_ + ".tmp"; + } std::string db_root_ = "/var/ton-work/db/"; diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp index 1d9223f2..e488504f 100644 --- a/validator-engine/validator-engine.cpp +++ b/validator-engine/validator-engine.cpp @@ -1595,6 +1595,12 @@ void ValidatorEngine::load_config(td::Promise promise) { config_file_ = db_root_ + "/config.json"; } auto conf_data_R = td::read_file(config_file_); + if (conf_data_R.is_error()) { + conf_data_R = td::read_file(temp_config_file()); + if (conf_data_R.is_ok()) { + td::rename(temp_config_file(), config_file_).ensure(); + } + } if (conf_data_R.is_error()) { auto P = td::PromiseCreator::lambda( [name = local_config_, new_name = config_file_, promise = std::move(promise)](td::Result R) { @@ -1643,12 +1649,15 @@ void ValidatorEngine::load_config(td::Promise promise) { void ValidatorEngine::write_config(td::Promise promise) { auto s = td::json_encode(td::ToJson(*config_.tl().get()), true); - auto S = td::write_file(config_file_, s); - if (S.is_ok()) { - promise.set_value(td::Unit()); - } else { + auto S = td::write_file(temp_config_file(), s); + if (S.is_error()) { + td::unlink(temp_config_file()).ignore(); promise.set_error(std::move(S)); + return; } + td::unlink(config_file_).ignore(); + TRY_STATUS_PROMISE(promise, td::rename(temp_config_file(), config_file_)); + promise.set_value(td::Unit()); } td::Promise ValidatorEngine::get_key_promise(td::MultiPromise::InitGuard &ig) { diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp index ebcd60c6..e59bb418 100644 --- a/validator-engine/validator-engine.hpp +++ b/validator-engine/validator-engine.hpp @@ -1,4 +1,4 @@ -/* +/* This file is part of TON Blockchain source code. TON Blockchain is free software; you can redistribute it and/or @@ -152,6 +152,9 @@ class ValidatorEngine : public td::actor::Actor { std::string local_config_ = ""; std::string global_config_ = "ton-global.config"; std::string config_file_; + std::string temp_config_file() const { + return config_file_ + ".tmp"; + } std::string fift_dir_ = "";