mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
#ifndef _HP_CONS_
|
|
#define _HP_CONS_
|
|
|
|
#include "../pchheader.hpp"
|
|
#include "../util.hpp"
|
|
#include "../proc/proc.hpp"
|
|
#include "../p2p/p2p.hpp"
|
|
#include "../usr/user_input.hpp"
|
|
|
|
namespace cons
|
|
{
|
|
|
|
//stage 1 vote threshold
|
|
static const float STAGE1_THRESHOLD = 0.5;
|
|
//stage 2 vote threshold
|
|
static const float STAGE2_THRESHOLD = 0.65;
|
|
//stage 3 vote threshold
|
|
static const float STAGE3_THRESHOLD = 0.8;
|
|
|
|
/**
|
|
* Represents a contract input that takes part in consensus.
|
|
*/
|
|
struct candidate_user_input
|
|
{
|
|
const std::string userpubkey;
|
|
const uint64_t maxledgerseqno;
|
|
std::string input;
|
|
|
|
candidate_user_input(const std::string userpubkey, const std::string input, const uint64_t maxledgerseqno)
|
|
: userpubkey(std::move(userpubkey)), input(std::move(input)), maxledgerseqno(maxledgerseqno)
|
|
{
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Represents a contract output that takes part in consensus.
|
|
*/
|
|
struct candidate_user_output
|
|
{
|
|
const std::string userpubkey;
|
|
std::string output;
|
|
|
|
candidate_user_output(const std::string userpubkey, const std::string output)
|
|
: userpubkey(std::move(userpubkey)), output(std::move(output))
|
|
{
|
|
}
|
|
};
|
|
|
|
/**
|
|
* This is used to store consensus information
|
|
*/
|
|
struct consensus_context
|
|
{
|
|
// The set of proposals that are being collected as consensus stages are progressing.
|
|
std::list<p2p::proposal> candidate_proposals;
|
|
|
|
// Set of user pubkeys that is said to be connected to the cluster. This will be cleared in each round.
|
|
std::unordered_set<std::string> candidate_users;
|
|
|
|
// Map of candidate user inputs with input hash as map key. Inputs will stay here until they
|
|
// achieve consensus or expire (due to maxledgerseqno). Input hash is globally unique among inputs
|
|
// from all users. We will use this map to feed inputs into the contract once consensus is achieved.
|
|
std::unordered_map<std::string, candidate_user_input> candidate_user_inputs;
|
|
|
|
// Map of outputs generated by the contract with output hash is the map key. Outputs will stay
|
|
// here until the end of the current consensus round. Output hash is globally unique among outputs for
|
|
// all users. We will use this map to distribute outputs back to connected users once consensus is achieved.
|
|
std::unordered_map<std::string, candidate_user_output> candidate_user_outputs;
|
|
|
|
util::rollover_hashset recent_userinput_hashes;
|
|
|
|
uint8_t stage;
|
|
uint64_t novel_proposal_time;
|
|
uint64_t time_now;
|
|
std::string lcl;
|
|
uint64_t led_seq_no;
|
|
|
|
consensus_context() : recent_userinput_hashes(200)
|
|
{
|
|
}
|
|
};
|
|
|
|
struct vote_counter
|
|
{
|
|
std::map<uint8_t, int32_t> stage;
|
|
std::map<uint64_t, int32_t> time;
|
|
std::map<std::string, int32_t> lcl;
|
|
std::map<std::string, int32_t> users;
|
|
std::map<std::string, int32_t> inputs;
|
|
std::map<std::string, int32_t> outputs;
|
|
};
|
|
|
|
extern consensus_context ctx;
|
|
|
|
int init();
|
|
|
|
void consensus();
|
|
|
|
void broadcast_nonunl_proposal();
|
|
|
|
void verify_and_populate_candidate_user_inputs();
|
|
|
|
p2p::proposal create_stage0_proposal();
|
|
|
|
p2p::proposal create_stage123_proposal(vote_counter &votes);
|
|
|
|
void broadcast_proposal(const p2p::proposal &p);
|
|
|
|
void check_majority_stage(bool &is_desync, bool &should_reset, uint8_t &majority_stage, vote_counter &votes);
|
|
|
|
void check_lcl_votes(bool &is_desync, bool &should_request_history, std::string &majority_lcl, vote_counter &votes);
|
|
|
|
float_t get_stage_threshold(const uint8_t stage);
|
|
|
|
void timewait_stage(const bool reset);
|
|
|
|
void apply_ledger(const p2p::proposal &proposal);
|
|
|
|
void dispatch_user_outputs(const p2p::proposal &cons_prop);
|
|
|
|
void feed_inputs_to_contract_bufmap(proc::contract_bufmap_t &bufmap, const p2p::proposal &cons_prop);
|
|
|
|
void extract_outputs_from_contract_bufmap(proc::contract_bufmap_t &bufmap);
|
|
|
|
void run_contract_binary(const int64_t time_now, proc::contract_bufmap_t &useriobufmap);
|
|
|
|
template <typename T>
|
|
void increment(std::map<T, int32_t> &counter, const T &candidate);
|
|
|
|
} // namespace cons
|
|
|
|
#endif
|