Skip to content

Commit

Permalink
Merge pull request #2699 from Taraxa-project/issue-2693/pillar_votes_…
Browse files Browse the repository at this point in the history
…syncing

stop pbft chain progress and trigger  pillar votes syncing if < 2t+1 …
  • Loading branch information
JakubFornadel authored Feb 20, 2024
2 parents 57e719a + af35103 commit 9e110d4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ class PillarChainManager {
std::vector<std::shared_ptr<PillarVote>> getVerifiedPillarVotes(PbftPeriod period,
const PillarBlock::Hash pillar_block_hash) const;

/**
* @brief Check if there is 2t+1 pillar votes for a combination of period & block_hash
*
* @param period
* @param block_hash
* @return true if there is 2t+1 pillar votes for a combination of period & block_hash
*/
bool hasTwoTPlusOneVotes(PbftPeriod period, const blk_hash_t& block_hash) const;

/**
* @return period of the latest finalized pillar block
*/
Expand Down
41 changes: 38 additions & 3 deletions libraries/core_libs/consensus/src/pbft/pbft_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1423,13 +1423,48 @@ bool PbftManager::validatePbftBlock(const std::shared_ptr<PbftBlock> &pbft_block
}
}

const auto kBlockPeriod = pbft_block->getPeriod();

// Check if we have pillar votes for current pillar block
if (kBlockPeriod >= 2 * kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods &&
kBlockPeriod % kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods == 0) {
const auto current_pillar_block = pillar_chain_mgr_->getCurrentPillarBlock();
if (!current_pillar_block) {
// This should never happen
LOG(log_er_) << "Unable to validate pbft block " << pbft_block_hash << ", period " << kBlockPeriod << ". No previous pillar block saved";
assert(false);
return false;
}

if (kBlockPeriod != current_pillar_block->getPeriod() + kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods) {
LOG(log_er_) << "Unable to validate pbft block " << pbft_block_hash << ", period " << kBlockPeriod << ". Previous pillar block period " << current_pillar_block->getPeriod();
assert(false);
return false;
}

// Check if there is 2t+1 pillar votes for current pillar block
if (!pillar_chain_mgr_->hasTwoTPlusOneVotes(current_pillar_block->getPeriod(), current_pillar_block->getHash())) {
LOG(log_er_) << "Unable to validate pbft block " << pbft_block_hash << ", period " << kBlockPeriod << ". There is < 2t+1 pillar votes for current pillar block " << current_pillar_block->getHash();

if (auto net = network_.lock(); net) {
LOG(log_nf_) << "Request pillar votes for block " << current_pillar_block->getHash() << ", period " << current_pillar_block->getPeriod();
net->requestPillarBlockVotesBundle(current_pillar_block->getPeriod(), current_pillar_block->getHash());
} else {
LOG(log_er_) << "validatePbftBlock: Failed to obtain net !";
}

return false;
}
}

// Validate optional pillar block hash
if (const auto pillar_block_hash = pbft_block->getPillarBlockHash();
pbft_block->getPeriod() >= kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods &&
pbft_block->getPeriod() % kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods ==
kBlockPeriod >= kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods &&
kBlockPeriod % kGenesisConfig.state.hardforks.ficus_hf.pillar_block_periods ==
kGenesisConfig.state.dpos.delegation_delay) {
if (!pillar_block_hash.has_value()) {
LOG(log_er_) << "PBFT block " << pbft_block_hash << " does not contain pillar block hash, period "
<< pbft_block->getPeriod();
<< kBlockPeriod;
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void PillarChainManager::createPillarBlock(const std::shared_ptr<final_chain::Fi
pillar_votes_.getVerifiedVotes(current_pillar_block_->getPeriod(), current_pillar_block_->getHash(), true);
if (two_t_plus_one_votes.empty()) {
LOG(log_er_) << "There is < 2t+1 votes for current pillar block " << current_pillar_block_->getHash()
<< ", period: " << current_pillar_block_->getPeriod();
<< ", period: " << current_pillar_block_->getPeriod() << ". Current period " << block_num;
return;
}

Expand Down Expand Up @@ -325,6 +325,10 @@ std::vector<std::shared_ptr<PillarVote>> PillarChainManager::getVerifiedPillarVo
return pillar_votes_.getVerifiedVotes(period, pillar_block_hash);
}

bool PillarChainManager::hasTwoTPlusOneVotes(PbftPeriod period, const blk_hash_t& block_hash) const {
return pillar_votes_.hasTwoTPlusOneVotes(period, block_hash);
}

std::optional<PbftPeriod> PillarChainManager::getLastFinalizedPillarBlockPeriod() const {
std::shared_lock<std::shared_mutex> lock(mutex_);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void PbftSyncPacketHandler::validatePacketRlpFormat(const threadpool::PacketData

// PeriodData rlp parsing cannot be done through util::rlp_tuple, which automatically checks the rlp size so it is
// checked here manually
if (packet_data.rlp_[1].itemCount() != PeriodData::kBaseRlpItemCount) {
if (packet_data.rlp_[1].itemCount() != PeriodData::kBaseRlpItemCount && packet_data.rlp_[1].itemCount() != PeriodData::kBaseRlpItemCount + 1) {
throw InvalidRlpItemsCountException(packet_data.type_str_ + ":PeriodData", packet_data.rlp_[1].itemCount(),
PeriodData::kBaseRlpItemCount);
}
Expand Down

0 comments on commit 9e110d4

Please sign in to comment.