Skip to content

Commit

Permalink
feat: save delayed state_root_hash in pbft block
Browse files Browse the repository at this point in the history
  • Loading branch information
kstdl committed Dec 6, 2022
1 parent 4acb9f8 commit 59c4465
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"number_of_proposers": "0x14",
"dag_blocks_size": "0x32",
"ghost_path_move_back": "0x0",
"state_root_recording_delay": "0x3",
"lambda_ms": "0x5DC",
"gas_limit": "0x3938700"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
"number_of_proposers": "0x14",
"dag_blocks_size": "0x32",
"ghost_path_move_back": "0x0",
"state_root_recording_delay": "0x3",
"lambda_ms": "0x5DC",
"gas_limit": "0x7d2b7500"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@
"number_of_proposers": "0x14",
"dag_blocks_size": "0x32",
"ghost_path_move_back": "0x0",
"state_root_recording_delay": "0x3",
"lambda_ms": "0x5DC",
"gas_limit": "0x7d2b7500"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"number_of_proposers": "0x14",
"dag_blocks_size": "0x32",
"ghost_path_move_back": "0x0",
"state_root_recording_delay": "0x3",
"lambda_ms": "0x5DC",
"gas_limit": "0x7d2b7500"
},
Expand Down
1 change: 1 addition & 0 deletions libraries/config/include/config/pbft_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct PbftConfig {
uint32_t number_of_proposers = 20;
uint32_t dag_blocks_size = 0;
uint32_t ghost_path_move_back = 0;
uint32_t state_root_recording_delay = 3;
uint64_t gas_limit = 0;

bytes rlp() const;
Expand Down
3 changes: 3 additions & 0 deletions libraries/config/src/pbft_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Json::Value enc_json(PbftConfig const& obj) {
ret["number_of_proposers"] = dev::toJS(obj.number_of_proposers);
ret["dag_blocks_size"] = dev::toJS(obj.dag_blocks_size);
ret["ghost_path_move_back"] = dev::toJS(obj.ghost_path_move_back);
ret["state_root_recording_delay"] = dev::toJS(obj.state_root_recording_delay);
ret["gas_limit"] = dev::toJS(obj.gas_limit);
return ret;
}
Expand All @@ -22,6 +23,7 @@ void dec_json(Json::Value const& json, PbftConfig& obj) {
obj.number_of_proposers = dev::jsToInt(json["number_of_proposers"].asString());
obj.dag_blocks_size = dev::jsToInt(json["dag_blocks_size"].asString());
obj.ghost_path_move_back = dev::jsToInt(json["ghost_path_move_back"].asString());
obj.state_root_recording_delay = dev::jsToInt(json["state_root_recording_delay"].asString());
obj.gas_limit = dev::getUInt(json["gas_limit"]);
}

Expand All @@ -34,6 +36,7 @@ bytes PbftConfig::rlp() const {
s << number_of_proposers;
s << dag_blocks_size;
s << ghost_path_move_back;
s << state_root_recording_delay;
s << gas_limit;

return s.out();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ class PbftManager : public std::enable_shared_from_this<PbftManager> {
* @brief Identify a leader block from all received proposed PBFT blocks for the current round by using minimum
* Verifiable Random Function (VRF) output. In filter state, don’t need check vote value correction.
* @param round current pbft round
* @param period new pbft period (perriod == chain_size + 1)
* @param period new pbft period (period == chain_size + 1)
* @return shared_ptr to leader identified leader block
*/
// TODO: exchange round <-> period
Expand Down
20 changes: 10 additions & 10 deletions libraries/core_libs/consensus/src/final_chain/final_chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FinalChainImpl final : public FinalChain {
StateAPI state_api_;

// It is not prepared to use more then 1 thread. Examine it if you want to change threads count
util::ThreadPool executor_thread_{1};
boost::asio::thread_pool executor_thread_{1};

std::atomic<uint64_t> num_executed_dag_blk_ = 0;
std::atomic<uint64_t> num_executed_trx_ = 0;
Expand Down Expand Up @@ -60,7 +60,6 @@ class FinalChainImpl final : public FinalChain {
[this](uint64_t blk) { return get_transaction_hashes(blk); }),
accounts_cache_(config.final_chain_cache_in_blocks,
[this](uint64_t blk, const addr_t& addr) { return state_api_.get_account(blk, addr); }),

total_vote_count_cache_(config.final_chain_cache_in_blocks,
[this](uint64_t blk) { return state_api_.dpos_eligible_total_vote_count(blk); }),
dpos_vote_count_cache_(
Expand Down Expand Up @@ -115,24 +114,25 @@ class FinalChainImpl final : public FinalChain {
delegation_delay_ = config.genesis.state.dpos.delegation_delay;
}

void stop() override { executor_thread_.stop(); }
void stop() override { executor_thread_.join(); }

std::future<std::shared_ptr<FinalizationResult const>> finalize(PeriodData&& new_blk,
std::future<std::shared_ptr<const FinalizationResult>> finalize(PeriodData&& new_blk,
std::vector<h256>&& finalized_dag_blk_hashes,
finalize_precommit_ext precommit_ext = {}) override {
auto p = std::make_shared<std::promise<std::shared_ptr<FinalizationResult const>>>();
executor_thread_.post([this, new_blk = std::move(new_blk),
finalized_dag_blk_hashes = std::move(finalized_dag_blk_hashes),
precommit_ext = std::move(precommit_ext), p]() mutable {
auto p = std::make_shared<std::promise<std::shared_ptr<const FinalizationResult>>>();
boost::asio::post(executor_thread_, [this, new_blk = std::move(new_blk),
finalized_dag_blk_hashes = std::move(finalized_dag_blk_hashes),
precommit_ext = std::move(precommit_ext), p]() mutable {
p->set_value(finalize_(std::move(new_blk), std::move(finalized_dag_blk_hashes), precommit_ext));
});
return p->get_future();
}

EthBlockNumber delegation_delay() const override { return delegation_delay_; }

std::shared_ptr<FinalizationResult> finalize_(PeriodData&& new_blk, std::vector<h256>&& finalized_dag_blk_hashes,
finalize_precommit_ext const& precommit_ext) {
std::shared_ptr<const FinalizationResult> finalize_(PeriodData&& new_blk,
std::vector<h256>&& finalized_dag_blk_hashes,
finalize_precommit_ext const& precommit_ext) {
auto batch = db_->createWriteBatch();

RewardsStats rewards_stats;
Expand Down
28 changes: 23 additions & 5 deletions libraries/core_libs/consensus/src/pbft/pbft_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1175,15 +1175,19 @@ std::shared_ptr<PbftBlock> PbftManager::generatePbftBlock(PbftPeriod propose_per
std::vector<vote_hash_t> reward_votes_hashes;
std::transform(reward_votes.begin(), reward_votes.end(), std::back_inserter(reward_votes_hashes),
[](const auto &v) { return v->getHash(); });
return std::make_shared<PbftBlock>(prev_blk_hash, anchor_hash, order_hash, propose_period, node_addr_, node_sk_,
std::move(reward_votes_hashes));
h256 last_state_root;
if (propose_period > config_.state_root_recording_delay) {
last_state_root = final_chain_->block_header(propose_period - config_.state_root_recording_delay)->state_root;
}
return std::make_shared<PbftBlock>(prev_blk_hash, anchor_hash, order_hash, last_state_root, propose_period,
node_addr_, node_sk_, std::move(reward_votes_hashes));
}

std::shared_ptr<Vote> PbftManager::generateVote(const blk_hash_t &blockhash, PbftVoteTypes type, PbftPeriod period,
std::shared_ptr<Vote> PbftManager::generateVote(const blk_hash_t &block_hash, PbftVoteTypes type, PbftPeriod period,
PbftRound round, PbftStep step) {
// sortition proof
VrfPbftSortition vrf_sortition(vrf_sk_, {type, period, round, step});
return std::make_shared<Vote>(node_sk_, std::move(vrf_sortition), blockhash);
return std::make_shared<Vote>(node_sk_, std::move(vrf_sortition), block_hash);
}

std::pair<bool, std::string> PbftManager::validateVote(const std::shared_ptr<Vote> &vote) const {
Expand Down Expand Up @@ -1560,6 +1564,20 @@ bool PbftManager::validatePbftBlock(const std::shared_ptr<PbftBlock> &pbft_block

auto const &pbft_block_hash = pbft_block->getBlockHash();

auto period = pbft_block->getPeriod();

{
h256 prev_state_root_hash;
if (period > config_.state_root_recording_delay) {
prev_state_root_hash = final_chain_->block_header(period - config_.state_root_recording_delay)->state_root;
}
if (pbft_block->getPrevStateRoot() != prev_state_root_hash) {
LOG(log_er_) << "Block " << pbft_block_hash << " state root " << pbft_block->getPrevStateRoot()
<< " isn't matching actual " << prev_state_root_hash;
return false;
}
}

// Vadliates reward votes
if (!vote_mgr_->checkRewardVotes(pbft_block)) {
LOG(log_er_) << "Failed verifying reward votes for proposed PBFT block " << pbft_block_hash;
Expand Down Expand Up @@ -1736,7 +1754,7 @@ void PbftManager::finalize_(PeriodData &&period_data, std::vector<h256> &&finali
auto result = final_chain_->finalize(
std::move(period_data), std::move(finalized_dag_blk_hashes),
[this, weak_ptr = weak_from_this(), anchor_hash = anchor, period = period_data.pbft_blk->getPeriod()](
auto const &, auto &batch) {
const auto &, auto &batch) {
// Update proposal period DAG levels map
auto ptr = weak_ptr.lock();
if (!ptr) return; // it was destroyed
Expand Down
6 changes: 5 additions & 1 deletion libraries/types/pbft_block/include/pbft/pbft_block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PbftBlock {
blk_hash_t prev_block_hash_;
blk_hash_t dag_block_hash_as_pivot_;
blk_hash_t order_hash_;
blk_hash_t prev_state_root_hash_;
PbftPeriod period_; // Block index, PBFT head block is period 0, first PBFT block is period 1
uint64_t timestamp_;
addr_t beneficiary_;
Expand All @@ -33,7 +34,8 @@ class PbftBlock {

public:
PbftBlock(const blk_hash_t& prev_blk_hash, const blk_hash_t& dag_blk_hash_as_pivot, const blk_hash_t& order_hash,
PbftPeriod period, const addr_t& beneficiary, const secret_t& sk, std::vector<vote_hash_t>&& reward_votes_);
const blk_hash_t& prev_state_root, PbftPeriod period, const addr_t& beneficiary, const secret_t& sk,
std::vector<vote_hash_t>&& reward_votes);
explicit PbftBlock(dev::RLP const& rlp);
explicit PbftBlock(bytes const& RLP);

Expand Down Expand Up @@ -102,6 +104,8 @@ class PbftBlock {
*/
auto const& getOrderHash() const { return order_hash_; }

auto const& getPrevStateRoot() const { return prev_state_root_hash_; }

/**
* @brief Get period number
* @return period number
Expand Down
13 changes: 8 additions & 5 deletions libraries/types/pbft_block/src/pbft_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ namespace taraxa {
PbftBlock::PbftBlock(bytes const& b) : PbftBlock(dev::RLP(b)) {}

PbftBlock::PbftBlock(dev::RLP const& rlp) {
util::rlp_tuple(util::RLPDecoderRef(rlp, true), prev_block_hash_, dag_block_hash_as_pivot_, order_hash_, period_,
timestamp_, reward_votes_, signature_);
util::rlp_tuple(util::RLPDecoderRef(rlp, true), prev_block_hash_, dag_block_hash_as_pivot_, order_hash_,
prev_state_root_hash_, period_, timestamp_, reward_votes_, signature_);
calculateHash_();
}

PbftBlock::PbftBlock(const blk_hash_t& prev_blk_hash, const blk_hash_t& dag_blk_hash_as_pivot,
const blk_hash_t& order_hash, uint64_t period, const addr_t& beneficiary, const secret_t& sk,
std::vector<vote_hash_t>&& reward_votes)
const blk_hash_t& order_hash, const blk_hash_t& prev_state_root, PbftPeriod period,
const addr_t& beneficiary, const secret_t& sk, std::vector<vote_hash_t>&& reward_votes)
: prev_block_hash_(prev_blk_hash),
dag_block_hash_as_pivot_(dag_blk_hash_as_pivot),
order_hash_(order_hash),
prev_state_root_hash_(prev_state_root),
period_(period),
beneficiary_(beneficiary),
reward_votes_(reward_votes) {
Expand Down Expand Up @@ -61,6 +62,7 @@ Json::Value PbftBlock::getJson() const {
json["prev_block_hash"] = prev_block_hash_.toString();
json["dag_block_hash_as_pivot"] = dag_block_hash_as_pivot_.toString();
json["order_hash"] = order_hash_.toString();
json["prev_state_root_hash"] = prev_state_root_hash_.toString();
json["period"] = (Json::Value::UInt64)period_;
json["timestamp"] = (Json::Value::UInt64)timestamp_;
json["block_hash"] = block_hash_.toString();
Expand All @@ -76,10 +78,11 @@ Json::Value PbftBlock::getJson() const {

// Using to setup PBFT block hash
void PbftBlock::streamRLP(dev::RLPStream& strm, bool include_sig) const {
strm.appendList(include_sig ? 7 : 6);
strm.appendList(include_sig ? 8 : 7);
strm << prev_block_hash_;
strm << dag_block_hash_as_pivot_;
strm << order_hash_;
strm << prev_state_root_hash_;
strm << period_;
strm << timestamp_;
strm.appendVector(reward_votes_);
Expand Down
5 changes: 3 additions & 2 deletions tests/final_chain_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ struct FinalChainTest : WithDataDir {
DagBlock dag_blk({}, {}, {}, trx_hashes, {}, {}, secret_t::random());
db->saveDagBlock(dag_blk);
std::vector<vote_hash_t> reward_votes_hashes;
auto pbft_block = std::make_shared<PbftBlock>(blk_hash_t(), blk_hash_t(), blk_hash_t(), 1, addr_t::random(),
dev::KeyPair::create().secret(), std::move(reward_votes_hashes));
auto pbft_block =
std::make_shared<PbftBlock>(blk_hash_t(), blk_hash_t(), blk_hash_t(), blk_hash_t(), 1, addr_t::random(),
dev::KeyPair::create().secret(), std::move(reward_votes_hashes));
std::vector<std::shared_ptr<Vote>> votes;
PeriodData period_data(pbft_block, votes);
period_data.dag_blocks.push_back(dag_blk);
Expand Down
22 changes: 11 additions & 11 deletions tests/network_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ TEST_F(NetworkTest, DISABLED_update_peer_chainsize) {
auto nw2 = nodes[1]->getNetwork();

std::vector<vote_hash_t> reward_votes{};
auto pbft_block =
std::make_shared<PbftBlock>(blk_hash_t(1), blk_hash_t(0), blk_hash_t(0), node1->getPbftManager()->getPbftPeriod(),
node1->getAddress(), node1->getSecretKey(), std::move(reward_votes));
auto pbft_block = std::make_shared<PbftBlock>(blk_hash_t(1), blk_hash_t(0), blk_hash_t(0), blk_hash_t(),
node1->getPbftManager()->getPbftPeriod(), node1->getAddress(),
node1->getSecretKey(), std::move(reward_votes));
auto vote =
node1_pbft_mgr->generateVote(pbft_block->getBlockHash(), PbftVoteTypes::propose_vote, pbft_block->getPeriod(),
node1_pbft_mgr->getPbftRound() + 1, value_proposal_state);
Expand Down Expand Up @@ -545,8 +545,8 @@ TEST_F(NetworkTest, node_pbft_sync) {
order_stream.appendList(1);
order_stream << blk1.getHash();

PbftBlock pbft_block1(prev_block_hash, blk1.getHash(), dev::sha3(order_stream.out()), period, beneficiary,
node1->getSecretKey(), {});
PbftBlock pbft_block1(prev_block_hash, blk1.getHash(), dev::sha3(order_stream.out()), blk_hash_t(), period,
beneficiary, node1->getSecretKey(), {});
std::vector<std::shared_ptr<Vote>> votes_for_pbft_blk1;
votes_for_pbft_blk1.emplace_back(
node1->getPbftManager()->generateVote(pbft_block1.getBlockHash(), PbftVoteTypes::cert_vote, 1, 1, 3));
Expand Down Expand Up @@ -601,8 +601,8 @@ TEST_F(NetworkTest, node_pbft_sync) {
dev::RLPStream order_stream2(1);
order_stream2.appendList(1);
order_stream2 << blk2.getHash();
PbftBlock pbft_block2(prev_block_hash, blk2.getHash(), dev::sha3(order_stream2.out()), period, beneficiary,
node1->getSecretKey(), {});
PbftBlock pbft_block2(prev_block_hash, blk2.getHash(), dev::sha3(order_stream2.out()), blk_hash_t(), period,
beneficiary, node1->getSecretKey(), {});
std::vector<std::shared_ptr<Vote>> votes_for_pbft_blk2;
votes_for_pbft_blk2.emplace_back(
node1->getPbftManager()->generateVote(pbft_block2.getBlockHash(), PbftVoteTypes::cert_vote, 2, 2, 3));
Expand Down Expand Up @@ -711,8 +711,8 @@ TEST_F(NetworkTest, node_pbft_sync_without_enough_votes) {
order_stream.appendList(1);
order_stream << blk1.getHash();

PbftBlock pbft_block1(prev_block_hash, blk1.getHash(), dev::sha3(order_stream.out()), period, beneficiary,
node1->getSecretKey(), {});
PbftBlock pbft_block1(prev_block_hash, blk1.getHash(), dev::sha3(order_stream.out()), blk_hash_t(), period,
beneficiary, node1->getSecretKey(), {});
std::vector<std::shared_ptr<Vote>> votes_for_pbft_blk1;
votes_for_pbft_blk1.emplace_back(
node1->getPbftManager()->generateVote(pbft_block1.getBlockHash(), PbftVoteTypes::cert_vote, 1, 1, 3));
Expand Down Expand Up @@ -759,8 +759,8 @@ TEST_F(NetworkTest, node_pbft_sync_without_enough_votes) {
order_stream2.appendList(1);
order_stream2 << blk2.getHash();

PbftBlock pbft_block2(prev_block_hash, blk2.getHash(), dev::sha3(order_stream2.out()), period, beneficiary,
node1->getSecretKey(), {});
PbftBlock pbft_block2(prev_block_hash, blk2.getHash(), dev::sha3(order_stream2.out()), blk_hash_t(), period,
beneficiary, node1->getSecretKey(), {});
std::cout << "Use fake votes for the second PBFT block" << std::endl;
// node1 put block2 into pbft chain and use fake votes storing into DB (malicious player)
// Add fake votes in DB
Expand Down
6 changes: 4 additions & 2 deletions tests/pbft_chain_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ TEST_F(PbftChainTest, serialize_desiriablize_pbft_block) {
blk_hash_t dag_block_hash_as_pivot(45678);
PbftPeriod period = 1;
addr_t beneficiary(98765);
PbftBlock pbft_block1(prev_block_hash, dag_block_hash_as_pivot, blk_hash_t(), period, beneficiary, sk, {});
PbftBlock pbft_block1(prev_block_hash, dag_block_hash_as_pivot, blk_hash_t(), blk_hash_t(), period, beneficiary, sk,
{});

auto rlp = pbft_block1.rlp(true);
PbftBlock pbft_block2(rlp);
Expand Down Expand Up @@ -56,7 +57,8 @@ TEST_F(PbftChainTest, pbft_db_test) {

PbftPeriod period = 1;
addr_t beneficiary(987);
PbftBlock pbft_block(prev_block_hash, blk1.getHash(), blk_hash_t(), period, beneficiary, node->getSecretKey(), {});
PbftBlock pbft_block(prev_block_hash, blk1.getHash(), blk_hash_t(), blk_hash_t(), period, beneficiary,
node->getSecretKey(), {});

// put into pbft chain and store into DB
auto batch = db->createWriteBatch();
Expand Down
8 changes: 4 additions & 4 deletions tests/pbft_manager_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ TEST_F(PbftManagerTest, propose_block_and_vote_broadcast) {
std::vector<vote_hash_t> reward_votes_hashes;
std::transform(reward_votes.begin(), reward_votes.end(), std::back_inserter(reward_votes_hashes),
[](const auto &v) { return v->getHash(); });
auto proposed_pbft_block = std::make_shared<PbftBlock>(prev_block_hash, blk_hash_t(0), blk_hash_t(0),
auto proposed_pbft_block = std::make_shared<PbftBlock>(prev_block_hash, blk_hash_t(0), blk_hash_t(0), blk_hash_t(0),
node1->getPbftManager()->getPbftPeriod(), node1->getAddress(),
node1->getSecretKey(), std::move(reward_votes_hashes));
auto propose_vote = pbft_mgr1->generateVote(proposed_pbft_block->getBlockHash(), PbftVoteTypes::propose_vote,
Expand Down Expand Up @@ -913,8 +913,8 @@ TEST_F(PbftManagerWithDagCreation, DISABLED_pbft_block_is_overweighted) {
std::transform(reward_votes.begin(), reward_votes.end(), std::back_inserter(reward_votes_hashes),
[](const auto &v) { return v->getHash(); });
const auto pbft_block =
std::make_shared<PbftBlock>(last_hash, dag_block_hash, order_hash, propose_period, node->getAddress(),
node->getSecretKey(), std::move(reward_votes_hashes));
std::make_shared<PbftBlock>(last_hash, dag_block_hash, order_hash, blk_hash_t(), propose_period,
node->getAddress(), node->getSecretKey(), std::move(reward_votes_hashes));
// node->getPbftChain()->pushUnverifiedPbftBlock(pbft_block);
}

Expand All @@ -932,7 +932,7 @@ TEST_F(PbftManagerWithDagCreation, proposed_blocks) {
// Create blocks
for (uint32_t i = 1; i <= block_count; i++) {
std::vector<vote_hash_t> reward_votes_hashes;
auto block = std::make_shared<PbftBlock>(blk_hash_t(1), blk_hash_t(0), blk_hash_t(0), 2, addr_t(),
auto block = std::make_shared<PbftBlock>(blk_hash_t(1), blk_hash_t(0), blk_hash_t(0), blk_hash_t(0), 2, addr_t(),
dev::KeyPair::create().secret(), std::move(reward_votes_hashes));
blocks.insert({block->getBlockHash(), block});
}
Expand Down
Loading

0 comments on commit 59c4465

Please sign in to comment.