Subject UNL changeset to consensus. (#183)

This commit is contained in:
Chalith Desaman
2020-12-07 13:06:58 +05:30
committed by GitHub
parent da0eb08512
commit a87e8a0c7e
17 changed files with 309 additions and 49 deletions

View File

@@ -125,7 +125,7 @@ namespace consensus
if (ctx.stage == 0)
{
// Prepare the consensus candidate user inputs that we have acumulated so far. (We receive them periodically via NUPs)
// Prepare the consensus candidate user inputs that we have accumulated so far. (We receive them periodically via NUPs)
// The candidate inputs will be included in the stage 0 proposal.
if (verify_and_populate_candidate_user_inputs(lcl_seq_no) == -1)
return -1;
@@ -164,6 +164,9 @@ namespace consensus
// This is the consensus proposal which makes it into the ledger and contract execution
const p2p::proposal p = create_stage123_proposal(STAGE3_THRESHOLD, votes, lcl, unl_count, state);
// Update the unl with the unl changeset that subjected to the consensus.
unl::update(p.unl_changeset.additions, p.unl_changeset.removals);
// Update the ledger and execute the contract using the consensus proposal.
if (update_ledger_and_execute_contract(p, lcl, state) == -1)
LOG_ERROR << "Error occured in Stage 3 consensus execution.";
@@ -518,6 +521,9 @@ namespace consensus
for (const auto &[hash, cand_output] : ctx.candidate_user_outputs)
stg_prop.hash_outputs.emplace(hash);
// Populate the proposal wil unl changeset.
stg_prop.unl_changeset = ctx.candidate_unl_changeset;
return stg_prop;
}
@@ -557,9 +563,19 @@ namespace consensus
for (const std::string &hash : cp.hash_outputs)
if (ctx.candidate_user_outputs.count(hash) > 0)
increment(votes.outputs, hash);
// Vote for unl additions. Only vote for the unl additions that are in our candidate_unl_changeset.
for (const std::string &pubkey : cp.unl_changeset.additions)
if (ctx.candidate_unl_changeset.additions.count(pubkey) > 0)
increment(votes.unl_additions, pubkey);
// Vote for unl removals. Only vote for the unl removals that are in our candidate_unl_changeset.
for (const std::string &pubkey : cp.unl_changeset.removals)
if (ctx.candidate_unl_changeset.removals.count(pubkey) > 0)
increment(votes.unl_removals, pubkey);
}
const uint32_t required_votes = ceil(vote_threshold * unl_count);
uint32_t required_votes = ceil(vote_threshold * unl_count);
// todo: check if inputs being proposed by another node are actually spoofed inputs
// from a user locally connected to this node.
@@ -581,6 +597,19 @@ namespace consensus
if (numvotes >= required_votes)
stg_prop.hash_outputs.emplace(hash);
// For the unl changeset reset required votes for majority votes.
required_votes = ceil(MAJORITY_THRESHOLD * unl_count);
// Add unl additions which have votes over majority threshold to proposal.
for (const auto &[pubkey, numvotes] : votes.unl_additions)
if (numvotes >= required_votes)
stg_prop.unl_changeset.additions.emplace(pubkey);
// Add unl removals which have votes over majority threshold to proposal.
for (const auto &[pubkey, numvotes] : votes.unl_removals)
if (numvotes >= required_votes)
stg_prop.unl_changeset.removals.emplace(pubkey);
// time is voted on a simple sorted (highest to lowest) and majority basis, since there will always be disagreement.
uint32_t highest_time_vote = 0;
for (auto itr = votes.time.rbegin(); itr != votes.time.rend(); ++itr)
@@ -772,6 +801,9 @@ namespace consensus
}
}
// Clear candidate unl changset after consensus rounds are completed.
ctx.candidate_unl_changeset.clear();
// Send any output from the previous consensus round to locally connected users.
dispatch_user_outputs(cons_prop, new_lcl_seq_no, new_lcl);
@@ -804,6 +836,10 @@ namespace consensus
extract_user_outputs_from_contract_bufmap(args.userbufs);
// Prepare the consensus candidate unl changeset that we have accumulated so far. (We receive them as control inputs)
// The candidate unl changeset will be included in the stage 0 proposal.
std::swap(ctx.candidate_unl_changeset, ctx.contract_ctx->args.unl_changeset);
{
std::scoped_lock lock(ctx.contract_ctx_mutex);
ctx.contract_ctx.reset();