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: block validation #1873

Merged
merged 3 commits into from
Nov 21, 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ You will also be able to see your node on https://telemetry.polkadot.io/. If you
Run `kagome --help` to explore other CLI flags.


#### Execute KAGOME validating node in development mode
#### Execute KAGOME block_validator node in development mode

The easiest way to get started with KAGOME is to run it in development mode, which is a single node network:

Expand Down
6 changes: 2 additions & 4 deletions core/consensus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ add_subdirectory(timeline)
add_subdirectory(babe)
add_subdirectory(grandpa)

add_library(consensus
validation/babe_block_validator.cpp
)
target_link_libraries(consensus
add_library(consensus INTERFACE)
target_link_libraries(consensus INTERFACE
timeline
babe
grandpa
Expand Down
2 changes: 1 addition & 1 deletion core/consensus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ This folder contains implementations for BABE and GRANDPA consensus in Kagome.
* [authority](authority) – authority manager implementations. Needed to keep track of grandpa authorities updates
* [babe](babe) - BABE block production algorithm implementation
* [grandpa](grandpa) – GRANDPA block finalization algorithm implementation
* [validation](validation) – contains logic for validating incoming blocks
* [validation](validation) – contains logic for block_validator incoming blocks
1 change: 1 addition & 0 deletions core/consensus/babe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library(babe
impl/babe.cpp
impl/threshold_util.cpp
impl/babe_lottery_impl.cpp
impl/babe_block_validator_impl.cpp
impl/babe_config_repository_impl.cpp
)
target_link_libraries(babe
Expand Down
21 changes: 21 additions & 0 deletions core/consensus/babe/babe_block_validator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "primitives/block.hpp"

namespace kagome::consensus::babe {

class BabeBlockValidator {
public:
virtual ~BabeBlockValidator() = default;

virtual outcome::result<void> validateHeader(
const primitives::BlockHeader &header) const = 0;
};

} // namespace kagome::consensus::babe
9 changes: 9 additions & 0 deletions core/consensus/babe/impl/babe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "blockchain/block_tree.hpp"
#include "consensus/babe/babe_config_repository.hpp"
#include "consensus/babe/babe_lottery.hpp"
#include "consensus/babe/impl/babe_block_validator_impl.hpp"
#include "consensus/babe/impl/babe_digests_util.hpp"
#include "consensus/block_production_error.hpp"
#include "consensus/timeline/backoff.hpp"
Expand Down Expand Up @@ -70,6 +71,7 @@ namespace kagome::consensus::babe {
std::shared_ptr<BabeLottery> lottery,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider,
std::shared_ptr<BabeBlockValidator> validating,
std::shared_ptr<parachain::BitfieldStore> bitfield_store,
std::shared_ptr<parachain::BackingStore> backing_store,
std::shared_ptr<dispute::DisputeCoordinator> dispute_coordinator,
Expand All @@ -90,6 +92,7 @@ namespace kagome::consensus::babe {
lottery_(std::move(lottery)),
hasher_(std::move(hasher)),
sr25519_provider_(std::move(sr25519_provider)),
validating_(std::move(validating)),
bitfield_store_(std::move(bitfield_store)),
backing_store_(std::move(backing_store)),
dispute_coordinator_(std::move(dispute_coordinator)),
Expand All @@ -108,6 +111,7 @@ namespace kagome::consensus::babe {
BOOST_ASSERT(lottery_);
BOOST_ASSERT(hasher_);
BOOST_ASSERT(sr25519_provider_);
BOOST_ASSERT(validating_);
BOOST_ASSERT(bitfield_store_);
BOOST_ASSERT(backing_store_);
BOOST_ASSERT(dispute_coordinator_);
Expand Down Expand Up @@ -213,6 +217,11 @@ namespace kagome::consensus::babe {
return processSlotLeadership();
}

outcome::result<void> Babe::validateHeader(
const primitives::BlockHeader &block_header) const {
return validating_->validateHeader(block_header);
}

bool Babe::changeEpoch(EpochNumber epoch,
const primitives::BlockInfo &block) const {
return lottery_->changeEpoch(epoch, block);
Expand Down
6 changes: 6 additions & 0 deletions core/consensus/babe/impl/babe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace kagome::consensus {

namespace kagome::consensus::babe {
class BabeConfigRepository;
class BabeBlockValidator;
class BabeLottery;
} // namespace kagome::consensus::babe

Expand Down Expand Up @@ -99,6 +100,7 @@ namespace kagome::consensus::babe {
std::shared_ptr<BabeLottery> lottery,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider,
std::shared_ptr<BabeBlockValidator> validating,
std::shared_ptr<parachain::BitfieldStore> bitfield_store,
std::shared_ptr<parachain::BackingStore> backing_store,
std::shared_ptr<dispute::DisputeCoordinator> dispute_coordinator,
Expand All @@ -121,6 +123,9 @@ namespace kagome::consensus::babe {
outcome::result<void> processSlot(
SlotNumber slot, const primitives::BlockInfo &best_block) override;

outcome::result<void> validateHeader(
const primitives::BlockHeader &block_header) const override;

private:
bool changeEpoch(EpochNumber epoch,
const primitives::BlockInfo &block) const override;
Expand Down Expand Up @@ -153,6 +158,7 @@ namespace kagome::consensus::babe {
std::shared_ptr<BabeLottery> lottery_;
std::shared_ptr<crypto::Hasher> hasher_;
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider_;
std::shared_ptr<BabeBlockValidator> validating_;
std::shared_ptr<parachain::BitfieldStore> bitfield_store_;
std::shared_ptr<parachain::BackingStore> backing_store_;
std::shared_ptr<dispute::DisputeCoordinator> dispute_coordinator_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "consensus/validation/babe_block_validator.hpp"
#include "consensus/babe/impl/babe_block_validator_impl.hpp"

#include <latch>

#include "consensus/babe/babe_config_repository.hpp"
#include "consensus/babe/babe_lottery.hpp"
#include "consensus/babe/impl/babe_digests_util.hpp"
#include "consensus/babe/impl/prepare_transcript.hpp"
#include "consensus/babe/types/seal.hpp"
#include "consensus/timeline/impl/slot_leadership_error.hpp"
#include "consensus/timeline/slots_util.hpp"
#include "crypto/sr25519_provider.hpp"
#include "crypto/vrf_provider.hpp"
#include "metrics/histogram_timer.hpp"
#include "prepare_transcript.hpp"
#include "primitives/inherent_data.hpp"
#include "primitives/transcript.hpp"
#include "runtime/runtime_api/offchain_worker_api.hpp"
#include "storage/trie/serialization/ordered_trie_hash.hpp"
#include "threshold_util.hpp"

OUTCOME_CPP_DEFINE_CATEGORY(kagome::consensus::babe,
BabeBlockValidator::ValidationError,
BabeBlockValidatorImpl::ValidationError,
e) {
using E = kagome::consensus::babe::BabeBlockValidator::ValidationError;
using E = kagome::consensus::babe::BabeBlockValidatorImpl::ValidationError;
switch (e) {
case E::NO_AUTHORITIES:
return "no authorities are provided for the validation";
Expand All @@ -31,28 +44,71 @@ OUTCOME_CPP_DEFINE_CATEGORY(kagome::consensus::babe,
}

namespace kagome::consensus::babe {
using common::Buffer;

BabeBlockValidator::BabeBlockValidator(
std::shared_ptr<blockchain::BlockTree> block_tree,
std::shared_ptr<runtime::TaggedTransactionQueue> tx_queue,
BabeBlockValidatorImpl::BabeBlockValidatorImpl(
LazySPtr<SlotsUtil> slots_util,
std::shared_ptr<BabeConfigRepository> config_repo,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::VRFProvider> vrf_provider,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider)
: block_tree_{std::move(block_tree)},
tx_queue_{std::move(tx_queue)},
hasher_{std::move(hasher)},
vrf_provider_{std::move(vrf_provider)},
sr25519_provider_{std::move(sr25519_provider)},
log_{log::createLogger("BlockValidator", "block_validator")} {
BOOST_ASSERT(block_tree_);
BOOST_ASSERT(tx_queue_);
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider,
std::shared_ptr<crypto::VRFProvider> vrf_provider)
: log_(log::createLogger("BabeBlockValidatorImpl", "babe")),
slots_util_(std::move(slots_util)),
config_repo_(std::move(config_repo)),
hasher_(std::move(hasher)),
sr25519_provider_(std::move(sr25519_provider)),
vrf_provider_(std::move(vrf_provider)) {
BOOST_ASSERT(config_repo_);
BOOST_ASSERT(hasher_);
BOOST_ASSERT(vrf_provider_);
BOOST_ASSERT(sr25519_provider_);
BOOST_ASSERT(vrf_provider_);
}

outcome::result<void> BabeBlockValidatorImpl::validateHeader(
const primitives::BlockHeader &block_header) const {
OUTCOME_TRY(babe_header, babe::getBabeBlockHeader(block_header));

auto slot_number = babe_header.slot_number;

OUTCOME_TRY(epoch_number,
slots_util_.get()->slotToEpoch(*block_header.parentInfo(),
slot_number));

SL_VERBOSE(
log_,
"Appending header of block {} ({} in slot {}, epoch {}, authority #{})",
block_header.blockInfo(),
to_string(babe_header.slotType()),
slot_number,
epoch_number,
babe_header.authority_index);

OUTCOME_TRY(config_ptr,
config_repo_->config(*block_header.parentInfo(), epoch_number));
auto &config = *config_ptr;

SL_TRACE(log_,
"Actual epoch digest to apply block {} (slot {}, epoch {}). "
"Randomness: {}",
block_header.blockInfo(),
slot_number,
epoch_number,
config.randomness);

auto threshold = calculateThreshold(config.leadership_rate,
config.authorities,
babe_header.authority_index);

OUTCOME_TRY(
validateHeader(block_header,
epoch_number,
config.authorities[babe_header.authority_index].id,
threshold,
config));

return outcome::success();
}

outcome::result<void> BabeBlockValidator::validateHeader(
outcome::result<void> BabeBlockValidatorImpl::validateHeader(
const primitives::BlockHeader &header,
const EpochNumber epoch_number,
const AuthorityId &authority_id,
Expand Down Expand Up @@ -90,7 +146,7 @@ namespace kagome::consensus::babe {
OUTCOME_TRY(seal, getSeal(header));

// signature in seal of the header must be valid
if (!verifySignature(header, babe_header, seal, authority_id)) {
if (!verifySignature(header, seal, authority_id)) {
return ValidationError::INVALID_SIGNATURE;
}

Expand All @@ -108,9 +164,8 @@ namespace kagome::consensus::babe {
return outcome::success();
}

bool BabeBlockValidator::verifySignature(
bool BabeBlockValidatorImpl::verifySignature(
const primitives::BlockHeader &header,
const BabeBlockHeader &babe_header,
const Seal &seal,
const AuthorityId &public_key) const {
primitives::UnsealedBlockHeaderReflection unsealed_header(header);
Expand All @@ -125,12 +180,12 @@ namespace kagome::consensus::babe {
return res && res.value();
}

bool BabeBlockValidator::verifyVRF(const BabeBlockHeader &babe_header,
const EpochNumber epoch_number,
const AuthorityId &public_key,
const Threshold &threshold,
const Randomness &randomness,
const bool checkThreshold) const {
bool BabeBlockValidatorImpl::verifyVRF(const BabeBlockHeader &babe_header,
const EpochNumber epoch_number,
const AuthorityId &public_key,
const Threshold &threshold,
const Randomness &randomness,
const bool checkThreshold) const {
primitives::Transcript transcript;
prepareTranscript(
transcript, randomness, babe_header.slot_number, epoch_number);
Expand Down
Loading
Loading