Skip to content
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
75 changes: 52 additions & 23 deletions core/network/beefy/beefy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ namespace kagome::network {
scale::decode<consensus::beefy::BeefyJustification>(raw.data));
auto &justification =
boost::get<consensus::beefy::SignedCommitment>(justification_v1);
if (justification.commitment.block_number == beefy_finalized_) {
return outcome::success();
}
OUTCOME_TRY(header, block_tree_->getBlockHeader(block_hash));
if (justification.commitment.block_number != header.number) {
return outcome::success();
Expand All @@ -120,6 +123,9 @@ namespace kagome::network {
boost::get<consensus::beefy::BeefyJustification>(&message)) {
auto &justification =
boost::get<consensus::beefy::SignedCommitment>(*justification_v1);
if (justification.commitment.block_number == beefy_finalized_) {
return;
}
if (justification.commitment.block_number
> block_tree_->bestBlock().number) {
return;
Expand Down Expand Up @@ -147,7 +153,8 @@ namespace kagome::network {
if (next_session == sessions_.begin()) {
return;
}
auto &session = std::prev(next_session)->second;
auto session_it = std::prev(next_session);
auto &session = session_it->second;
if (vote.commitment.validator_set_id != session.validators.id) {
SL_VERBOSE(log_, "wrong validator set id for block {}", block_number);
return;
Expand All @@ -157,12 +164,28 @@ namespace kagome::network {
SL_VERBOSE(log_, "unknown validator for block {}", block_number);
return;
}
auto total = session.validators.validators.size();
auto round = session.rounds.find(block_number);
if (round != session.rounds.end() and round->second.signatures[*index]) {
return;
}
if (not verify(*ecdsa_, vote)) {
SL_VERBOSE(log_, "wrong vote for block {}", block_number);
return;
}
auto total = session.validators.validators.size();
auto round = session.rounds.find(block_number);
auto commitment_ok = false;
if (round != session.rounds.end()) {
commitment_ok = vote.commitment == round->second.commitment;
} else if (auto r = getCommitment(session.validators.id, block_number);
not r or not r.value()) {
return;
Comment thread
turuslan marked this conversation as resolved.
} else {
commitment_ok = vote.commitment == *r.value();
}
if (not commitment_ok) {
SL_WARN(log_, "unexpected commitment for block {}", block_number);
return;
}
if (round == session.rounds.end()) {
round =
session.rounds
Expand All @@ -171,9 +194,6 @@ namespace kagome::network {
.first;
round->second.signatures.resize(total);
}
if (round->second.signatures[*index]) {
return;
}
round->second.signatures[*index] = vote.signature;
size_t count = 0;
for (auto &sig : round->second.signatures) {
Expand Down Expand Up @@ -411,31 +431,40 @@ namespace kagome::network {
session->second.validators.id);
return outcome::success();
}
OUTCOME_TRY(block_hash, block_tree_->getBlockHash(target));
if (not block_hash) {
SL_VERBOSE(log_, "can't vote: no block {}", target);
OUTCOME_TRY(commitment,
getCommitment(session->second.validators.id, target));
if (not commitment) {
SL_VERBOSE(log_, "can't vote: no commitment {}", target);
return outcome::success();
}
OUTCOME_TRY(sig,
ecdsa_->signPrehashed(consensus::beefy::prehash(*commitment),
key->first->secret_key));
onVote({std::move(*commitment), key->first->public_key, sig}, true);
last_voted_ = target;
return outcome::success();
}

outcome::result<std::optional<consensus::beefy::Commitment>>
Beefy::getCommitment(consensus::beefy::AuthoritySetId validator_set_id,
primitives::BlockNumber block_number) {
OUTCOME_TRY(block_hash, block_tree_->getBlockHash(block_number));
if (not block_hash) {
SL_VERBOSE(log_, "getCommitment: no block {}", block_number);
return std::nullopt;
}
OUTCOME_TRY(header, block_tree_->getBlockHeader(*block_hash));
auto mmr = beefyMmrDigest(header);
if (not mmr) {
SL_VERBOSE(log_, "can't vote: no mmr digest in block {}", target);
return outcome::success();
SL_VERBOSE(
log_, "getCommitment: no mmr digest in block {}", block_number);
return std::nullopt;
}
consensus::beefy::VoteMessage vote;
vote.commitment = {
return consensus::beefy::Commitment{
{{consensus::beefy::kMmr, common::Buffer{*mmr}}},
target,
session->second.validators.id,
block_number,
validator_set_id,
};
vote.id = key->first->public_key;
BOOST_OUTCOME_TRY(
vote.signature,
ecdsa_->signPrehashed(consensus::beefy::prehash(vote.commitment),
key->first->secret_key));
onVote(std::move(vote), true);
last_voted_ = target;
return outcome::success();
}

void Beefy::metricValidatorSetId() {
Expand Down
3 changes: 3 additions & 0 deletions core/network/beefy/beefy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ namespace kagome::network {
consensus::beefy::SignedCommitment justification, bool broadcast);
outcome::result<void> update();
outcome::result<void> vote();
outcome::result<std::optional<consensus::beefy::Commitment>> getCommitment(
consensus::beefy::AuthoritySetId validator_set_id,
primitives::BlockNumber block_number);
void metricValidatorSetId();

std::shared_ptr<blockchain::BlockTree> block_tree_;
Expand Down