Added stage slice config to control stage time allocation. (#310)

This commit is contained in:
Ravin Perera
2021-05-19 16:59:01 +05:30
committed by GitHub
parent 94b29b9e05
commit 45492f7c7f
15 changed files with 148 additions and 110 deletions

View File

@@ -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