From 45492f7c7fc913d6e73496ee39cbd2869cd4e2d3 Mon Sep 17 00:00:00 2001 From: Ravin Perera <33562092+ravinsp@users.noreply.github.com> Date: Wed, 19 May 2021 16:59:01 +0530 Subject: [PATCH] Added stage slice config to control stage time allocation. (#310) --- examples/c_contract/hotpocket_contract.h | 26 ++++++++--- examples/nodejs_contract/hp-contract-lib.js | 6 ++- src/conf.cpp | 35 ++++++++++----- src/conf.hpp | 31 +++++++------ src/consensus.cpp | 40 +++++++++-------- src/consensus.hpp | 2 +- src/msg/fbuf/p2pmsg.fbs | 4 +- src/msg/fbuf/p2pmsg_conversion.cpp | 12 +++--- src/msg/fbuf/p2pmsg_generated.h | 48 ++++++++++----------- src/p2p/p2p.hpp | 4 +- src/p2p/peer_comm_session.hpp | 2 +- src/p2p/peer_session_handler.cpp | 4 +- src/sc/contract_sync.cpp | 2 +- src/unl.cpp | 38 ++++++++-------- src/unl.hpp | 4 +- 15 files changed, 148 insertions(+), 110 deletions(-) diff --git a/examples/c_contract/hotpocket_contract.h b/examples/c_contract/hotpocket_contract.h index d357c4f8..e652b23f 100644 --- a/examples/c_contract/hotpocket_contract.h +++ b/examples/c_contract/hotpocket_contract.h @@ -155,6 +155,7 @@ struct hp_config char *bin_path; char *bin_args; uint32_t roundtime; + uint32_t stage_slice; char *consensus; char *npl; uint16_t max_input_ledger_offset; @@ -504,9 +505,12 @@ int hp_update_config(const struct hp_config *config) if (!config->bin_path || strlen(config->bin_path) == 0) __HP_UPDATE_CONFIG_ERROR("Binary path cannot be empty."); - if (config->roundtime <= 0) - __HP_UPDATE_CONFIG_ERROR("Round time must be higher than 0."); - + if (config->roundtime <= 0 || config->roundtime > 3600000) + __HP_UPDATE_CONFIG_ERROR("Round time must be between 1 and 3600000ms inclusive."); + + if (config->stage_slice <= 0 || config->stage_slice > 33) + __HP_UPDATE_CONFIG_ERROR("Stage slice must be between 1 and 33 percent inclusive"); + if (config->max_input_ledger_offset < 0) __HP_UPDATE_CONFIG_ERROR("Invalid max input ledger offset."); @@ -646,18 +650,23 @@ int __hp_write_to_patch_file(const int fd, const struct hp_config *config) // Top-level field values. - const char *json_string = " \"bin_path\": \"%s\",\n \"bin_args\": \"%s\",\n \"roundtime\": %s,\n" + const char *json_string = " \"bin_path\": \"%s\",\n \"bin_args\": \"%s\",\n \"roundtime\": %s,\n \"stage_slice\": %s,\n" " \"consensus\": \"%s\",\n \"npl\": \"%s\",\n \"max_input_ledger_offset\": %s,\n"; char roundtime_str[16]; sprintf(roundtime_str, "%d", config->roundtime); + char stage_slice_str[16]; + sprintf(stage_slice_str, "%d", config->stage_slice); + char max_input_ledger_offset_str[16]; sprintf(max_input_ledger_offset_str, "%d", config->max_input_ledger_offset); - const size_t json_string_len = 128 + strlen(config->bin_path) + strlen(config->bin_args) + strlen(roundtime_str) + strlen(config->consensus) + strlen(config->npl) + strlen(max_input_ledger_offset_str); + const size_t json_string_len = 149 + strlen(config->bin_path) + strlen(config->bin_args) + + strlen(roundtime_str) + strlen(stage_slice_str) + + strlen(config->consensus) + strlen(config->npl) + strlen(max_input_ledger_offset_str); char json_buf[json_string_len]; - sprintf(json_buf, json_string, config->bin_path, config->bin_args, roundtime_str, config->consensus, config->npl, max_input_ledger_offset_str); + sprintf(json_buf, json_string, config->bin_path, config->bin_args, roundtime_str, stage_slice_str, config->consensus, config->npl, max_input_ledger_offset_str); iov_vec[2].iov_base = json_buf; iov_vec[2].iov_len = json_string_len; @@ -753,6 +762,11 @@ void __hp_populate_patch_from_json_object(struct hp_config *config, const struct const struct json_number_s *value = (struct json_number_s *)elem->value->payload; config->roundtime = strtol(value->number, NULL, 0); } + else if (strcmp(k->string, "stage_slice") == 0) + { + const struct json_number_s *value = (struct json_number_s *)elem->value->payload; + config->stage_slice = strtol(value->number, NULL, 0); + } else if (strcmp(k->string, "max_input_ledger_offset") == 0) { const struct json_number_s *value = (struct json_number_s *)elem->value->payload; diff --git a/examples/nodejs_contract/hp-contract-lib.js b/examples/nodejs_contract/hp-contract-lib.js index baf2d0ee..961ad909 100644 --- a/examples/nodejs_contract/hp-contract-lib.js +++ b/examples/nodejs_contract/hp-contract-lib.js @@ -147,8 +147,10 @@ class PatchConfig { } if (!config.bin_path || !config.bin_path.length) throw "Binary path cannot be empty."; - if (config.roundtime <= 0) - throw "Round time must be higher than zero." + if (config.roundtime < 1 && config.roundtime > 3600000) + throw "Round time must be between 1 and 3600000ms inclusive."; + if (config.stage_slice < 1 || config.stage_slice > 33) + throw "Stage slice must be between 1 and 33 percent inclusive."; if (config.consensus != "public" && config.consensus != "private") throw "Invalid consensus flag configured in patch file. Valid values: public|private"; if (config.npl != "public" && config.npl != "private") diff --git a/src/conf.cpp b/src/conf.cpp index 729bce3e..f5631866 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -20,6 +20,8 @@ namespace conf ROLE startup_role; constexpr int FILE_PERMS = 0644; + constexpr uint32_t MAX_ROUND_TIME = 3600000; + constexpr uint32_t MAX_STAGE_SLICE = 33; constexpr const char *ROLE_OBSERVER = "observer"; constexpr const char *ROLE_VALIDATOR = "validator"; @@ -164,6 +166,7 @@ namespace conf cfg.contract.unl.emplace(cfg.node.public_key); cfg.contract.bin_path = ""; cfg.contract.roundtime = 1000; + cfg.contract.stage_slice = 25; cfg.contract.is_consensus_public = false; cfg.contract.is_npl_public = false; cfg.contract.max_input_ledger_offset = 10; @@ -644,13 +647,14 @@ namespace conf // Other required fields. bool fields_invalid = false; - fields_invalid |= cfg.contract.roundtime == 0 && std::cerr << "Invalid value for roundtime\n"; + fields_invalid |= cfg.contract.roundtime == 0 && std::cerr << "Invalid value for roundtime.\n"; + fields_invalid |= cfg.contract.stage_slice == 0 && std::cerr << "Invalid value for stage slice.\n"; fields_invalid |= cfg.contract.unl.empty() && std::cerr << "Invalid value for unl. Unl list cannot be empty.\n"; fields_invalid |= cfg.contract.id.empty() && std::cerr << "Invalid value for contract id.\n"; - fields_invalid |= cfg.mesh.port == 0 && std::cerr << "Invalid value for mesh port\n"; - fields_invalid |= cfg.user.port == 0 && std::cerr << "Invalid value for user port\n"; - fields_invalid |= cfg.log.log_level.empty() && std::cerr << "Invalid value for loglevel\n"; - fields_invalid |= cfg.log.loggers.empty() && std::cerr << "Invalid value for loggers\n"; + fields_invalid |= cfg.mesh.port == 0 && std::cerr << "Invalid value for mesh port.\n"; + fields_invalid |= cfg.user.port == 0 && std::cerr << "Invalid value for user port.\n"; + fields_invalid |= cfg.log.log_level.empty() && std::cerr << "Invalid value for loglevel.\n"; + fields_invalid |= cfg.log.loggers.empty() && std::cerr << "Invalid value for loggers.\n"; if (fields_invalid) { @@ -777,10 +781,13 @@ namespace conf /** * Prints the config json parsing field missing error. */ - void print_missing_field_error(std::string_view jpath, const std::exception &e) + void print_missing_field_error(std::string_view jpath, const std::exception &e, const bool is_patch_config) { // Extract field name from jsoncons exception message. - std::cerr << "Config validation error: " << e.what() << " in '" << jpath << "' section at " << ctx.config_file << std::endl; + if (is_patch_config) + LOG_ERROR << "Config validation error: " << e.what() << " in '" << jpath << "' section in patch config"; + else + std::cerr << "Config validation error: " << e.what() << " in '" << jpath << "' section at " << ctx.config_file << std::endl; } /** @@ -942,6 +949,7 @@ namespace conf jdoc.insert_or_assign("bin_path", contract.bin_path); jdoc.insert_or_assign("bin_args", contract.bin_args); jdoc.insert_or_assign("roundtime", contract.roundtime.load()); + jdoc.insert_or_assign("stage_slice", contract.stage_slice.load()); jdoc.insert_or_assign("consensus", contract.is_consensus_public ? PUBLIC : PRIVATE); jdoc.insert_or_assign("npl", contract.is_npl_public ? PUBLIC : PRIVATE); jdoc.insert_or_assign("max_input_ledger_offset", contract.max_input_ledger_offset); @@ -1016,9 +1024,16 @@ namespace conf contract.bin_args = jdoc["bin_args"].as(); contract.roundtime = jdoc["roundtime"].as(); - if (contract.roundtime == 0) + if (contract.roundtime < 1 || contract.roundtime > MAX_ROUND_TIME) { - std::cerr << "Round time cannot be zero.\n"; + std::cerr << "Round time must be between 1 and " << MAX_ROUND_TIME << "ms inclusive.\n"; + return -1; + } + + contract.stage_slice = jdoc["stage_slice"].as(); + if (contract.stage_slice < 1 || contract.stage_slice > MAX_STAGE_SLICE) + { + std::cerr << "Stage slice must be between 1 and " << MAX_STAGE_SLICE << " percent inclusive.\n"; return -1; } @@ -1051,7 +1066,7 @@ namespace conf } catch (const std::exception &e) { - print_missing_field_error(jpath, e); + print_missing_field_error(jpath, e, is_patch_config); return -1; } diff --git a/src/conf.hpp b/src/conf.hpp index 7a66e58b..4e770e55 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -11,6 +11,8 @@ namespace conf { constexpr size_t CONCURRENT_READ_REQUEST_MAX_LIMIT = 32; +#define CURRENT_TIME_CONFIG ((conf::cfg.contract.roundtime * 100) + conf::cfg.contract.stage_slice) + // Struct to represent ip and port of the peer. struct peer_ip_port { @@ -94,17 +96,18 @@ namespace conf struct contract_config { - std::string id; // Contract guid. - bool execute = false; // Whether or not to execute the contract on the node. - bool log_output = false; // Whether to log stdout/err of the contract process. - std::string version; // Contract version string. - std::set unl; // Unique node list (list of binary public keys) - std::string bin_path; // Full path to the contract binary - std::string bin_args; // CLI arguments to pass to the contract binary - std::atomic roundtime = 0; // Consensus round time in ms - bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well. - bool is_npl_public = false; // If true, npl messages are broadcasted to non-unl nodes as well. - uint16_t max_input_ledger_offset; // Maximum ledger sequence number offset that can be specified in the input. + std::string id; // Contract guid. + bool execute = false; // Whether or not to execute the contract on the node. + bool log_output = false; // Whether to log stdout/err of the contract process. + std::string version; // Contract version string. + std::set unl; // Unique node list (list of binary public keys). + std::string bin_path; // Full path to the contract binary. + std::string bin_args; // CLI arguments to pass to the contract binary. + std::atomic roundtime = 0; // Consensus round time in ms (max: 3,600,000). + std::atomic stage_slice = 0; // Percentage slice of round time that stages 0,1,2 get (max: 33). + bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well. + bool is_npl_public = false; // If true, npl messages are broadcasted to non-unl nodes as well. + uint16_t max_input_ledger_offset; // Maximum ledger sequence number offset that can be specified in the input. appbill_config appbill; round_limits_config round_limits; @@ -197,8 +200,8 @@ namespace conf struct log_config { - std::string log_level; // Log severity level (dbg, inf, wrn, wrr) - LOG_SEVERITY log_level_type; // Log severity level enum (debug, info, warn, error) + std::string log_level; // Log severity level (dbg, inf, wrn, wrr) + LOG_SEVERITY log_level_type; // Log severity level enum (debug, info, warn, error) std::unordered_set loggers; // List of enabled loggers (console, file) size_t max_mbytes_per_file = 0; // Max MB size of a single log file. size_t max_file_count = 0; // Max no. of log files to keep. @@ -247,7 +250,7 @@ namespace conf LOG_SEVERITY get_loglevel_type(std::string_view severity); - void print_missing_field_error(std::string_view jpath, const std::exception &e); + void print_missing_field_error(std::string_view jpath, const std::exception &e, const bool is_patch_config = false); int populate_patch_config(); diff --git a/src/consensus.cpp b/src/consensus.cpp index 36caef06..87818c5c 100644 --- a/src/consensus.cpp +++ b/src/consensus.cpp @@ -34,7 +34,7 @@ namespace consensus int init() { - refresh_roundtime(false); + refresh_time_config(false); // Starting consensus processing thread. ctx.consensus_thread = std::thread(run_consensus); @@ -149,7 +149,7 @@ namespace consensus ctx.unreliable_votes_attempts++; if (ctx.unreliable_votes_attempts >= MAX_UNRELIABLE_VOTES_ATTEMPTS) { - refresh_roundtime(true); + refresh_time_config(true); ctx.unreliable_votes_attempts = 0; } } @@ -378,7 +378,7 @@ namespace consensus } // Provide latest roundtime information to unl statistics. - unl::update_roundtime_stats(collected_proposals); + unl::update_time_config_stats(collected_proposals); // Move collected propsals to candidate set of proposals. for (const auto &p : collected_proposals) @@ -571,15 +571,15 @@ namespace consensus // If a node doesn't have enough time (eg. due to network delay) to recieve/send reliable stage proposals for next stage, // it will join in next round. Otherwise it will continue particapating in this round. - if (to_wait < ctx.stage_reset_wait_threshold) //todo: self claculating/adjusting network delay + if (stage_start < now || to_wait < ctx.stage_reset_wait_threshold) //todo: self claculating/adjusting network delay { LOG_DEBUG << "Missed stage " << std::to_string(ctx.stage) << " window. Resetting to stage 0."; - ctx.stage = 1; + ctx.stage = 0; return false; } else { - LOG_DEBUG << "Waiting " << std::to_string(to_wait) << "ms for stage " << std::to_string(ctx.stage); + LOG_DEBUG << "Waiting " << to_wait << "ms for stage " << std::to_string(ctx.stage); util::sleep(to_wait); return true; } @@ -773,6 +773,7 @@ namespace consensus p.patch_hash = patch_hash; p.last_primary_shard_id = last_primary_shard_id; p.last_raw_shard_id = last_raw_shard_id; + p.time_config = CURRENT_TIME_CONFIG; crypto::random_bytes(p.nonce, ROUND_NONCE_SIZE); // Populate the proposal with set of candidate user pubkeys. @@ -802,6 +803,7 @@ namespace consensus p.patch_hash = patch_hash; p.last_primary_shard_id = last_primary_shard_id; p.last_raw_shard_id = last_raw_shard_id; + p.time_config = CURRENT_TIME_CONFIG; p.output_hash.resize(BLAKE3_OUT_LEN); // Default empty hash. const uint64_t time_now = util::get_epoch_milliseconds(); @@ -1253,7 +1255,7 @@ namespace consensus // Appling new patch file changes to hpcore runtime. if (conf::apply_patch_config(HPFS_SESSION_NAME) == -1) { - LOG_ERROR << "Appling patch file changes after consensus failed."; + LOG_ERROR << "Applying patch file changes after consensus failed."; sc::contract_fs.stop_ro_session(HPFS_SESSION_NAME); return -1; } @@ -1261,7 +1263,7 @@ namespace consensus { unl::update_unl_changes_from_patch(); // Refresh values in consensus context to match newly synced roundtime from patch file. - refresh_roundtime(false); + refresh_time_config(false); is_patch_update_pending = false; } } @@ -1273,26 +1275,28 @@ namespace consensus } /** - * Updates roundtime-based calculations with the latest roundtime value. - * @param perform_detection Whether or not to detect roundtime from latest network information. + * Updates roundtime-based calculations with the latest time config value. + * @param perform_detection Whether or not to detect time config from latest network information. */ - void refresh_roundtime(const bool perform_detection) + void refresh_time_config(const bool perform_detection) { if (perform_detection) { - LOG_DEBUG << "Detecting roundtime..."; - const uint32_t majority_roundtime = unl::get_majority_roundtime(); + LOG_DEBUG << "Detecting time config..."; + const uint32_t majority_time_config = unl::get_majority_time_config(); - if (majority_roundtime == 0 || conf::cfg.contract.roundtime == majority_roundtime) + if (majority_time_config == 0 || CURRENT_TIME_CONFIG == majority_time_config) return; - LOG_INFO << "New roundtime detected:" << majority_roundtime << " previous:" << conf::cfg.contract.roundtime; + LOG_INFO << "New time config detected:" << majority_time_config << " previous:" << CURRENT_TIME_CONFIG; - conf::cfg.contract.roundtime = majority_roundtime; + // Time config is a single value derived from roundtime*100 + stage_slice. Here we derive back the original components. + conf::cfg.contract.roundtime = (majority_time_config / 100); + conf::cfg.contract.stage_slice = majority_time_config - (conf::cfg.contract.roundtime * 100); } - // We allocate 1/4 of roundtime for each stage (0, 1, 2, 3). - ctx.stage_time = conf::cfg.contract.roundtime / 4; + // We allocate configured stage slice for stages 0, 1, 2. Stage 3 gets the entire remaining time from the round window. + ctx.stage_time = conf::cfg.contract.roundtime * conf::cfg.contract.stage_slice / 100; ctx.stage_reset_wait_threshold = conf::cfg.contract.roundtime / 10; // We use a time window boundry offset based on contract id to vary the window boundries between diff --git a/src/consensus.hpp b/src/consensus.hpp index 9c797c94..b4248b92 100644 --- a/src/consensus.hpp +++ b/src/consensus.hpp @@ -214,7 +214,7 @@ namespace consensus int apply_consensed_patch_file_changes(const util::h32 &prop_patch_hash, const util::h32 ¤t_patch_hash); - void refresh_roundtime(const bool perform_detection); + void refresh_time_config(const bool perform_detection); } // namespace consensus diff --git a/src/msg/fbuf/p2pmsg.fbs b/src/msg/fbuf/p2pmsg.fbs index 1883e8a1..1e14c585 100644 --- a/src/msg/fbuf/p2pmsg.fbs +++ b/src/msg/fbuf/p2pmsg.fbs @@ -27,7 +27,7 @@ table P2PMsg { table PeerChallengeMsg { contract_id:string; - roundtime:uint32; + time_config:uint32; // Contains unified value derived from (roundtime*100 + stage_slice) is_full_history:bool; challenge:[ubyte]; } @@ -58,7 +58,7 @@ table ProposalMsg { sig:[ubyte]; // Signature of the field data. stage:uint8; time:uint64; - roundtime:uint32; + time_config:uint32; // Contains unified value derived from (roundtime*100 + stage_slice) nonce: [ubyte]; users:[ByteArray]; input_hashes:[ByteArray]; diff --git a/src/msg/fbuf/p2pmsg_conversion.cpp b/src/msg/fbuf/p2pmsg_conversion.cpp index efa36f6f..2d4ceeff 100644 --- a/src/msg/fbuf/p2pmsg_conversion.cpp +++ b/src/msg/fbuf/p2pmsg_conversion.cpp @@ -70,7 +70,7 @@ namespace msg::fbuf::p2pmsg flatbuf_hasher hasher; hasher.add(msg.stage()); hasher.add(msg.time()); - hasher.add(msg.roundtime()); + hasher.add(msg.time_config()); hasher.add(msg.nonce()); hasher.add(msg.users()); hasher.add(msg.input_hashes()); @@ -110,7 +110,7 @@ namespace msg::fbuf::p2pmsg const auto &msg = *mi.p2p_msg->content_as_PeerChallengeMsg(); return { std::string(flatbuf_str_to_sv(msg.contract_id())), - msg.roundtime(), + msg.time_config(), msg.is_full_history(), std::string(flatbuf_bytes_to_sv(msg.challenge()))}; } @@ -133,7 +133,7 @@ namespace msg::fbuf::p2pmsg p.sent_timestamp = mi.originated_on; p.recv_timestamp = util::get_epoch_milliseconds(); p.time = msg.time(); - p.roundtime = msg.roundtime(); + p.time_config = msg.time_config(); p.nonce = flatbuf_bytes_to_sv(msg.nonce()); p.stage = msg.stage(); p.state_hash = flatbuf_bytes_to_sv(msg.state_hash()); @@ -319,7 +319,7 @@ namespace msg::fbuf::p2pmsg flatbuf_hasher hasher; hasher.add(p.stage); hasher.add(p.time); - hasher.add(p.roundtime); + hasher.add(p.time_config); hasher.add(p.nonce); hasher.add(p.users); hasher.add(p.input_ordered_hashes); @@ -361,7 +361,7 @@ namespace msg::fbuf::p2pmsg const auto msg = CreatePeerChallengeMsg( builder, sv_to_flatbuf_str(builder, conf::cfg.contract.id), - conf::cfg.contract.roundtime, + CURRENT_TIME_CONFIG, conf::cfg.node.history == conf::HISTORY::FULL, sv_to_flatbuf_bytes(builder, challenge)); create_p2p_msg(builder, P2PMsgContent_PeerChallengeMsg, msg.Union()); @@ -396,7 +396,7 @@ namespace msg::fbuf::p2pmsg sv_to_flatbuf_bytes(builder, generate_proposal_signature(p)), p.stage, p.time, - p.roundtime, + p.time_config, sv_to_flatbuf_bytes(builder, p.nonce), stringlist_to_flatbuf_bytearrayvector(builder, p.users), stringlist_to_flatbuf_bytearrayvector(builder, p.input_ordered_hashes), diff --git a/src/msg/fbuf/p2pmsg_generated.h b/src/msg/fbuf/p2pmsg_generated.h index d5ea79c4..ce8a99d9 100644 --- a/src/msg/fbuf/p2pmsg_generated.h +++ b/src/msg/fbuf/p2pmsg_generated.h @@ -543,7 +543,7 @@ struct PeerChallengeMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef PeerChallengeMsgBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_CONTRACT_ID = 4, - VT_ROUNDTIME = 6, + VT_TIME_CONFIG = 6, VT_IS_FULL_HISTORY = 8, VT_CHALLENGE = 10 }; @@ -553,11 +553,11 @@ struct PeerChallengeMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { flatbuffers::String *mutable_contract_id() { return GetPointer(VT_CONTRACT_ID); } - uint32_t roundtime() const { - return GetField(VT_ROUNDTIME, 0); + uint32_t time_config() const { + return GetField(VT_TIME_CONFIG, 0); } - bool mutate_roundtime(uint32_t _roundtime) { - return SetField(VT_ROUNDTIME, _roundtime, 0); + bool mutate_time_config(uint32_t _time_config) { + return SetField(VT_TIME_CONFIG, _time_config, 0); } bool is_full_history() const { return GetField(VT_IS_FULL_HISTORY, 0) != 0; @@ -575,7 +575,7 @@ struct PeerChallengeMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_CONTRACT_ID) && verifier.VerifyString(contract_id()) && - VerifyField(verifier, VT_ROUNDTIME) && + VerifyField(verifier, VT_TIME_CONFIG) && VerifyField(verifier, VT_IS_FULL_HISTORY) && VerifyOffset(verifier, VT_CHALLENGE) && verifier.VerifyVector(challenge()) && @@ -590,8 +590,8 @@ struct PeerChallengeMsgBuilder { void add_contract_id(flatbuffers::Offset contract_id) { fbb_.AddOffset(PeerChallengeMsg::VT_CONTRACT_ID, contract_id); } - void add_roundtime(uint32_t roundtime) { - fbb_.AddElement(PeerChallengeMsg::VT_ROUNDTIME, roundtime, 0); + void add_time_config(uint32_t time_config) { + fbb_.AddElement(PeerChallengeMsg::VT_TIME_CONFIG, time_config, 0); } void add_is_full_history(bool is_full_history) { fbb_.AddElement(PeerChallengeMsg::VT_IS_FULL_HISTORY, static_cast(is_full_history), 0); @@ -614,12 +614,12 @@ struct PeerChallengeMsgBuilder { inline flatbuffers::Offset CreatePeerChallengeMsg( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset contract_id = 0, - uint32_t roundtime = 0, + uint32_t time_config = 0, bool is_full_history = false, flatbuffers::Offset> challenge = 0) { PeerChallengeMsgBuilder builder_(_fbb); builder_.add_challenge(challenge); - builder_.add_roundtime(roundtime); + builder_.add_time_config(time_config); builder_.add_contract_id(contract_id); builder_.add_is_full_history(is_full_history); return builder_.Finish(); @@ -628,7 +628,7 @@ inline flatbuffers::Offset CreatePeerChallengeMsg( inline flatbuffers::Offset CreatePeerChallengeMsgDirect( flatbuffers::FlatBufferBuilder &_fbb, const char *contract_id = nullptr, - uint32_t roundtime = 0, + uint32_t time_config = 0, bool is_full_history = false, const std::vector *challenge = nullptr) { auto contract_id__ = contract_id ? _fbb.CreateString(contract_id) : 0; @@ -636,7 +636,7 @@ inline flatbuffers::Offset CreatePeerChallengeMsgDirect( return msg::fbuf::p2pmsg::CreatePeerChallengeMsg( _fbb, contract_id__, - roundtime, + time_config, is_full_history, challenge__); } @@ -953,7 +953,7 @@ struct ProposalMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_SIG = 6, VT_STAGE = 8, VT_TIME = 10, - VT_ROUNDTIME = 12, + VT_TIME_CONFIG = 12, VT_NONCE = 14, VT_USERS = 16, VT_INPUT_HASHES = 18, @@ -988,11 +988,11 @@ struct ProposalMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool mutate_time(uint64_t _time) { return SetField(VT_TIME, _time, 0); } - uint32_t roundtime() const { - return GetField(VT_ROUNDTIME, 0); + uint32_t time_config() const { + return GetField(VT_TIME_CONFIG, 0); } - bool mutate_roundtime(uint32_t _roundtime) { - return SetField(VT_ROUNDTIME, _roundtime, 0); + bool mutate_time_config(uint32_t _time_config) { + return SetField(VT_TIME_CONFIG, _time_config, 0); } const flatbuffers::Vector *nonce() const { return GetPointer *>(VT_NONCE); @@ -1056,7 +1056,7 @@ struct ProposalMsg FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVector(sig()) && VerifyField(verifier, VT_STAGE) && VerifyField(verifier, VT_TIME) && - VerifyField(verifier, VT_ROUNDTIME) && + VerifyField(verifier, VT_TIME_CONFIG) && VerifyOffset(verifier, VT_NONCE) && verifier.VerifyVector(nonce()) && VerifyOffset(verifier, VT_USERS) && @@ -1097,8 +1097,8 @@ struct ProposalMsgBuilder { void add_time(uint64_t time) { fbb_.AddElement(ProposalMsg::VT_TIME, time, 0); } - void add_roundtime(uint32_t roundtime) { - fbb_.AddElement(ProposalMsg::VT_ROUNDTIME, roundtime, 0); + void add_time_config(uint32_t time_config) { + fbb_.AddElement(ProposalMsg::VT_TIME_CONFIG, time_config, 0); } void add_nonce(flatbuffers::Offset> nonce) { fbb_.AddOffset(ProposalMsg::VT_NONCE, nonce); @@ -1145,7 +1145,7 @@ inline flatbuffers::Offset CreateProposalMsg( flatbuffers::Offset> sig = 0, uint8_t stage = 0, uint64_t time = 0, - uint32_t roundtime = 0, + uint32_t time_config = 0, flatbuffers::Offset> nonce = 0, flatbuffers::Offset>> users = 0, flatbuffers::Offset>> input_hashes = 0, @@ -1166,7 +1166,7 @@ inline flatbuffers::Offset CreateProposalMsg( builder_.add_input_hashes(input_hashes); builder_.add_users(users); builder_.add_nonce(nonce); - builder_.add_roundtime(roundtime); + builder_.add_time_config(time_config); builder_.add_sig(sig); builder_.add_pubkey(pubkey); builder_.add_stage(stage); @@ -1179,7 +1179,7 @@ inline flatbuffers::Offset CreateProposalMsgDirect( const std::vector *sig = nullptr, uint8_t stage = 0, uint64_t time = 0, - uint32_t roundtime = 0, + uint32_t time_config = 0, const std::vector *nonce = nullptr, const std::vector> *users = nullptr, const std::vector> *input_hashes = nullptr, @@ -1204,7 +1204,7 @@ inline flatbuffers::Offset CreateProposalMsgDirect( sig__, stage, time, - roundtime, + time_config, nonce__, users__, input_hashes__, diff --git a/src/p2p/p2p.hpp b/src/p2p/p2p.hpp index da9f39cb..a55dd916 100644 --- a/src/p2p/p2p.hpp +++ b/src/p2p/p2p.hpp @@ -72,7 +72,7 @@ namespace p2p uint64_t recv_timestamp = 0; // The timestamp when we received the proposal. (used for network statistics) uint64_t time = 0; // The descreet concensus time value that is voted on. uint8_t stage = 0; // The round-stage that this proposal belongs to. - uint32_t roundtime = 0; // Roundtime of the proposer. + uint32_t time_config = 0; // Time config of the proposer. std::string nonce; // Random nonce that is used to reduce lcl predictability. sequence_hash last_primary_shard_id; sequence_hash last_raw_shard_id; @@ -92,7 +92,7 @@ namespace p2p struct peer_challenge { std::string contract_id; - uint32_t roundtime = 0; + uint32_t time_config = 0; // Contains unified value derived from (roundtime*100 + stage_slice) bool is_full_history = false; std::string challenge; }; diff --git a/src/p2p/peer_comm_session.hpp b/src/p2p/peer_comm_session.hpp index 3ae0eb7b..8f618778 100644 --- a/src/p2p/peer_comm_session.hpp +++ b/src/p2p/peer_comm_session.hpp @@ -25,7 +25,7 @@ namespace p2p std::optional known_ipport; // A known ip/port information that matches with our peer list configuration. bool need_consensus_msg_forwarding = false; // Holds whether this node requires consensus message forwarding. bool is_unl = false; // Whether this session's pubkey is in unl list. - uint32_t reported_roundtime = 0; // Initial roundtime reported by this peer on peer challenge. + uint32_t reported_time_config = 0; // Initial time config reported by this peer on peer challenge. bool is_full_history; // Stores whether the connection is to a full history node or not. }; diff --git a/src/p2p/peer_session_handler.cpp b/src/p2p/peer_session_handler.cpp index a601ae1a..1f50bf39 100644 --- a/src/p2p/peer_session_handler.cpp +++ b/src/p2p/peer_session_handler.cpp @@ -122,8 +122,8 @@ namespace p2p return -1; } - // Remember the roundtime reported by this peer. - session.reported_roundtime = chall.roundtime; + // Remember the time config reported by this peer. + session.reported_time_config = chall.time_config; // Whether this node is a full history node or not. session.is_full_history = chall.is_full_history; diff --git a/src/sc/contract_sync.cpp b/src/sc/contract_sync.cpp index b35b2c7b..1c4e8cfd 100644 --- a/src/sc/contract_sync.cpp +++ b/src/sc/contract_sync.cpp @@ -20,7 +20,7 @@ namespace sc else { unl::update_unl_changes_from_patch(); - consensus::refresh_roundtime(false); + consensus::refresh_time_config(false); // Update global hash tracker with the new patch file hash. fs_mount->set_parent_hash(synced_target.vpath, synced_target.hash); diff --git a/src/unl.cpp b/src/unl.cpp index 0716d89f..bd1cfdf1 100644 --- a/src/unl.cpp +++ b/src/unl.cpp @@ -9,7 +9,7 @@ */ namespace unl { - std::map list; // List of binary pubkeys of UNL and their latest reported roundtime. + std::map list; // List of binary pubkeys of UNL and their latest reported time configs. std::string json_list; // Stringified json array of UNL. (To be fed into the contract args) std::shared_mutex unl_mutex; @@ -38,7 +38,7 @@ namespace unl { std::shared_lock lock(unl_mutex); std::set ret; - for (auto [pubkey, roundtime] : list) + for (auto [pubkey, time_config] : list) ret.emplace(std::move(pubkey)); return ret; } @@ -81,9 +81,9 @@ namespace unl } /** - * Updates unl pubkey-roundtime information using the specified list of proposals. + * Updates unl pubkey-->time config information using the specified list of proposals. */ - void update_roundtime_stats(const std::list &proposals) + void update_time_config_stats(const std::list &proposals) { std::unique_lock lock(unl_mutex); @@ -91,53 +91,53 @@ namespace unl { const auto itr = list.find(p.pubkey); if (itr != list.end()) - itr->second = p.roundtime; + itr->second = p.time_config; } } /** - * Returns the majority roundtime reported among the unl. + * Returns the majority time config reported among the unl. */ - uint32_t get_majority_roundtime() + uint32_t get_majority_time_config() { std::unique_lock lock(unl_mutex); - // Vote and find majority roundtime within the unl. - // Fill any 0 roundtimes with information from peer connections. - std::map roundtime_votes; + // Vote and find majority time config within the unl using values extracted from incoming proposals. + // Fill any 0 time configs with information from peer connections. + std::map time_config_votes; { std::scoped_lock lock(p2p::ctx.peer_connections_mutex); for (auto itr = list.begin(); itr != list.end(); itr++) { - // If roundtime is 0, attempt to get from peer connection (if available). + // If time config is 0, attempt to get from peer connection (if available). if (itr->second == 0) { const auto peer_itr = p2p::ctx.peer_connections.find(itr->first); if (peer_itr != p2p::ctx.peer_connections.end()) - itr->second = peer_itr->second->reported_roundtime; + itr->second = peer_itr->second->reported_time_config; } - const uint32_t roundtime = itr->second; - if (roundtime > 0) - roundtime_votes[roundtime]++; + const uint32_t time_config = itr->second; + if (time_config > 0) + time_config_votes[time_config]++; } } // Find the majority vote. uint32_t highest_votes = 0; - uint32_t majority_roundtime = 0; - for (const auto [roundtime, num_votes] : roundtime_votes) + uint32_t majority_time_config = 0; + for (const auto [time_config, num_votes] : time_config_votes) { if (num_votes > highest_votes) { highest_votes = num_votes; - majority_roundtime = roundtime; + majority_time_config = time_config; } } - return majority_roundtime; + return majority_time_config; } /** diff --git a/src/unl.hpp b/src/unl.hpp index 386d05bf..c4a9cb78 100644 --- a/src/unl.hpp +++ b/src/unl.hpp @@ -17,8 +17,8 @@ namespace unl bool exists(const std::string &bin_pubkey); int init(); void update_unl_changes_from_patch(); - void update_roundtime_stats(const std::list &proposals); - uint32_t get_majority_roundtime(); + void update_time_config_stats(const std::list &proposals); + uint32_t get_majority_time_config(); bool update_unl_list(const std::set &new_list); const std::string prepare_json_list(const std::set &new_list);