Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: rewards stats passing #2463

Merged
merged 3 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@
"7e4aa664f71de4e9d0b4a6473d796372639bdcde": "0x1027e72f1f12813088000000",
"ee1326fbf7d9322e5ea02c6fe5eb63535fceccd1": "0x52b7d2dcc80cd2e4000000"
},
"hardforks": {
"rewards_distribution_frequency": {
}
},
"gas_price": {
"blocks": 200,
"percentile": 60,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@
}
]
},
"hardforks": {
"rewards_distribution_frequency": {
}
},
"initial_balances": {
"723304d1357a2334fcf902aa3d232f5139080a1b": "0xd53323b7ca3737afbb45000",
"b0800c7af0a6aec0ff8dbe01708bd8e300c6305b": "0x208b1d135e4a8000",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,10 @@
"a903715b57d3bf62e098a6a643c6924d9bdacec4": "0x170a0f5040e50400000",
"5bd47fef8e8dcb6677c2957ecd78b8232354f145": "0x191cf61eb2bec223400"
},
"hardforks": {
"rewards_distribution_frequency": {
}
},
"gas_price": {
"blocks": 200,
"percentile": 60,
Expand Down
7 changes: 1 addition & 6 deletions libraries/common/include/common/range_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <functional>
#include <type_traits>

namespace taraxa::util::range_view {
namespace taraxa::util {

template <typename Element>
struct RangeView {
Expand Down Expand Up @@ -72,9 +72,4 @@ auto make_range_view(Seq const &seq) {
return RangeView<decltype(*seq.begin())>(seq);
}

} // namespace taraxa::util::range_view

namespace taraxa::util {
using range_view::make_range_view;
using range_view::RangeView;
} // namespace taraxa::util
4 changes: 2 additions & 2 deletions libraries/config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set(HEADERS
include/config/dag_config.hpp
include/config/pbft_config.hpp
include/config/state_config.hpp
# include/config/hardfork.hpp
include/config/hardfork.hpp
)

set(SOURCES
Expand All @@ -18,7 +18,7 @@ set(SOURCES
src/dag_config.cpp
src/pbft_config.cpp
src/state_config.cpp
# src/hardfork.cpp
src/hardfork.cpp
)

# Configure file with version
Expand Down
13 changes: 12 additions & 1 deletion libraries/config/include/config/hardfork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@
#include "common/encoding_rlp.hpp"

struct Hardforks {
uint64_t fix_genesis_fork_block = 0;
/*
* @brief key is block number at which change is applied and value is new distribution interval.
* Default distribution frequency is every block
* To change rewards distribution frequency we should add a new element in map below.
* For example {{101, 20}, {201, 10}} means:
* 1. for blocks [1,100] we are distributing rewards every block
* 2. for blocks [101, 200] rewards are distributed every 20 block. On blocks 120, 140, etc.
* 3. for blocks after 201 rewards are distributed every 10 block. On blocks 210, 220, etc.
*/
using RewardsDistributionMap = std::map<uint64_t, uint32_t>;
RewardsDistributionMap rewards_distribution_frequency;

HAS_RLP_FIELDS
};

Expand Down
4 changes: 2 additions & 2 deletions libraries/config/include/config/state_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "common/encoding_rlp.hpp"
#include "common/types.hpp"
#include "common/vrf_wrapper.hpp"
// #include "config/hardfork.hpp"
#include "config/hardfork.hpp"

namespace taraxa::state_api {

Expand Down Expand Up @@ -61,7 +61,7 @@ struct Config {
EVMChainConfig evm_chain_config;
BalanceMap initial_balances;
DPOSConfig dpos;
// Hardforks hardforks;
Hardforks hardforks;

HAS_RLP_FIELDS
};
Expand Down
17 changes: 13 additions & 4 deletions libraries/config/src/hardfork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@

Json::Value enc_json(const Hardforks& obj) {
Json::Value json(Json::objectValue);
json["fix_genesis_fork_block"] = dev::toJS(obj.fix_genesis_fork_block);

auto& rewards = json["rewards_distribution_frequency"];
rewards = Json::objectValue;
for (auto i = obj.rewards_distribution_frequency.begin(); i != obj.rewards_distribution_frequency.end(); ++i) {
rewards[std::to_string(i->first)] = i->second;
}
return json;
}

void dec_json(const Json::Value& json, Hardforks& obj) {
if (auto const& e = json["fix_genesis_fork_block"]) {
obj.fix_genesis_fork_block = dev::getUInt(e);
if (const auto& e = json["rewards_distribution_frequency"]) {
assert(e.isObject());

for (auto itr = e.begin(); itr != e.end(); ++itr) {
obj.rewards_distribution_frequency[itr.key().asUInt64()] = itr->asUInt64();
}
}
}

RLP_FIELDS_DEFINE(Hardforks, fix_genesis_fork_block)
RLP_FIELDS_DEFINE(Hardforks, rewards_distribution_frequency)
4 changes: 2 additions & 2 deletions libraries/config/src/state_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ void dec_json(const Json::Value& /*json*/, uint64_t chain_id, EVMChainConfig& ob
void append_json(Json::Value& json, const Config& obj) {
json["evm_chain_config"] = enc_json(obj.evm_chain_config);
json["initial_balances"] = enc_json(obj.initial_balances);
// json["hardforks"] = enc_json(obj.hardforks);
json["hardforks"] = enc_json(obj.hardforks);
json["dpos"] = enc_json(obj.dpos);
}

void dec_json(const Json::Value& json, Config& obj) {
dec_json(json["evm_chain_config"], json["chain_id"].asUInt(), obj.evm_chain_config);
dec_json(json["initial_balances"], obj.initial_balances);
// dec_json(json["hardforks"], obj.hardforks);
dec_json(json["hardforks"], obj.hardforks);
dec_json(json["dpos"], obj.dpos);
}

Expand Down
6 changes: 6 additions & 0 deletions libraries/core_libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ file(GLOB_RECURSE STORAGE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/storage/*.cpp)
file(GLOB_RECURSE NODE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/node/*.hpp)
file(GLOB_RECURSE NODE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/node/*.cpp)

file(GLOB_RECURSE REWARDS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/rewards/*.hpp)
file(GLOB_RECURSE REWARDS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/rewards/*.cpp)

set(HEADERS
${CONSENSUS_HEADERS}
${NETWORK_HEADERS}
${STORAGE_HEADERS}
${NODE_HEADERS}
${REWARDS_HEADERS}
)

set(SOURCES
Expand All @@ -28,6 +32,7 @@ set(SOURCES
${STORAGE_SOURCES}
${NODE_SOURCES}
${GRAPHQL_GENERATED_SOURCES}
${REWARDS_SOURCES}
)

add_library(core_libs ${SOURCES} ${HEADERS})
Expand All @@ -36,6 +41,7 @@ target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/consensu
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/network/include)
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/node/include)
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/storage/include)
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/rewards/include)
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# GraphQL
target_include_directories(core_libs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/network/graphql/gen)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "common/types.hpp"
#include "final_chain/final_chain.hpp"
#include "final_chain/rewards_stats.hpp"

namespace taraxa::final_chain {
class ContractInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include <functional>

#include "common/range_view.hpp"
#include "final_chain/rewards_stats.hpp"
#include "final_chain/state_api_data.hpp"
#include "rewards/block_stats.hpp"
#include "storage/storage.hpp"

namespace taraxa::state_api {
Expand Down Expand Up @@ -43,9 +43,7 @@ class StateAPI {
StateDescriptor get_last_committed_state_descriptor() const;
const StateTransitionResult& transition_state(const EVMBlock& block,
const util::RangeView<EVMTransaction>& transactions,
const util::RangeView<addr_t>& transactions_validators = {},
const util::RangeView<UncleBlock>& uncles = {},
const RewardsStats& rewards_stats = {});
const std::vector<rewards::BlockStats>& rewards_stats = {});
void transition_state_commit();
void create_snapshot(PbftPeriod period);
void prune(const std::vector<dev::h256>& state_root_to_keep, EthBlockNumber blk_num);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,33 @@
#include "pbft/period_data.hpp"
#include "vote/vote.hpp"

namespace taraxa {
namespace taraxa::rewards {

/**
* @class RewardsStats
* @brief RewardsStats contains rewards statistics for single pbft block
*/
class RewardsStats {
class BlockStats {
public:
// Needed for RLP
BlockStats() = default;
/**
* @brief Process PeriodData and returns vector of validators, who included provided block.transactions as first in
* dag block, e.g. returned validator on position 2 included transaction block.transactions[2] as first in his dag
* block
* @brief setting block_author_, max_votes_weight_ and calls processStats function
*
* @param block
* @param dpos_vote_count - votes count for previous block
* @param committee_size
* @return vector of validators
*/
std::vector<addr_t> processStats(const PeriodData& block, uint64_t dpos_vote_count, uint32_t committee_size);
BlockStats(const PeriodData& block, uint64_t dpos_vote_count, uint32_t committee_size);

HAS_RLP_FIELDS

private:
/**
* @brief Process PeriodData and save stats in class for future serialization. returns
*
* @param block
*/
void processStats(const PeriodData& block);
/**
* @brief In case unique tx_hash is provided, it is mapped to it's validator's address + validator's unique txs count
* is incremented. If provided tx_hash was already processed, nothing happens
Expand All @@ -56,16 +60,7 @@ class RewardsStats {
*/
bool addVote(const std::shared_ptr<Vote>& vote);

/**
* @brief Prepares reward statistics bases on period data data
*
* @param sync_blk
* @param dpos_vote_count - votes count for previous block
* @param committee_size
*/
void initStats(const PeriodData& sync_blk, uint64_t dpos_vote_count, uint32_t committee_size);

private:
protected:
struct ValidatorStats {
// count of rewardable(with 1 or more unique transactions) DAG blocks produced by this validator
uint32_t dag_blocks_count_ = 0;
Expand All @@ -76,8 +71,15 @@ class RewardsStats {
HAS_RLP_FIELDS
};

// Pbft block author
addr_t block_author_;

// Transactions validators: tx hash -> validator that included it as first in his block
std::unordered_map<trx_hash_t, addr_t> txs_validators_;
std::unordered_map<trx_hash_t, addr_t> validator_by_tx_hash_;

// Vector with all transactions validators, who included provided block.transactions as first in dag block,
// e.g. returned validator on position 2 included transaction block.transactions[2] as first in his dag block
std::vector<addr_t> txs_validators_;

// Txs stats: validator -> ValidatorStats
std::unordered_map<addr_t, ValidatorStats> validators_stats_;
Expand All @@ -92,4 +94,4 @@ class RewardsStats {
uint64_t max_votes_weight_{0};
};

} // namespace taraxa
} // namespace taraxa::rewards
54 changes: 54 additions & 0 deletions libraries/core_libs/consensus/include/rewards/rewards_stats.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "config/hardfork.hpp"
#include "rewards/block_stats.hpp"
#include "storage/storage.hpp"

namespace taraxa::rewards {
/*
* @brief class that is managing rewards stats processing and hardforks(intervals changes)
* So intermediate blocks stats are stored in the vector in data(to restore on the node restart)
* and full list of interval stats is returned in the end of interval
*/
class Stats {
public:
Stats(uint32_t committee_size, const Hardforks::RewardsDistributionMap& rdm, std::shared_ptr<DB> db,
std::function<uint64_t(EthBlockNumber)>&& dpos_eligible_total_vote_count);

/*
* @brief processing passed block and returns stats that should be processed at this block
* @param current_blk block to process
* @return vector<BlockStats> that should be processed at current block
*/
std::vector<BlockStats> processStats(const PeriodData& current_blk);

protected:
/*
* @brief load current interval stats from database
*/
void loadFromDb();
/*
* @brief returns rewards distribution frequency for specified period
*/
uint32_t getCurrentDistributionFrequency(uint64_t current_period) const;
/*
* @brief gets all needed data and makes(processes) BlocksStats
* @param current_blk block to process
* @return block statistics needed for rewards distribution
*/
BlockStats getBlockStats(const PeriodData& current_blk);
/*
* @brief saves stats to database to not lose this data in case of node restart
*/
void saveBlockStats(uint64_t number, const BlockStats& stats);
/*
* @brief called on start of new rewards interval. clears blocks_stats_ collection
* and removes all data saved in db column
*/
void clear();

const uint32_t kCommitteeSize;
const Hardforks::RewardsDistributionMap kRewardsDistributionFrequency;
std::shared_ptr<DB> db_;
const std::function<uint64_t(EthBlockNumber)> dpos_eligible_total_vote_count_;
std::vector<BlockStats> blocks_stats_;
};
} // namespace taraxa::rewards
Loading