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

beefy justifications #1812

Merged
merged 23 commits into from
Oct 3, 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
6 changes: 3 additions & 3 deletions core/blockchain/impl/digest_tracker_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ namespace kagome::blockchain {

return grandpa_digest_observer_->onDigest(context, digest);

} else if (message.consensus_engine_id == primitives::kBeefyEngineId) {
return outcome::success();
} else if (message.consensus_engine_id
== primitives::kUnsupportedEngineId_BEEF
or message.consensus_engine_id
== primitives::kUnsupportedEngineId_POL1) {
== primitives::kUnsupportedEngineId_POL1) {
SL_TRACE(logger_,
"Unsupported consensus engine id in block {}: {}",
context.block_info,
Expand Down
57 changes: 57 additions & 0 deletions core/consensus/beefy/digest.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "consensus/beefy/types.hpp"
#include "primitives/block_header.hpp"

namespace kagome {
inline std::optional<consensus::beefy::ValidatorSet> beefyValidatorsDigest(
const primitives::BlockHeader &block) {
for (auto &digest : block.digest) {
auto consensus = boost::get<primitives::Consensus>(&digest);
if (not consensus) {
continue;
}
if (consensus->consensus_engine_id != primitives::kBeefyEngineId) {
continue;
}
auto decoded_res =
scale::decode<consensus::beefy::ConsensusDigest>(consensus->data);
if (not decoded_res) {
continue;
}
auto &decoded = decoded_res.value();
if (auto item = boost::get<consensus::beefy::ValidatorSet>(&decoded)) {
return std::move(*item);
}
}
return std::nullopt;
}

inline std::optional<consensus::beefy::MmrRootHash> beefyMmrDigest(
const primitives::BlockHeader &block) {
for (auto &digest : block.digest) {
auto consensus = boost::get<primitives::Consensus>(&digest);
if (not consensus) {
continue;
}
if (consensus->consensus_engine_id != primitives::kBeefyEngineId) {
continue;
}
auto decoded_res =
scale::decode<consensus::beefy::ConsensusDigest>(consensus->data);
if (not decoded_res) {
continue;
}
auto &decoded = decoded_res.value();
if (auto item = boost::get<consensus::beefy::MmrRootHash>(&decoded)) {
return *item;
}
}
return std::nullopt;
}
} // namespace kagome
10 changes: 8 additions & 2 deletions core/consensus/beefy/sig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ namespace kagome::consensus::beefy {
}

inline bool verify(const crypto::EcdsaProvider &ecdsa,
const BeefyJustification &justification_v1,
const SignedCommitment &justification,
const ValidatorSet &validators) {
auto &justification = boost::get<SignedCommitment>(justification_v1);
if (justification.commitment.validator_set_id != validators.id) {
return false;
}
Expand All @@ -50,4 +49,11 @@ namespace kagome::consensus::beefy {
}
return valid >= threshold(total);
}

inline bool verify(const crypto::EcdsaProvider &ecdsa,
const BeefyJustification &justification_v1,
const ValidatorSet &validators) {
return verify(
ecdsa, boost::get<SignedCommitment>(justification_v1), validators);
}
} // namespace kagome::consensus::beefy
20 changes: 16 additions & 4 deletions core/consensus/beefy/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ namespace kagome::consensus::beefy {

std::vector<crypto::EcdsaPublicKey> validators;
primitives::AuthoritySetId id;

std::optional<primitives::AuthorityIndex> find(
const crypto::EcdsaPublicKey &key) const {
auto it = std::find(validators.begin(), validators.end(), key);
if (it == validators.end()) {
return std::nullopt;
}
return it - validators.begin();
}
};

using ConsensusDigest =
Expand All @@ -34,6 +43,7 @@ namespace kagome::consensus::beefy {
MmrRootHash>;

using PayloadId = common::Blob<2>;
constexpr PayloadId kMmr{{'m', 'h'}};

struct Commitment {
SCALE_TIE(3);
Expand All @@ -55,8 +65,8 @@ namespace kagome::consensus::beefy {
Commitment commitment;
std::vector<std::optional<crypto::EcdsaSignature>> signatures;
};
scale::ScaleEncoderStream &operator<<(scale::ScaleEncoderStream &s,
const SignedCommitment &v) {
inline scale::ScaleEncoderStream &operator<<(scale::ScaleEncoderStream &s,
const SignedCommitment &v) {
s << v.commitment;
size_t count = 0;
common::Buffer bits;
Expand All @@ -80,8 +90,8 @@ namespace kagome::consensus::beefy {
}
return s;
}
scale::ScaleDecoderStream &operator>>(scale::ScaleDecoderStream &s,
SignedCommitment &v) {
inline scale::ScaleDecoderStream &operator>>(scale::ScaleDecoderStream &s,
SignedCommitment &v) {
s >> v.commitment;
common::Buffer bits;
s >> bits;
Expand Down Expand Up @@ -111,4 +121,6 @@ namespace kagome::consensus::beefy {
}

using BeefyJustification = boost::variant<Unused<0>, SignedCommitment>;

using BeefyGossipMessage = boost::variant<VoteMessage, BeefyJustification>;
} // namespace kagome::consensus::beefy
1 change: 1 addition & 0 deletions core/crypto/crypto_store/key_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace kagome::crypto {
KEY_TYPE_ASGN,
KEY_TYPE_AUDI,
KEY_TYPE_ACCO,
KEY_TYPE_BEEF,
};

return supported_types.count(k) > 0;
Expand Down
1 change: 1 addition & 0 deletions core/crypto/crypto_store/key_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace kagome::crypto {
KEY_TYPE_AUDI = 0x69647561u, // Account discovery [sr25519, ed25519, secp256k1]
KEY_TYPE_ASGN = 0x6e677361u, // ASGN
KEY_TYPE_PARA = 0x61726170u, // PARA
KEY_TYPE_BEEF = 0x66656562u, // Beefy, secp256k1
// clang-format on
};

Expand Down
9 changes: 9 additions & 0 deletions core/crypto/crypto_store/session_keys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ namespace kagome::crypto {
store_->generateSr25519Keypair(KEY_TYPE_AUDI, *dev).value();
store_->generateSr25519Keypair(KEY_TYPE_ASGN, *dev).value();
store_->generateSr25519Keypair(KEY_TYPE_PARA, *dev).value();
store_->generateEcdsaKeypair(KEY_TYPE_BEEF, *dev).value();
}
}

Expand Down Expand Up @@ -123,4 +124,12 @@ namespace kagome::crypto {
return nullptr;
}

SessionKeys::KeypairWithIndexOpt<EcdsaKeypair>
SessionKeysImpl::getBeefKeyPair(
const std::vector<EcdsaPublicKey> &authorities) {
return find<EcdsaKeypair,
&CryptoStore::getEcdsaPublicKeys,
&CryptoStore::findEcdsaKeypair>(
beef_key_pair_, KEY_TYPE_BEEF, authorities, std::equal_to{});
}
} // namespace kagome::crypto
11 changes: 11 additions & 0 deletions core/crypto/crypto_store/session_keys.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "common/blob.hpp"
#include "crypto/crypto_store/key_type.hpp"
#include "crypto/ecdsa_types.hpp"
#include "network/types/roles.hpp"
#include "primitives/authority.hpp"
#include "primitives/authority_discovery_id.hpp"
Expand Down Expand Up @@ -65,13 +66,20 @@ namespace kagome::crypto {
*/
virtual std::shared_ptr<Sr25519Keypair> getAudiKeyPair(
const std::vector<primitives::AuthorityDiscoveryId> &authorities) = 0;

/**
* @return current BEEF session key pair
*/
virtual KeypairWithIndexOpt<EcdsaKeypair> getBeefKeyPair(
const std::vector<EcdsaPublicKey> &authorities) = 0;
};

class SessionKeysImpl : public SessionKeys {
KeypairWithIndexOpt<Sr25519Keypair> babe_key_pair_;
KeypairWithIndexOpt<Ed25519Keypair> gran_key_pair_;
KeypairWithIndexOpt<Sr25519Keypair> para_key_pair_;
KeypairWithIndexOpt<Sr25519Keypair> audi_key_pair_;
KeypairWithIndexOpt<EcdsaKeypair> beef_key_pair_;
network::Roles roles_;
std::shared_ptr<CryptoStore> store_;

Expand Down Expand Up @@ -107,6 +115,9 @@ namespace kagome::crypto {
std::shared_ptr<Sr25519Keypair> getAudiKeyPair(
const std::vector<primitives::AuthorityDiscoveryId> &authorities)
override;

KeypairWithIndexOpt<EcdsaKeypair> getBeefKeyPair(
const std::vector<EcdsaPublicKey> &authorities) override;
};

} // namespace kagome::crypto
Expand Down
1 change: 1 addition & 0 deletions core/injector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_library(application_injector
application_injector.cpp
)
target_link_libraries(application_injector
beefy_api
Boost::Boost.DI
runtime_wavm
account_nonce_api
Expand Down
4 changes: 4 additions & 0 deletions core/injector/application_injector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#include "metrics/impl/metrics_watcher.hpp"
#include "metrics/impl/prometheus/handler_impl.hpp"
#include "metrics/metrics.hpp"
#include "network/beefy/beefy.hpp"
#include "network/impl/block_announce_transmitter_impl.hpp"
#include "network/impl/extrinsic_observer_impl.hpp"
#include "network/impl/grandpa_transmitter_impl.hpp"
Expand Down Expand Up @@ -143,6 +144,7 @@
#include "runtime/runtime_api/impl/account_nonce_api.hpp"
#include "runtime/runtime_api/impl/authority_discovery_api.hpp"
#include "runtime/runtime_api/impl/babe_api.hpp"
#include "runtime/runtime_api/impl/beefy.hpp"
#include "runtime/runtime_api/impl/block_builder.hpp"
#include "runtime/runtime_api/impl/core.hpp"
#include "runtime/runtime_api/impl/grandpa_api.hpp"
Expand Down Expand Up @@ -502,6 +504,7 @@ namespace {
di::bind<offchain::OffchainLocalStorage>.template to<offchain::OffchainLocalStorageImpl>(),
di::bind<runtime::Metadata>.template to<runtime::MetadataImpl>(),
di::bind<runtime::GrandpaApi>.template to<runtime::GrandpaApiImpl>(),
di::bind<runtime::BeefyApi>.template to<runtime::BeefyApiImpl>(),
di::bind<runtime::Core>.template to<runtime::CoreImpl>(),
di::bind<runtime::BabeApi>.template to<runtime::BabeApiImpl>(),
di::bind<runtime::SessionKeysApi>.template to<runtime::SessionKeysApiImpl>(),
Expand Down Expand Up @@ -796,6 +799,7 @@ namespace {
di::bind<crypto::SessionKeys>.template to<crypto::SessionKeysImpl>(),
di::bind<network::SyncProtocol>.template to<network::SyncProtocolImpl>(),
di::bind<network::StateProtocol>.template to<network::StateProtocolImpl>(),
di::bind<network::IBeefy>.template to<network::Beefy>(),
di::bind<consensus::babe::BabeLottery>.template to<consensus::babe::BabeLotteryImpl>(),
di::bind<network::BlockAnnounceObserver>.template to<consensus::TimelineImpl>(),
di::bind<dispute::DisputeCoordinator>.template to<dispute::DisputeCoordinatorImpl>(),
Expand Down
14 changes: 14 additions & 0 deletions core/metrics/histogram_timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ namespace kagome::metrics {
return buckets;
}

struct GaugeHelper {
GaugeHelper(const std::string &name, const std::string &help) {
registry_->registerGaugeFamily(name, help);
metric_ = registry_->registerGaugeMetric(name);
}

auto *operator->() {
return metric_;
}

metrics::RegistryPtr registry_ = metrics::createRegistry();
metrics::Gauge *metric_;
};

struct HistogramHelper {
HistogramHelper(const std::string &name,
const std::string &help,
Expand Down
3 changes: 3 additions & 0 deletions core/network/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ add_subdirectory(protobuf)


add_library(network
beefy/beefy.cpp
beefy/protocol.cpp
impl/protocols/light.cpp
impl/state_protocol_observer_impl.cpp
impl/state_sync_request_flow.cpp
Expand Down Expand Up @@ -38,6 +40,7 @@ target_link_libraries(network
core_api
light_api_proto
p2p::p2p_basic_scheduler
runtime_transaction_error
executor
scale_libp2p_types
blockchain
Expand Down
4 changes: 2 additions & 2 deletions core/network/adapters/protobuf_block_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace kagome::network {
vec.emplace_back(primitives::kGrandpaEngineId, gran->data);
}
if (auto &beef = src_block.beefy_justification) {
vec.emplace_back(primitives::kUnsupportedEngineId_BEEF, beef->data);
vec.emplace_back(primitives::kBeefyEngineId, beef->data);
}
dst_block->set_justifications(
common::Buffer{scale::encode(vec).value()}.toString());
Expand Down Expand Up @@ -124,7 +124,7 @@ namespace kagome::network {
if (engine == primitives::kGrandpaEngineId) {
justification = primitives::Justification{std::move(raw)};
}
if (engine == primitives::kUnsupportedEngineId_BEEF) {
if (engine == primitives::kBeefyEngineId) {
beefy_justification = primitives::Justification{std::move(raw)};
}
}
Expand Down
Loading
Loading