Skip to content

Commit

Permalink
chore: improve dag propose probability
Browse files Browse the repository at this point in the history
  • Loading branch information
mfrankovi authored and JakubFornadel committed Sep 22, 2023
1 parent 7a16797 commit b9c995e
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class DagBlockProposer {
DagBlockProposer(const DagBlockProposerConfig& bp_config, std::shared_ptr<DagManager> dag_mgr,
std::shared_ptr<TransactionManager> trx_mgr, std::shared_ptr<final_chain::FinalChain> final_chain,
std::shared_ptr<DbStorage> db, std::shared_ptr<KeyManager> key_manager, addr_t node_addr,
secret_t node_sk, vrf_wrapper::vrf_sk_t vrf_sk, uint64_t pbft_gas_limit, uint64_t dag_gas_limit);
secret_t node_sk, vrf_wrapper::vrf_sk_t vrf_sk, uint64_t pbft_gas_limit, uint64_t dag_gas_limit,
const state_api::Config& state_config);
~DagBlockProposer() { stop(); }
DagBlockProposer(const DagBlockProposer&) = delete;
DagBlockProposer(DagBlockProposer&&) = delete;
Expand Down Expand Up @@ -149,6 +150,9 @@ class DagBlockProposer {
const uint64_t kPbftGasLimit;
const uint64_t kDagGasLimit;

const HardforksConfig kHardforks;
const uint64_t kValidatorMaxVote;

LOG_OBJECTS_DEFINE
};

Expand Down
6 changes: 4 additions & 2 deletions libraries/core_libs/consensus/include/dag/dag_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class DagManager : public std::enable_shared_from_this<DagManager> {
const DagConfig &dag_config, std::shared_ptr<TransactionManager> trx_mgr,
std::shared_ptr<PbftChain> pbft_chain, std::shared_ptr<FinalChain> final_chain,
std::shared_ptr<DbStorage> db, std::shared_ptr<KeyManager> key_manager, uint64_t pbft_gas_limit,
bool is_light_node = false, uint64_t light_node_history = 0,
uint32_t max_levels_per_period = kMaxLevelsPerPeriod,
const state_api::Config &state_config, bool is_light_node = false,
uint64_t light_node_history = 0, uint32_t max_levels_per_period = kMaxLevelsPerPeriod,
uint32_t dag_expiry_limit = kDagExpiryLevelLimit);

