Skip to content

Commit

Permalink
Merge branch 'mit-dci:trunk' into config_generator
Browse files Browse the repository at this point in the history
  • Loading branch information
ykaravas authored Sep 27, 2022
2 parents b8acdba + 46771a9 commit 70e54c1
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/uhs/sentinel/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ namespace cbdc::sentinel::rpc {
: m_logger(std::move(logger)),
m_client(std::move(endpoints)) {}

auto client::init() -> bool {
if(!m_client.init()) {
auto client::init(std::optional<bool> error_fatal) -> bool {
if(!m_client.init(error_fatal)) {
m_logger->error("Failed to initialize sentinel RPC client");
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion src/uhs/sentinel/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ namespace cbdc::sentinel::rpc {
auto operator=(client&&) -> client& = delete;

/// Initializes the client. Establishes a connection to the sentinel.
/// \param error_fatal treat connection errors as fatal. See
/// tcp_client::init for further explanation.
/// \return true if initialization succeeded.
auto init() -> bool;
/// \see \ref cbdc::rpc::tcp_client::init(std::optional<bool>)
auto init(std::optional<bool> error_fatal = std::nullopt) -> bool;

/// Result type from execute_transaction.
using execute_result_type
Expand Down
18 changes: 16 additions & 2 deletions src/uhs/twophase/sentinel_2pc/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ namespace cbdc::sentinel_2pc {
.size())]) {}

auto controller::init() -> bool {
if(m_opts.m_sentinel_endpoints.empty()) {
m_logger->error("No sentinel endpoints are defined.");
return false;
}

if(m_sentinel_id >= m_opts.m_sentinel_endpoints.size()) {
m_logger->error(
"The sentinel ID is too large for the number of sentinels.");
return false;
}

auto skey = m_opts.m_sentinel_private_keys.find(m_sentinel_id);
if(skey == m_opts.m_sentinel_private_keys.end()) {
if(m_opts.m_attestation_threshold > 0) {
Expand All @@ -49,13 +60,16 @@ namespace cbdc::sentinel_2pc {
auto client = std::make_unique<sentinel::rpc::client>(
std::vector<network::endpoint_t>{ep},
m_logger);
if(!client->init()) {
if(!client->init(false)) {
m_logger->warn("Failed to start sentinel client");
}
m_sentinel_clients.emplace_back(std::move(client));
}

m_dist = decltype(m_dist)(0, m_sentinel_clients.size() - 1);
constexpr size_t dist_lower_bound = 0;
const size_t dist_upper_bound
= m_sentinel_clients.empty() ? 0 : m_sentinel_clients.size() - 1;
m_dist = decltype(m_dist)(dist_lower_bound, dist_upper_bound);

auto rpc_server = std::make_unique<cbdc::rpc::tcp_server<
cbdc::rpc::async_server<cbdc::sentinel::request,
Expand Down
5 changes: 5 additions & 0 deletions src/util/common/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,11 @@ namespace cbdc::config {
return "Two-phase mode requires at least one configured "
"sentinel";
}
if(opts.m_sentinel_endpoints.size()
< opts.m_attestation_threshold) {
return "The number of required attestations is larger \n"
"than the number of sentinels that can provide them.";
}
if(opts.m_locking_shard_endpoints.empty()) {
return "Two-phase mode requires at least one configured shard";
}
Expand Down
11 changes: 6 additions & 5 deletions src/util/raft/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ namespace cbdc::raft {
: m_node_id(static_cast<uint32_t>(node_id)),
m_blocking(blocking),
m_port(raft_endpoints[m_node_id].second),
m_raft_logger(nuraft::cs_new<console_logger>(std::move(logger))),
m_raft_logger(nuraft::cs_new<console_logger>(logger)),
m_smgr(nuraft::cs_new<state_manager>(
static_cast<uint32_t>(m_node_id + 1),
node_type + "_raft_log_" + std::to_string(m_node_id),
node_type + "_raft_config_" + std::to_string(m_node_id) + ".dat",
node_type + "_raft_state_" + std::to_string(m_node_id) + ".dat",
std::move(raft_endpoints))),
m_sm(std::move(sm)) {
m_sm(std::move(sm)),
m_log(std::move(logger)) {
m_asio_opt.thread_pool_size_ = asio_thread_pool_size;
m_init_opts.raft_callback_ = std::move(raft_cb);
if(m_node_id != 0) {
Expand All @@ -51,16 +52,16 @@ namespace cbdc::raft {
m_init_opts);

if(!m_raft_instance) {
std::cerr << "Failed to initialize raft launcher" << std::endl;
m_log->error("Failed to initialize raft launcher");
return false;
}

m_raft_logger->info("Waiting for raft initialization");
m_log->info("Waiting for raft initialization");
static constexpr auto wait_time = std::chrono::milliseconds(100);
while(!m_raft_instance->is_initialized()) {
std::this_thread::sleep_for(wait_time);
}
m_raft_logger->info("Raft initialization complete");
m_log->info("Raft initialization complete");

return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/util/raft/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ namespace cbdc::raft {

nuraft::asio_service::options m_asio_opt;
nuraft::raft_server::init_options m_init_opts;

std::shared_ptr<logging::log> m_log;
};
}

Expand Down
25 changes: 21 additions & 4 deletions src/util/rpc/tcp_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,28 @@ namespace cbdc::rpc {

/// Initializes the client. Connects to the server endpoints and
/// starts the response handler thread.
/// \return false if there is only one endpoint and connecting failed.
/// Otherwise true.
[[nodiscard]] auto init() -> bool {
/// \param error_fatal treat connection errors as fatal.
/// If this is set to true, failure to connect
/// to any of the endpoints will result in failure
/// to start the client and return false from this
/// function.
/// If this is set to false, any
/// connection error will be silently ignored and
/// the handler thread will be started. The client
/// will continue to retry connecting in the
/// background.
/// If this is std::nullopt, connection
/// errors are only treated as fatal when there is a
/// single endpoint.
/// \return false if there is a fatal connection error, true if the
/// client is connected and ready and the response handler is started.
[[nodiscard]] auto init(std::optional<bool> error_fatal = std::nullopt)
-> bool {
if(!error_fatal) {
error_fatal = m_server_endpoints.size() <= 1;
}
if(!m_net.cluster_connect(m_server_endpoints,
m_server_endpoints.size() <= 1)) {
error_fatal.value())) {
return false;
}

Expand Down
45 changes: 45 additions & 0 deletions tests/unit/sentinel_2pc/controller_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ class sentinel_2pc_test : public ::testing::Test {
m_opts.m_coordinator_endpoints.resize(1);
m_opts.m_coordinator_endpoints[0].push_back(coordinator_ep);

// The locking shard endpoint defined below may not be used in tests,
// but it must be defined for the options struct to be valid. Without
// it, the check_options function couldn't be used to validate the
// other options used in this test.
static constexpr unsigned short m_locking_shard_port = 42001;
const auto locking_shard_endpoint
= std::make_pair(cbdc::network::localhost, m_locking_shard_port);
m_opts.m_locking_shard_endpoints.resize(1);
m_opts.m_locking_shard_endpoints[0].push_back(locking_shard_endpoint);

auto opt_chk_result = cbdc::config::check_options(m_opts);
ASSERT_FALSE(opt_chk_result.has_value());

m_dummy_coordinator_thread = m_dummy_coordinator_net->start_server(
coordinator_ep,
[&](cbdc::network::message_t&& pkt)
Expand Down Expand Up @@ -226,3 +239,35 @@ TEST_F(sentinel_2pc_test, bad_rpc_server_endpoint) {
// Check that the controller with the invalid endpoint fails to initialize.
ASSERT_FALSE(ctl->init());
}

TEST_F(sentinel_2pc_test, out_of_range_sentinel_id) {
// Test that controller initialization fails when the sentinel ID is
// too large for the number of sentinels. Here, since there's only
// 1 sentinel, the only allowable sentinel ID is 0. However, it's
// deliberately set to 1 to trigger failure.
constexpr uint32_t bad_sentinel_id = 1;

// Add private key for the bad sentinel ID to avoid triggering the error
// "No private key specified".
constexpr auto sentinel_private_key
= "0000000000000001000000000000000000000000000000000000000000000001";
m_opts.m_sentinel_private_keys[bad_sentinel_id]
= cbdc::hash_from_hex(sentinel_private_key);

auto ctl
= std::make_unique<cbdc::sentinel_2pc::controller>(bad_sentinel_id,
m_opts,
m_logger);
ASSERT_FALSE(ctl->init());
}

TEST_F(sentinel_2pc_test, no_sentinel_endpoints) {
m_opts.m_sentinel_endpoints.clear();
auto ctl = std::make_unique<cbdc::sentinel_2pc::controller>(0,
m_opts,
m_logger);

// Check that the controller fails to initialize if no sentinel endpoints
// are defined.
ASSERT_FALSE(ctl->init());
}
6 changes: 3 additions & 3 deletions tools/bench/atomizer-cli-watchtower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ auto main(int argc, char** argv) -> int {
static std::atomic_bool running = true;
uint64_t best_watchtower_height = 0;

std::ofstream latency_log("latency_samples_" + std::to_string(cli_id)
+ ".txt");
std::ofstream latency_log("tx_samples_" + std::to_string(cli_id) + ".txt");

assert(latency_log.good());

std::ofstream utxo_set_log("utxo_set_size_" + std::to_string(cli_id)
Expand Down Expand Up @@ -216,7 +216,7 @@ auto main(int argc, char** argv) -> int {
if(tx_it != txs.end()) {
const auto tx_delay
= now - tx_it->second.first;
latency_log << tx_delay << "\n";
latency_log << now << " " << tx_delay << "\n";
txs.erase(tx_it);
}
if(cfg.m_invalid_rate > 0.0
Expand Down

0 comments on commit 70e54c1

Please sign in to comment.