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

stop pbft chain progress and trigger pillar votes syncing if < 2t+1 … #2699

Merged
merged 1 commit into from
Feb 20, 2024
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 @@ -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
Loading