OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
state_manager.cpp
Go to the documentation of this file.
1// Copyright (c) 2021 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "state_manager.hpp"
7
8#include "log_store.hpp"
9
10#include <cstring>
11#include <filesystem>
12#include <fstream>
13#include <utility>
14
15namespace cbdc::raft {
17 int32_t srv_id,
18 std::string log_dir,
19 std::string config_file,
20 std::string state_file,
21 std::vector<network::endpoint_t> raft_endpoints)
22 : m_id(srv_id),
23 m_config_file(std::move(config_file)),
24 m_state_file(std::move(state_file)),
25 m_log_dir(std::move(log_dir)),
26 m_raft_endpoints(std::move(raft_endpoints)) {}
27
28 template<typename T>
29 void save_object(const T& obj, const std::string& filename) {
30 auto buf = obj.serialize();
31 std::vector<char> char_buf(buf->size());
32 std::memcpy(char_buf.data(), buf->data_begin(), char_buf.size());
33
34 const auto tmp_file = filename + ".tmp";
35 std::ofstream file(tmp_file, std::ios::binary | std::ios::trunc);
36 assert(file.good());
37
38 file.write(char_buf.data(),
39 static_cast<std::streamsize>(char_buf.size()));
40 file.flush();
41 file.close();
42
43 std::filesystem::rename(tmp_file, filename);
44 }
45
46 template<typename T>
47 auto load_object(const std::string& filename) -> nuraft::ptr<T> {
48 std::ifstream file(filename, std::ios::binary);
49 if(!file.good()) {
50 return nullptr;
51 }
52
53 auto file_sz = std::filesystem::file_size(filename);
54 std::vector<char> buf(file_sz);
55 if(!file.read(buf.data(), static_cast<std::streamsize>(file_sz))) {
56 return nullptr;
57 }
58
59 auto nuraft_buf = nuraft::buffer::alloc(file_sz);
60 std::memcpy(nuraft_buf->data_begin(), buf.data(), nuraft_buf->size());
61
62 auto obj = T::deserialize(*nuraft_buf);
63 return obj;
64 }
65
66 auto state_manager::load_config() -> nuraft::ptr<nuraft::cluster_config> {
67 auto config = load_object<nuraft::cluster_config>(m_config_file);
68 if(!config) {
69 auto cluster_config = nuraft::cs_new<nuraft::cluster_config>();
70 for(size_t i = 0; i < m_raft_endpoints.size(); i++) {
71 auto& ep = m_raft_endpoints[i];
72 auto ep_str = ep.first + ":" + std::to_string(ep.second);
73 auto srv_config
74 = nuraft::cs_new<nuraft::srv_config>(i + 1, ep_str);
75 if(i == 0) {
76 constexpr auto leader_priority = 100;
77 srv_config->set_priority(leader_priority);
78 }
79 cluster_config->get_servers().emplace_back(
80 std::move(srv_config));
81 }
82 return cluster_config;
83 }
84
85 return config;
86 }
87
88 void state_manager::save_config(const nuraft::cluster_config& config) {
89 save_object(config, m_config_file);
90 }
91
92 void state_manager::save_state(const nuraft::srv_state& state) {
93 save_object(state, m_state_file);
94 }
95
96 auto state_manager::read_state() -> nuraft::ptr<nuraft::srv_state> {
97 auto state = load_object<nuraft::srv_state>(m_state_file);
98 return state;
99 }
100
101 auto state_manager::load_log_store() -> nuraft::ptr<nuraft::log_store> {
102 auto log = nuraft::cs_new<log_store>();
103 if(!log->load(m_log_dir)) {
104 return nullptr;
105 }
106
107 return log;
108 }
109
110 auto state_manager::server_id() -> int32_t {
111 return m_id;
112 }
113
114 void state_manager::system_exit(int exit_code) {
115 std::exit(exit_code);
116 }
117}
state_manager(int32_t srv_id, std::string log_dir, std::string config_file, std::string state_file, std::vector< network::endpoint_t > raft_endpoints)
Constructor.
void save_state(const nuraft::srv_state &state) override
Serialize and write the given server state.
void save_config(const nuraft::cluster_config &config) override
Serialize and write the given cluster configuration.
auto read_state() -> nuraft::ptr< nuraft::srv_state > override
Read and deserialize the server state.
auto load_config() -> nuraft::ptr< nuraft::cluster_config > override
Read and deserialize the cluster configuration.
auto load_log_store() -> nuraft::ptr< nuraft::log_store > override
Load and return the log store.
void system_exit(int exit_code) override
Terminate the application with the given exit code.
auto server_id() -> int32_t override
Return the server ID.
auto load_object(const std::string &filename) -> nuraft::ptr< T >
void save_object(const T &obj, const std::string &filename)