DagManager(const DagManager &) = delete;
Expand Down Expand Up @@ -282,6 +282,8 @@ class DagManager : public std::enable_shared_from_this<DagManager> {
ExpirationCacheMap<blk_hash_t, DagBlock> seen_blocks_;
std::shared_ptr<FinalChain> final_chain_;
const uint64_t kPbftGasLimit;
const HardforksConfig kHardforks;
const uint64_t kValidatorMaxVote;

LOG_OBJECTS_DEFINE
};
Expand Down
16 changes: 12 additions & 4 deletions libraries/core_libs/consensus/src/dag/dag_block_proposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ DagBlockProposer::DagBlockProposer(const DagBlockProposerConfig& bp_config, std:
std::shared_ptr<TransactionManager> trx_mgr,
std::shared_ptr<final_chain::FinalChain> final_chain, std::shared_ptr<DbStorage> db,
std::shared_ptr<KeyManager> key_manager, addr_t node_addr, secret_t node_sk,
vrf_wrapper::vrf_sk_t vrf_sk, uint64_t pbft_gas_limit, uint64_t dag_gas_limit)
vrf_wrapper::vrf_sk_t vrf_sk, uint64_t pbft_gas_limit, uint64_t dag_gas_limit,
const state_api::Config& state_config)
: bp_config_(bp_config),
total_trx_shards_(std::max(bp_config_.shard, uint16_t(1))),
dag_mgr_(std::move(dag_mgr)),
Expand All @@ -30,7 +31,9 @@ DagBlockProposer::DagBlockProposer(const DagBlockProposerConfig& bp_config, std:
vrf_sk_(std::move(vrf_sk)),
vrf_pk_(vrf_wrapper::getVrfPublicKey(vrf_sk_)),
kPbftGasLimit(pbft_gas_limit),
kDagGasLimit(dag_gas_limit) {
kDagGasLimit(dag_gas_limit),
kHardforks(state_config.hardforks),
kValidatorMaxVote(state_config.dpos.validator_maximum_stake / state_config.dpos.vote_eligibility_balance_step) {
LOG_OBJECTS_CREATE("DAG_PROPOSER");

// Add a random component in proposing stale blocks so that not all nodes propose stale blocks at the same time
Expand Down Expand Up @@ -69,15 +72,20 @@ bool DagBlockProposer::proposeDagBlock() {
return false;
}

const auto total_vote_count = final_chain_->dpos_eligible_total_vote_count(*proposal_period);
uint64_t max_vote_count = 0;
const auto vote_count = final_chain_->dpos_eligible_vote_count(*proposal_period, node_addr_);
if (*proposal_period < kHardforks.magnolia_hf.block_num) {
max_vote_count = final_chain_->dpos_eligible_total_vote_count(*proposal_period);
} else {
max_vote_count = kValidatorMaxVote;
}

const auto period_block_hash = db_->getPeriodBlockHash(*proposal_period);
// get sortition
const auto sortition_params = dag_mgr_->sortitionParamsManager().getSortitionParams(*proposal_period);
vdf_sortition::VdfSortition vdf(sortition_params, vrf_sk_,
VrfSortitionBase::makeVrfInput(propose_level, period_block_hash), vote_count,
total_vote_count);
max_vote_count);
if (vdf.isStale(sortition_params)) {
if (last_propose_level_ == propose_level) {
if (num_tries_ < max_num_tries_) {
Expand Down
26 changes: 19 additions & 7 deletions libraries/core_libs/consensus/src/dag/dag_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ DagManager::DagManager(const DagBlock &dag_genesis_block, addr_t node_addr, cons
const DagConfig &dag_config, std::shared_ptr<TransactionManager> trx_mgr,
std::shared_ptr<PbftChain> pbft_chain, std::shared_ptr<FinalChain> final_chain,
std::shared_ptr<DbStorage> db, std::shared_ptr<KeyManager> key_manager, uint64_t pbft_gas_limit,
bool is_light_node, uint64_t light_node_history, uint32_t max_levels_per_period,
uint32_t dag_expiry_limit) try
const state_api::Config &state_config, bool is_light_node, uint64_t light_node_history,
uint32_t max_levels_per_period, uint32_t dag_expiry_limit) try
: max_level_(db->getLastBlocksLevel()),
pivot_tree_(std::make_shared<PivotTree>(dag_genesis_block.getHash(), node_addr)),
total_dag_(std::make_shared<Dag>(dag_genesis_block.getHash(), node_addr)),
Expand All @@ -39,7 +39,9 @@ DagManager::DagManager(const DagBlock &dag_genesis_block, addr_t node_addr, cons
dag_expiry_limit_(dag_expiry_limit),
seen_blocks_(cache_max_size_, cache_delete_step_),
final_chain_(std::move(final_chain)),
kPbftGasLimit(pbft_gas_limit) {
kPbftGasLimit(pbft_gas_limit),
kHardforks(state_config.hardforks),
kValidatorMaxVote(state_config.dpos.validator_maximum_stake / state_config.dpos.vote_eligibility_balance_step) {
LOG_OBJECTS_CREATE("DAGMGR");
if (auto ret = getLatestPivotAndTips(); ret) {
frontier_.pivot = ret->first;
Expand Down Expand Up @@ -502,10 +504,15 @@ void DagManager::recoverDag() {
}
// Verify VDF solution
try {
const auto total_vote_count = final_chain_->dpos_eligible_total_vote_count(*propose_period);
uint64_t max_vote_count = 0;
const auto vote_count = final_chain_->dpos_eligible_vote_count(*propose_period, blk.getSender());
if (*propose_period < kHardforks.magnolia_hf.block_num) {
max_vote_count = final_chain_->dpos_eligible_total_vote_count(*propose_period);
} else {
max_vote_count = kValidatorMaxVote;
}
blk.verifyVdf(sortition_params_manager_.getSortitionParams(*propose_period),
db_->getPeriodBlockHash(*propose_period), *pk, vote_count, total_vote_count);
db_->getPeriodBlockHash(*propose_period), *pk, vote_count, max_vote_count);
} catch (vdf_sortition::VdfSortition::InvalidVdfSortition const &e) {
LOG(log_er_) << "DAG block " << blk.getHash() << " with " << blk.getLevel()
<< " level failed on VDF verification with pivot hash " << blk.getPivot() << " reason "
Expand Down Expand Up @@ -630,10 +637,15 @@ DagManager::VerifyBlockReturnType DagManager::verifyBlock(const DagBlock &blk) {

try {
const auto proposal_period_hash = db_->getPeriodBlockHash(*propose_period);
const auto total_vote_count = final_chain_->dpos_eligible_total_vote_count(*propose_period);
uint64_t max_vote_count = 0;
const auto vote_count = final_chain_->dpos_eligible_vote_count(*propose_period, blk.getSender());
if (*propose_period < kHardforks.magnolia_hf.block_num) {
max_vote_count = final_chain_->dpos_eligible_total_vote_count(*propose_period);
} else {
max_vote_count = kValidatorMaxVote;
}
blk.verifyVdf(sortition_params_manager_.getSortitionParams(*propose_period), proposal_period_hash, *pk, vote_count,
total_vote_count);
max_vote_count);
} catch (vdf_sortition::VdfSortition::InvalidVdfSortition const &e) {
LOG(log_er_) << "DAG block " << block_hash << " with " << blk.getLevel()
<< " level failed on VDF verification with pivot hash " << blk.getPivot() << " reason " << e.what();
Expand Down
2 changes: 1 addition & 1 deletion libraries/core_libs/consensus/src/pbft/pbft_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ bool PbftManager::advancePeriod() {
// Cleanup proposed blocks
proposed_blocks_.cleanupProposedPbftBlocksByPeriod(new_period);

LOG(log_er_) << "Period advanced to: " << new_period << ", round and step reset to 1";
LOG(log_nf_) << "Period advanced to: " << new_period << ", round and step reset to 1";

// Restart while loop...
return true;
Expand Down
10 changes: 5 additions & 5 deletions libraries/core_libs/node/src/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ void FullNode::init() {
}

pbft_chain_ = std::make_shared<PbftChain>(node_addr, db_);
dag_mgr_ = std::make_shared<DagManager>(conf_.genesis.dag_genesis_block, node_addr, conf_.genesis.sortition,
conf_.genesis.dag, trx_mgr_, pbft_chain_, final_chain_, db_, key_manager_,
conf_.genesis.pbft.gas_limit, conf_.is_light_node, conf_.light_node_history,
conf_.max_levels_per_period, conf_.dag_expiry_limit);
dag_mgr_ = std::make_shared<DagManager>(
conf_.genesis.dag_genesis_block, node_addr, conf_.genesis.sortition, conf_.genesis.dag, trx_mgr_, pbft_chain_,
final_chain_, db_, key_manager_, conf_.genesis.pbft.gas_limit, conf_.genesis.state, conf_.is_light_node,
conf_.light_node_history, conf_.max_levels_per_period, conf_.dag_expiry_limit);
auto slashing_manager = std::make_shared<SlashingManager>(final_chain_, trx_mgr_, gas_pricer_, conf_, kp_.secret());
vote_mgr_ = std::make_shared<VoteManager>(node_addr, conf_.genesis.pbft, kp_.secret(), conf_.vrf_secret, db_,
pbft_chain_, final_chain_, key_manager_, slashing_manager);
Expand All @@ -135,7 +135,7 @@ void FullNode::init() {
pbft_chain_, vote_mgr_, dag_mgr_, trx_mgr_, final_chain_, kp_.secret());
dag_block_proposer_ = std::make_shared<DagBlockProposer>(
conf_.genesis.dag.block_proposer, dag_mgr_, trx_mgr_, final_chain_, db_, key_manager_, node_addr, getSecretKey(),
getVrfSecretKey(), conf_.genesis.pbft.gas_limit, conf_.genesis.dag.gas_limit);
getVrfSecretKey(), conf_.genesis.pbft.gas_limit, conf_.genesis.dag.gas_limit, conf_.genesis.state);

network_ = std::make_shared<Network>(conf_, genesis_hash, conf_.net_file_path().string(), kp_, db_, pbft_mgr_,
pbft_chain_, vote_mgr_, dag_mgr_, trx_mgr_, std::move(slashing_manager));
Expand Down
63 changes: 63 additions & 0 deletions tests/crypto_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,69 @@ TEST_F(CryptoTest, vdf_stake_test) {
<< (count_dag_blocks_production[i] * 1000 / total_dags % 100) << "%" << std::endl;
}
}

// Post magnolia hardfork stakes
for (uint32_t upper_threshold = 0x5ff; upper_threshold < 0xffff; upper_threshold *= 3) {
std::cout << "Upper threshold: " << upper_threshold << std::endl;
SortitionParams sortition_params(upper_threshold, 16, 21, 23, 0x64);
uint64_t total_vote_count = 800;
const uint64_t voters_count = 8;
uint64_t voters_vote_count[voters_count];
uint64_t count_dag_blocks_production[voters_count];
for (uint64_t i = 0; i < voters_count; i++) {
count_dag_blocks_production[i] = 0;
}
voters_vote_count[0] = 50;
voters_vote_count[1] = 100;
voters_vote_count[2] = 200;
voters_vote_count[3] = 300;
voters_vote_count[4] = 400;
voters_vote_count[5] = 500;
voters_vote_count[6] = 650;
voters_vote_count[7] = 800;
vrf_sk_t sk(
"0b6627a6680e01cea3d9f36fa797f7f34e8869c3a526d9ed63ed8170e35542aad05dc12c"
"1df1edc9f3367fba550b7971fc2de6c5998d8784051c5be69abc9644");
for (uint32_t counter = 1; counter < 3000; counter++) {
level_t level = counter * voters_count;
uint64_t difficulties[voters_count];
for (uint64_t i = 0; i < voters_count; i++) {
VdfSortition vdf(sortition_params, sk, getRlpBytes(level + i), voters_vote_count[i], total_vote_count);
difficulties[i] = vdf.getDifficulty();
}
uint64_t min_diff = 24;
for (uint64_t i = 0; i < voters_count; i++) {
if (difficulties[i] < min_diff) {
min_diff = difficulties[i];
}
}
// Stale block is produced by random node
if (min_diff == 23) {
count_dag_blocks_production[rand() % voters_count]++;
} else {
for (uint64_t i = 0; i < voters_count; i++) {
if (difficulties[i] == min_diff) {
count_dag_blocks_production[i]++;
// std::cout << "min AT " << i << std::endl;
}
}
}
}
uint64_t total_dags = 0;
for (auto count : count_dag_blocks_production) {
total_dags += count;
}
std::cout << "total_dags: " << total_dags << std::endl;
for (uint64_t i = 0; i < voters_count; i++) {
if (i > 0) {
// Verify that greater stake produce more dag blocks
EXPECT_GE(count_dag_blocks_production[i], count_dag_blocks_production[i - 1]);
}
std::cout << "Vote stake " << voters_vote_count[i] / 8 << "." << voters_vote_count[i] % 8
<< "% - Dag ratio: " << count_dag_blocks_production[i] * 100 / total_dags << "."
<< (count_dag_blocks_production[i] * 1000 / total_dags % 100) << "%" << std::endl;
}
}
}

TEST_F(CryptoTest, vdf_sortition) {
Expand Down
36 changes: 18 additions & 18 deletions tests/dag_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ TEST_F(DagTest, compute_epoch) {
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
const blk_hash_t GENESIS = node_cfgs[0].genesis.dag_genesis_block.getHash();
auto mgr =
std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition,
node_cfgs[0].genesis.dag, trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000);
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state);

DagBlock blkA(GENESIS, 1, {}, {trx_hash_t(2)}, sig_t(1), blk_hash_t(2), addr_t(1));
DagBlock blkB(GENESIS, 1, {}, {trx_hash_t(3), trx_hash_t(4)}, sig_t(1), blk_hash_t(3), addr_t(1));
Expand Down Expand Up @@ -228,9 +228,9 @@ TEST_F(DagTest, dag_expiry) {
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
const blk_hash_t GENESIS = node_cfgs[0].genesis.dag_genesis_block.getHash();
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, false, 0, 3, EXPIRY_LIMIT);
auto mgr = std::make_shared<DagManager>(
node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag,
trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state, false, 0, 3, EXPIRY_LIMIT);

DagBlock blkA(GENESIS, 1, {}, {trx_hash_t(2)}, sig_t(1), blk_hash_t(2), addr_t(1));
DagBlock blkB(GENESIS, 1, {}, {trx_hash_t(3), trx_hash_t(4)}, sig_t(1), blk_hash_t(3), addr_t(1));
Expand Down Expand Up @@ -304,9 +304,9 @@ TEST_F(DagTest, receive_block_in_order) {
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
const blk_hash_t GENESIS = node_cfgs[0].genesis.dag_genesis_block.getHash();
auto mgr =
std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition,
node_cfgs[0].genesis.dag, trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000);
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state);

DagBlock blk1(GENESIS, 1, {}, {}, sig_t(777), blk_hash_t(1), addr_t(15));
DagBlock blk2(blk_hash_t(1), 2, {}, {}, sig_t(777), blk_hash_t(2), addr_t(15));
Expand Down Expand Up @@ -336,9 +336,9 @@ TEST_F(DagTest, compute_epoch_2) {
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
const blk_hash_t GENESIS = node_cfgs[0].genesis.dag_genesis_block.getHash();
auto mgr =
std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition,
node_cfgs[0].genesis.dag, trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000);
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state);

DagBlock blkA(GENESIS, 1, {}, {trx_hash_t(2)}, sig_t(1), blk_hash_t(2), addr_t(1));
DagBlock blkB(GENESIS, 1, {}, {trx_hash_t(3), trx_hash_t(4)}, sig_t(1), blk_hash_t(3), addr_t(1));
Expand Down Expand Up @@ -419,9 +419,9 @@ TEST_F(DagTest, get_latest_pivot_tips) {
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
const blk_hash_t GENESIS = node_cfgs[0].genesis.dag_genesis_block.getHash();
auto mgr =
std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition,
node_cfgs[0].genesis.dag, trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000);
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state);

DagBlock blk2(GENESIS, 1, {}, {}, sig_t(1), blk_hash_t(2), addr_t(15));
DagBlock blk3(blk_hash_t(2), 2, {}, {}, sig_t(1), blk_hash_t(3), addr_t(15));
Expand All @@ -446,9 +446,9 @@ TEST_F(DagTest, initial_pivot) {
auto db_ptr = std::make_shared<DbStorage>(data_dir / "db");
auto trx_mgr = std::make_shared<TransactionManager>(FullNodeConfig(), db_ptr, nullptr, addr_t());
auto pbft_chain = std::make_shared<PbftChain>(addr_t(), db_ptr);
auto mgr =
std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(), node_cfgs[0].genesis.sortition,
node_cfgs[0].genesis.dag, trx_mgr, pbft_chain, nullptr, db_ptr, nullptr, 100000);
auto mgr = std::make_shared<DagManager>(node_cfgs[0].genesis.dag_genesis_block, addr_t(),
node_cfgs[0].genesis.sortition, node_cfgs[0].genesis.dag, trx_mgr, pbft_chain,
nullptr, db_ptr, nullptr, 100000, node_cfgs[0].genesis.state);

auto pt = mgr->getLatestPivotAndTips();

Expand Down
Loading

0 comments on commit b9c995e

Please sign in to comment.