From cfa437631339bee2190938e93b9ee6ca689b1482 Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 14:56:02 +0300 Subject: [PATCH 01/11] scale bitvec Signed-off-by: turuslan --- cmake/Hunter/hunter-gate-url.cmake | 4 ++-- core/consensus/babe/impl/parachains_inherent_data.hpp | 6 ++++-- core/runtime/runtime_api/parachain_host_types.hpp | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cmake/Hunter/hunter-gate-url.cmake b/cmake/Hunter/hunter-gate-url.cmake index b226061782..ee4457e9cb 100644 --- a/cmake/Hunter/hunter-gate-url.cmake +++ b/cmake/Hunter/hunter-gate-url.cmake @@ -1,6 +1,6 @@ HunterGate( - URL "https://github.com/soramitsu/soramitsu-hunter/archive/52069249f8ed86f30d3f473c32de44c64270d186.zip" - SHA1 "4edea9f8976988f8f34ca59c5341a2297315a941" + URL "https://github.com/soramitsu/soramitsu-hunter/archive/refs/tags/v0.23.257-soramitsu31.zip" + SHA1 "a13dcf6dae9e926441715e67c409838630f6f3e0" LOCAL ) diff --git a/core/consensus/babe/impl/parachains_inherent_data.hpp b/core/consensus/babe/impl/parachains_inherent_data.hpp index 4c484e49cf..7ba0451111 100644 --- a/core/consensus/babe/impl/parachains_inherent_data.hpp +++ b/core/consensus/babe/impl/parachains_inherent_data.hpp @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include "common/stub.hpp" #include "common/tagged.hpp" #include "common/unused.hpp" @@ -189,7 +191,7 @@ namespace kagome::consensus::babe { std::vector validity_votes; /// A bitfield of indices of the validators within the validator group - std::vector indices; + scale::BitVec indices; }; scale::ScaleEncoderStream &operator<<(scale::ScaleEncoderStream &s, @@ -287,7 +289,7 @@ namespace kagome::consensus::babe { /// Bitfields signed by validators claiming the candidate is available or not struct SignedBitfields { /// The availability bitfield - std::vector bitfield; + scale::BitVec bitfield; /// The signature of the validator Signature signature; diff --git a/core/runtime/runtime_api/parachain_host_types.hpp b/core/runtime/runtime_api/parachain_host_types.hpp index f63b84506f..098aebcb36 100644 --- a/core/runtime/runtime_api/parachain_host_types.hpp +++ b/core/runtime/runtime_api/parachain_host_types.hpp @@ -6,6 +6,8 @@ #ifndef KAGOME_CORE_RUNTIME_PARACHAIN_HOST_TYPES_HPP #define KAGOME_CORE_RUNTIME_PARACHAIN_HOST_TYPES_HPP +#include + #include "common/blob.hpp" #include "common/unused.hpp" #include "primitives/block_id.hpp" @@ -24,7 +26,6 @@ namespace kagome::runtime { using CollatorSignature = common::Hash256; using ValidationCodeHash = common::Hash256; using BlockNumber = primitives::BlockNumber; - using Bitvec = std::vector; using CandidateHash = common::Hash256; using HeadData = Buffer; using GroupRotatePeriod = uint32_t; @@ -86,7 +87,7 @@ namespace kagome::runtime { /// A bitfield with 1 bit for each validator in the set. `1` bits mean that /// the corresponding validators has attested to availability on-chain. A /// 2/3+ majority of `1` bits means that this will be available. - Bitvec availability; + scale::BitVec availability; /// The group assigned to distribute availability pieces of this candidate. GroupIndex group_responsible; /// The hash of the candidate occupying the core. From 4fabc9d20dfa063f334720658e75e58168e66bc3 Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 15:06:54 +0300 Subject: [PATCH 02/11] signed bitfield Signed-off-by: turuslan --- .../babe/impl/parachains_inherent_data.hpp | 33 ++----------------- core/network/types/collator_messages.hpp | 14 ++++++++ 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/core/consensus/babe/impl/parachains_inherent_data.hpp b/core/consensus/babe/impl/parachains_inherent_data.hpp index 7ba0451111..ac6ef2016b 100644 --- a/core/consensus/babe/impl/parachains_inherent_data.hpp +++ b/core/consensus/babe/impl/parachains_inherent_data.hpp @@ -8,6 +8,7 @@ #include "common/stub.hpp" #include "common/tagged.hpp" #include "common/unused.hpp" +#include "network/types/collator_messages.hpp" #include "primitives/common.hpp" namespace kagome::consensus::babe { @@ -286,42 +287,12 @@ namespace kagome::consensus::babe { // clang-format on } - /// Bitfields signed by validators claiming the candidate is available or not - struct SignedBitfields { - /// The availability bitfield - scale::BitVec bitfield; - - /// The signature of the validator - Signature signature; - - /// The validator index in the authority set - uint32_t validator_index; - }; - - scale::ScaleEncoderStream &operator<<(scale::ScaleEncoderStream &s, - const SignedBitfields &data) { - // clang-format off - return s << data.bitfield - << data.signature - << data.validator_index; - // clang-format on - } - - scale::ScaleDecoderStream &operator>>(scale::ScaleDecoderStream &s, - SignedBitfields &data) { - // clang-format off - return s >> data.bitfield - >> data.signature - >> data.validator_index; - // clang-format on - } - struct ParachainInherentData { /// The array of signed bitfields by validators claiming the candidate is /// available (or not). /// @note The array must be sorted by validator index corresponding to the /// authority set - std::vector bitfields; + std::vector bitfields; /// The array of backed candidates for inclusion in the current block std::vector backed_candidates; diff --git a/core/network/types/collator_messages.hpp b/core/network/types/collator_messages.hpp index 9004e40c3d..28256603c8 100644 --- a/core/network/types/collator_messages.hpp +++ b/core/network/types/collator_messages.hpp @@ -7,6 +7,7 @@ #define KAGOME_COLLATOR_DECLARE_HPP #include +#include #include #include #include @@ -30,6 +31,17 @@ namespace kagome::network { using CandidateHash = primitives::BlockHash; using ChunkProof = std::vector; + template + struct Signed { + SCALE_TIE(3); + + static_assert(std::is_same_v, Payload>); + + Payload payload; + ValidatorIndex validator_index; + Signature signature; + }; + /// NU element. using Dummy = std::tuple<>; @@ -199,6 +211,8 @@ namespace kagome::network { Statement statement; /// statement of seconded candidate }; + using SignedBitfield = Signed; + /** * Collator -> Validator and Validator -> Collator if statement message. * Type of the appropriate message. From 657ab4caaa4a06c80c6635db87896339eaf9a65c Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 15:46:44 +0300 Subject: [PATCH 03/11] validator signer Signed-off-by: turuslan --- core/parachain/CMakeLists.txt | 1 + core/parachain/validator/signer.cpp | 60 +++++++++++++++++++++ core/parachain/validator/signer.hpp | 82 +++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 core/parachain/validator/signer.cpp create mode 100644 core/parachain/validator/signer.hpp diff --git a/core/parachain/CMakeLists.txt b/core/parachain/CMakeLists.txt index e0755cf088..cbc0230256 100644 --- a/core/parachain/CMakeLists.txt +++ b/core/parachain/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(validator_parachain availability/store/store_impl.cpp validator/impl/parachain_observer.cpp validator/impl/parachain_processor.cpp + validator/signer.cpp ) target_link_libraries(validator_parachain diff --git a/core/parachain/validator/signer.cpp b/core/parachain/validator/signer.cpp new file mode 100644 index 0000000000..383724bb15 --- /dev/null +++ b/core/parachain/validator/signer.cpp @@ -0,0 +1,60 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parachain/validator/signer.hpp" + +namespace kagome::parachain { + outcome::result SigningContext::make( + const std::shared_ptr ¶chain_api, + const primitives::BlockHash &relay_parent) { + OUTCOME_TRY(session_index, + parachain_api->session_index_for_child(relay_parent)); + return SigningContext{session_index, relay_parent}; + } + + ValidatorSigner::ValidatorSigner( + ValidatorIndex validator_index, + SigningContext context, + std::shared_ptr keypair, + std::shared_ptr sr25519_provider) + : validator_index_{validator_index}, + context_{context}, + keypair_{std::move(keypair)}, + sr25519_provider_{std::move(sr25519_provider)} {} + + ValidatorSigner::ValidatorIndex ValidatorSigner::validatorIndex() const { + return validator_index_; + } + + const SigningContext &ValidatorSigner::context() const { + return context_; + } + + ValidatorSignerFactory::ValidatorSignerFactory( + std::shared_ptr parachain_api, + std::shared_ptr keypair, + std::shared_ptr sr25519_provider) + : parachain_api_{std::move(parachain_api)}, + keypair_{std::move(keypair)}, + sr25519_provider_{std::move(sr25519_provider)} {} + + outcome::result> ValidatorSignerFactory::at( + const primitives::BlockHash &relay_parent) { + OUTCOME_TRY(validators, parachain_api_->validators(relay_parent)); + auto it = + std::find(validators.begin(), validators.end(), keypair_->public_key); + if (it == validators.end()) { + return std::nullopt; + } + network::ValidatorIndex validator_index = it - validators.begin(); + OUTCOME_TRY(context, SigningContext::make(parachain_api_, relay_parent)); + return ValidatorSigner{ + validator_index, + context, + keypair_, + sr25519_provider_, + }; + } +} // namespace kagome::parachain diff --git a/core/parachain/validator/signer.hpp b/core/parachain/validator/signer.hpp new file mode 100644 index 0000000000..b5af29d270 --- /dev/null +++ b/core/parachain/validator/signer.hpp @@ -0,0 +1,82 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_PARACHAIN_VALIDATOR_SIGNER_HPP +#define KAGOME_PARACHAIN_VALIDATOR_SIGNER_HPP + +#include + +#include "crypto/sr25519_provider.hpp" +#include "network/types/collator_messages.hpp" +#include "runtime/runtime_api/parachain_host.hpp" + +namespace kagome::parachain { + /// A type returned by runtime with current session index and a parent hash. + struct SigningContext { + SCALE_TIE(2); + + static outcome::result make( + const std::shared_ptr ¶chain_api, + const primitives::BlockHash &relay_parent); + + template + auto signable(const T &payload) const { + return scale::encode(std::tie(payload, *this)); + } + + /// Current session index. + runtime::SessionIndex session_index; + /// Hash of the parent. + primitives::BlockHash relay_parent; + }; + + class ValidatorSigner { + public: + using ValidatorIndex = network::ValidatorIndex; + + ValidatorSigner(ValidatorIndex validator_index, + SigningContext context, + std::shared_ptr keypair, + std::shared_ptr sr25519_provider); + + template + outcome::result> sign(T payload) const { + OUTCOME_TRY(data, context_.signable(payload)); + OUTCOME_TRY(signature, sr25519_provider_->sign(*keypair_, data)); + return network::Signed{ + std::move(payload), + validator_index_, + signature, + }; + } + + ValidatorIndex validatorIndex() const; + const SigningContext &context() const; + + private: + ValidatorIndex validator_index_; + SigningContext context_; + std::shared_ptr keypair_; + std::shared_ptr sr25519_provider_; + }; + + class ValidatorSignerFactory { + public: + ValidatorSignerFactory( + std::shared_ptr parachain_api, + std::shared_ptr keypair, + std::shared_ptr sr25519_provider); + + outcome::result> at( + const primitives::BlockHash &relay_parent); + + private: + std::shared_ptr parachain_api_; + std::shared_ptr keypair_; + std::shared_ptr sr25519_provider_; + }; +} // namespace kagome::parachain + +#endif // KAGOME_PARACHAIN_VALIDATOR_SIGNER_HPP From cb61d4a820faa4814ff551aeb37eb253fbc6e7f7 Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 16:03:24 +0300 Subject: [PATCH 04/11] bitfield store Signed-off-by: turuslan --- core/injector/application_injector.cpp | 2 ++ core/parachain/CMakeLists.txt | 1 + .../parachain/availability/bitfield/store.hpp | 26 +++++++++++++++++ .../availability/bitfield/store_impl.cpp | 23 +++++++++++++++ .../availability/bitfield/store_impl.hpp | 28 +++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 core/parachain/availability/bitfield/store.hpp create mode 100644 core/parachain/availability/bitfield/store_impl.cpp create mode 100644 core/parachain/availability/bitfield/store_impl.hpp diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 58b6cf6417..7af5f6b330 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -109,6 +109,7 @@ #include "offchain/impl/offchain_worker_impl.hpp" #include "offchain/impl/offchain_worker_pool_impl.hpp" #include "outcome/outcome.hpp" +#include "parachain/availability/bitfield/store_impl.hpp" #include "parachain/availability/store/store_impl.hpp" #include "parachain/validator/parachain_observer.hpp" #include "parachain/validator/parachain_processor.hpp" @@ -1233,6 +1234,7 @@ namespace { bind_by_lambda(get_state_observer_impl), bind_by_lambda(get_sync_observer_impl), di::bind.template to(), + di::bind.template to(), di::bind.to([](auto const &injector) { return get_parachain_observer_impl(injector); }), diff --git a/core/parachain/CMakeLists.txt b/core/parachain/CMakeLists.txt index cbc0230256..888f069c1f 100644 --- a/core/parachain/CMakeLists.txt +++ b/core/parachain/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(validator_parachain + availability/bitfield/store_impl.cpp availability/store/store_impl.cpp validator/impl/parachain_observer.cpp validator/impl/parachain_processor.cpp diff --git a/core/parachain/availability/bitfield/store.hpp b/core/parachain/availability/bitfield/store.hpp new file mode 100644 index 0000000000..68c01c7a22 --- /dev/null +++ b/core/parachain/availability/bitfield/store.hpp @@ -0,0 +1,26 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_HPP +#define KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_HPP + +#include "network/types/collator_messages.hpp" + +namespace kagome::parachain { + class BitfieldStore { + public: + using BlockHash = primitives::BlockHash; + using SignedBitfield = network::SignedBitfield; + + virtual ~BitfieldStore() = 0; + + virtual void putBitfield(const BlockHash &relay_parent, + const SignedBitfield &bitfield) = 0; + virtual std::vector getBitfields( + const BlockHash &relay_parent) const = 0; + }; +} // namespace kagome::parachain + +#endif // KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_HPP diff --git a/core/parachain/availability/bitfield/store_impl.cpp b/core/parachain/availability/bitfield/store_impl.cpp new file mode 100644 index 0000000000..907ea6f544 --- /dev/null +++ b/core/parachain/availability/bitfield/store_impl.cpp @@ -0,0 +1,23 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parachain/availability/bitfield/store_impl.hpp" + +namespace kagome::parachain { + void BitfieldStoreImpl::putBitfield(const BlockHash &relay_parent, + const SignedBitfield &bitfield) { + bitfields_[relay_parent].push_back(bitfield); + } + + std::vector BitfieldStoreImpl::getBitfields( + const BlockHash &relay_parent) const { + std::vector bitfields; + auto it = bitfields_.find(relay_parent); + if (it != bitfields_.end()) { + bitfields = it->second; + } + return bitfields; + } +} // namespace kagome::parachain diff --git a/core/parachain/availability/bitfield/store_impl.hpp b/core/parachain/availability/bitfield/store_impl.hpp new file mode 100644 index 0000000000..0dd62fb2c3 --- /dev/null +++ b/core/parachain/availability/bitfield/store_impl.hpp @@ -0,0 +1,28 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_IMPL_HPP +#define KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_IMPL_HPP + +#include "parachain/availability/bitfield/store.hpp" + +#include + +namespace kagome::parachain { + class BitfieldStoreImpl : public BitfieldStore { + public: + ~BitfieldStoreImpl() override = default; + + void putBitfield(const BlockHash &relay_parent, + const SignedBitfield &bitfield) override; + std::vector getBitfields( + const BlockHash &relay_parent) const override; + + private: + std::unordered_map> bitfields_; + }; +} // namespace kagome::parachain + +#endif // KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_STORE_IMPL_HPP From 4d2f38cbfc2d3ad639cde523c269bda72f3b5369 Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 16:24:35 +0300 Subject: [PATCH 05/11] bitfield signer Signed-off-by: turuslan --- core/parachain/CMakeLists.txt | 1 + .../availability/bitfield/signer.cpp | 94 +++++++++++++++++++ .../availability/bitfield/signer.hpp | 48 ++++++++++ 3 files changed, 143 insertions(+) create mode 100644 core/parachain/availability/bitfield/signer.cpp create mode 100644 core/parachain/availability/bitfield/signer.hpp diff --git a/core/parachain/CMakeLists.txt b/core/parachain/CMakeLists.txt index 888f069c1f..867397c691 100644 --- a/core/parachain/CMakeLists.txt +++ b/core/parachain/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(validator_parachain + availability/bitfield/signer.cpp availability/bitfield/store_impl.cpp availability/store/store_impl.cpp validator/impl/parachain_observer.cpp diff --git a/core/parachain/availability/bitfield/signer.cpp b/core/parachain/availability/bitfield/signer.cpp new file mode 100644 index 0000000000..10e85937ed --- /dev/null +++ b/core/parachain/availability/bitfield/signer.cpp @@ -0,0 +1,94 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parachain/availability/bitfield/signer.hpp" + +#include "log/logger.hpp" +#include "primitives/block_header.hpp" + +namespace kagome::parachain { + constexpr std::chrono::milliseconds kDelay{1500}; + + namespace { + inline auto log() { + return log::createLogger("BitfieldSigner"); + } + } // namespace + + BitfieldSigner::BitfieldSigner( + std::shared_ptr hasher, + std::shared_ptr signer_factory, + std::shared_ptr scheduler, + std::shared_ptr parachain_api, + std::shared_ptr store, + std::shared_ptr bitfield_store) + : hasher_{std::move(hasher)}, + signer_factory_{std::move(signer_factory)}, + scheduler_{std::move(scheduler)}, + parachain_api_{std::move(parachain_api)}, + store_{std::move(store)}, + bitfield_store_{std::move(bitfield_store)} {} + + void BitfieldSigner::start( + std::shared_ptr + chain_sub_engine) { + chain_sub_ = std::make_shared( + chain_sub_engine); + chain_sub_->subscribe(chain_sub_->generateSubscriptionSetId(), + primitives::events::ChainEventType::kNewHeads); + chain_sub_->setCallback( + [weak = weak_from_this()]( + subscription::SubscriptionSetId, + auto &&, + primitives::events::ChainEventType, + const primitives::events::ChainEventParams &event) { + if (auto self = weak.lock()) { + auto r = self->onBlock(self->hasher_->blake2b_256( + scale::encode( + boost::get(event)) + .value())); + if (r.has_error()) { + SL_WARN(log(), "onBlock error {}", r.error()); + } + } + }); + } + + outcome::result BitfieldSigner::sign(const ValidatorSigner &signer) { + auto &relay_parent = signer.context().relay_parent; + scale::BitVec bitfield; + OUTCOME_TRY(cores, parachain_api_->availability_cores(relay_parent)); + bitfield.bits.reserve(cores.size()); + for (auto &core : cores) { + auto occupied = boost::get(&core); + bitfield.bits.push_back(occupied != nullptr + && store_->hasChunk(occupied->candidate_hash, + signer.validatorIndex())); + } + + OUTCOME_TRY(signed_bitfield, signer.sign(bitfield)); + bitfield_store_->putBitfield(relay_parent, signed_bitfield); + // TODO(turuslan): broadcast + return outcome::success(); + } + + outcome::result BitfieldSigner::onBlock(const BlockHash &relay_parent) { + OUTCOME_TRY(signer, signer_factory_->at(relay_parent)); + if (not signer.has_value()) { + return outcome::success(); + } + scheduler_->schedule( + [weak = weak_from_this(), relay_parent, signer{std::move(*signer)}]() { + if (auto self = weak.lock()) { + auto r = self->sign(signer); + if (r.has_error()) { + SL_WARN(log(), "sign error {}", r.error()); + } + } + }, + kDelay); + return outcome::success(); + } +} // namespace kagome::parachain diff --git a/core/parachain/availability/bitfield/signer.hpp b/core/parachain/availability/bitfield/signer.hpp new file mode 100644 index 0000000000..981f5a609f --- /dev/null +++ b/core/parachain/availability/bitfield/signer.hpp @@ -0,0 +1,48 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_SIGNER_HPP +#define KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_SIGNER_HPP + +#include + +#include "crypto/hasher.hpp" +#include "parachain/availability/bitfield/store.hpp" +#include "parachain/availability/store/store.hpp" +#include "parachain/validator/signer.hpp" +#include "primitives/event_types.hpp" +#include "runtime/runtime_api/parachain_host.hpp" + +namespace kagome::parachain { + class BitfieldSigner : public std::enable_shared_from_this { + public: + BitfieldSigner(std::shared_ptr hasher, + std::shared_ptr signer_factory, + std::shared_ptr scheduler, + std::shared_ptr parachain_api, + std::shared_ptr store, + std::shared_ptr bitfield_store); + + void start(std::shared_ptr + chain_sub_engine); + + outcome::result sign(const ValidatorSigner &signer); + + private: + using BlockHash = primitives::BlockHash; + + outcome::result onBlock(const BlockHash &relay_parent); + + std::shared_ptr hasher_; + std::shared_ptr signer_factory_; + std::shared_ptr scheduler_; + std::shared_ptr parachain_api_; + std::shared_ptr store_; + std::shared_ptr bitfield_store_; + std::shared_ptr chain_sub_; + }; +} // namespace kagome::parachain + +#endif // KAGOME_PARACHAIN_AVAILABILITY_BITFIELD_SIGNER_HPP From f716fe6517be8aebe26e3413ee213ba450d24504 Mon Sep 17 00:00:00 2001 From: turuslan Date: Tue, 13 Sep 2022 16:53:12 +0300 Subject: [PATCH 06/11] comments Signed-off-by: turuslan --- core/network/types/collator_messages.hpp | 5 +++++ core/parachain/availability/bitfield/signer.hpp | 3 +++ core/parachain/availability/bitfield/store.hpp | 4 ++++ core/parachain/validator/signer.hpp | 9 +++++++++ 4 files changed, 21 insertions(+) diff --git a/core/network/types/collator_messages.hpp b/core/network/types/collator_messages.hpp index 28256603c8..f21ae14f4b 100644 --- a/core/network/types/collator_messages.hpp +++ b/core/network/types/collator_messages.hpp @@ -31,14 +31,18 @@ namespace kagome::network { using CandidateHash = primitives::BlockHash; using ChunkProof = std::vector; + /// Payload signed by validator. template struct Signed { SCALE_TIE(3); static_assert(std::is_same_v, Payload>); + /// Payload. Payload payload; + /// Index of validator in validator list. ValidatorIndex validator_index; + /// Signature of `SigningContext::signable(payload)`. Signature signature; }; @@ -211,6 +215,7 @@ namespace kagome::network { Statement statement; /// statement of seconded candidate }; + /// Signed availability bitfield. using SignedBitfield = Signed; /** diff --git a/core/parachain/availability/bitfield/signer.hpp b/core/parachain/availability/bitfield/signer.hpp index 981f5a609f..5998ea6311 100644 --- a/core/parachain/availability/bitfield/signer.hpp +++ b/core/parachain/availability/bitfield/signer.hpp @@ -16,6 +16,7 @@ #include "runtime/runtime_api/parachain_host.hpp" namespace kagome::parachain { + /// Signs, stores and broadcasts bitfield for every new head. class BitfieldSigner : public std::enable_shared_from_this { public: BitfieldSigner(std::shared_ptr hasher, @@ -25,9 +26,11 @@ namespace kagome::parachain { std::shared_ptr store, std::shared_ptr bitfield_store); + /// Subscribes to new heads. void start(std::shared_ptr chain_sub_engine); + /// Sign bitfield for given block. outcome::result sign(const ValidatorSigner &signer); private: diff --git a/core/parachain/availability/bitfield/store.hpp b/core/parachain/availability/bitfield/store.hpp index 68c01c7a22..b8e08c71b3 100644 --- a/core/parachain/availability/bitfield/store.hpp +++ b/core/parachain/availability/bitfield/store.hpp @@ -9,6 +9,7 @@ #include "network/types/collator_messages.hpp" namespace kagome::parachain { + /// Stores bitfields signed by validators. class BitfieldStore { public: using BlockHash = primitives::BlockHash; @@ -16,8 +17,11 @@ namespace kagome::parachain { virtual ~BitfieldStore() = 0; + /// Store bitfield at given block. virtual void putBitfield(const BlockHash &relay_parent, const SignedBitfield &bitfield) = 0; + + /// Get bitfields for given block. virtual std::vector getBitfields( const BlockHash &relay_parent) const = 0; }; diff --git a/core/parachain/validator/signer.hpp b/core/parachain/validator/signer.hpp index b5af29d270..dd43b26686 100644 --- a/core/parachain/validator/signer.hpp +++ b/core/parachain/validator/signer.hpp @@ -17,10 +17,12 @@ namespace kagome::parachain { struct SigningContext { SCALE_TIE(2); + /// Make signing context for given block. static outcome::result make( const std::shared_ptr ¶chain_api, const primitives::BlockHash &relay_parent); + /// Make signable message for payload. template auto signable(const T &payload) const { return scale::encode(std::tie(payload, *this)); @@ -32,6 +34,7 @@ namespace kagome::parachain { primitives::BlockHash relay_parent; }; + /// Signs payload with signing context and validator keypair. class ValidatorSigner { public: using ValidatorIndex = network::ValidatorIndex; @@ -41,6 +44,7 @@ namespace kagome::parachain { std::shared_ptr keypair, std::shared_ptr sr25519_provider); + /// Sign payload. template outcome::result> sign(T payload) const { OUTCOME_TRY(data, context_.signable(payload)); @@ -52,7 +56,10 @@ namespace kagome::parachain { }; } + /// Get validator index. ValidatorIndex validatorIndex() const; + + /// Get signing context. const SigningContext &context() const; private: @@ -62,6 +69,7 @@ namespace kagome::parachain { std::shared_ptr sr25519_provider_; }; + /// Creates validator signer. class ValidatorSignerFactory { public: ValidatorSignerFactory( @@ -69,6 +77,7 @@ namespace kagome::parachain { std::shared_ptr keypair, std::shared_ptr sr25519_provider); + /// Create validator signer if keypair belongs to validator at given block. outcome::result> at( const primitives::BlockHash &relay_parent); From 96feba2176d34b519d95554c342253413dab17c5 Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 14 Sep 2022 07:34:39 +0300 Subject: [PATCH 07/11] fix destructor Signed-off-by: turuslan --- core/parachain/availability/bitfield/store.hpp | 2 +- core/parachain/availability/store/store.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/parachain/availability/bitfield/store.hpp b/core/parachain/availability/bitfield/store.hpp index b8e08c71b3..e13140e4ec 100644 --- a/core/parachain/availability/bitfield/store.hpp +++ b/core/parachain/availability/bitfield/store.hpp @@ -15,7 +15,7 @@ namespace kagome::parachain { using BlockHash = primitives::BlockHash; using SignedBitfield = network::SignedBitfield; - virtual ~BitfieldStore() = 0; + virtual ~BitfieldStore() = default; /// Store bitfield at given block. virtual void putBitfield(const BlockHash &relay_parent, diff --git a/core/parachain/availability/store/store.hpp b/core/parachain/availability/store/store.hpp index 32d402b9c2..c9284d8e49 100644 --- a/core/parachain/availability/store/store.hpp +++ b/core/parachain/availability/store/store.hpp @@ -21,7 +21,7 @@ namespace kagome::parachain { using ParachainBlock = network::ParachainBlock; using PersistedValidationData = runtime::PersistedValidationData; - virtual ~AvailabilityStore() = 0; + virtual ~AvailabilityStore() = default; /// Has ErasureChunk virtual bool hasChunk(const CandidateHash &candidate_hash, From ffac04e4f9ccbbdd6060c6ceae9df9dcf4effeec Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 14 Sep 2022 07:36:11 +0300 Subject: [PATCH 08/11] fix cmake Signed-off-by: turuslan --- core/injector/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/injector/CMakeLists.txt b/core/injector/CMakeLists.txt index 79a4673a58..fb5950d7de 100644 --- a/core/injector/CMakeLists.txt +++ b/core/injector/CMakeLists.txt @@ -66,6 +66,7 @@ target_link_libraries(application_injector p2p::p2p_identify p2p::p2p_kademlia p2p::p2p_ping + parachain_host_api payment_api_service pbkdf2_provider peer_manager From 7f8831ac1e5816256119b34db8416b88e513362c Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 14 Sep 2022 07:37:25 +0300 Subject: [PATCH 09/11] session keys para Signed-off-by: turuslan --- core/crypto/crypto_store/session_keys.cpp | 10 ++++++++++ core/crypto/crypto_store/session_keys.hpp | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/core/crypto/crypto_store/session_keys.cpp b/core/crypto/crypto_store/session_keys.cpp index 733a5b8d3a..b249ce08e7 100644 --- a/core/crypto/crypto_store/session_keys.cpp +++ b/core/crypto/crypto_store/session_keys.cpp @@ -35,4 +35,14 @@ namespace kagome::crypto { return gran_key_pair_; } + const std::shared_ptr &SessionKeys::getParaKeyPair() { + if (not para_key_pair_ && roles_.flags.authority) { + auto keys = store_->getSr25519PublicKeys(KEY_TYPE_PARA); + if (keys and not keys.value().empty()) { + auto kp = store_->findSr25519Keypair(KEY_TYPE_PARA, keys.value().at(0)); + para_key_pair_ = std::make_shared(kp.value()); + } + } + return para_key_pair_; + } } // namespace kagome::crypto diff --git a/core/crypto/crypto_store/session_keys.hpp b/core/crypto/crypto_store/session_keys.hpp index f3f809b625..37da48bf69 100644 --- a/core/crypto/crypto_store/session_keys.hpp +++ b/core/crypto/crypto_store/session_keys.hpp @@ -30,6 +30,7 @@ namespace kagome::crypto { class SessionKeys { std::shared_ptr babe_key_pair_; std::shared_ptr gran_key_pair_; + std::shared_ptr para_key_pair_; network::Roles roles_; std::shared_ptr store_; @@ -46,6 +47,11 @@ namespace kagome::crypto { * @return current GRANDPA session key pair */ const std::shared_ptr &getGranKeyPair(); + + /** + * @return current parachain validator session key pair + */ + const std::shared_ptr &getParaKeyPair(); }; } // namespace kagome::crypto From e247b8b982ec73814aa7becd4a562acacffe6893 Mon Sep 17 00:00:00 2001 From: turuslan Date: Wed, 14 Sep 2022 08:15:47 +0300 Subject: [PATCH 10/11] use session keys Signed-off-by: turuslan --- core/parachain/validator/signer.cpp | 12 ++++++++---- core/parachain/validator/signer.hpp | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/parachain/validator/signer.cpp b/core/parachain/validator/signer.cpp index 383724bb15..fd3312e17d 100644 --- a/core/parachain/validator/signer.cpp +++ b/core/parachain/validator/signer.cpp @@ -34,17 +34,21 @@ namespace kagome::parachain { ValidatorSignerFactory::ValidatorSignerFactory( std::shared_ptr parachain_api, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr sr25519_provider) : parachain_api_{std::move(parachain_api)}, - keypair_{std::move(keypair)}, + session_keys_{std::move(session_keys)}, sr25519_provider_{std::move(sr25519_provider)} {} outcome::result> ValidatorSignerFactory::at( const primitives::BlockHash &relay_parent) { + auto &keypair = session_keys_->getParaKeyPair(); + if (keypair == nullptr) { + return std::nullopt; + } OUTCOME_TRY(validators, parachain_api_->validators(relay_parent)); auto it = - std::find(validators.begin(), validators.end(), keypair_->public_key); + std::find(validators.begin(), validators.end(), keypair->public_key); if (it == validators.end()) { return std::nullopt; } @@ -53,7 +57,7 @@ namespace kagome::parachain { return ValidatorSigner{ validator_index, context, - keypair_, + keypair, sr25519_provider_, }; } diff --git a/core/parachain/validator/signer.hpp b/core/parachain/validator/signer.hpp index dd43b26686..324fee331b 100644 --- a/core/parachain/validator/signer.hpp +++ b/core/parachain/validator/signer.hpp @@ -8,6 +8,7 @@ #include +#include "crypto/crypto_store/session_keys.hpp" #include "crypto/sr25519_provider.hpp" #include "network/types/collator_messages.hpp" #include "runtime/runtime_api/parachain_host.hpp" @@ -74,7 +75,7 @@ namespace kagome::parachain { public: ValidatorSignerFactory( std::shared_ptr parachain_api, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr sr25519_provider); /// Create validator signer if keypair belongs to validator at given block. @@ -83,7 +84,7 @@ namespace kagome::parachain { private: std::shared_ptr parachain_api_; - std::shared_ptr keypair_; + std::shared_ptr session_keys_; std::shared_ptr sr25519_provider_; }; } // namespace kagome::parachain From af994b1220cf1d2e595ff8cc4cdb24ba9404a5ac Mon Sep 17 00:00:00 2001 From: turuslan Date: Mon, 19 Sep 2022 11:10:47 +0300 Subject: [PATCH 11/11] fix Signed-off-by: turuslan --- core/parachain/CMakeLists.txt | 1 + core/parachain/validator/signer.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/core/parachain/CMakeLists.txt b/core/parachain/CMakeLists.txt index 867397c691..92d8c2e899 100644 --- a/core/parachain/CMakeLists.txt +++ b/core/parachain/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(validator_parachain ) target_link_libraries(validator_parachain + crypto_store req_collation_protocol collation_protocol protocol_error diff --git a/core/parachain/validator/signer.hpp b/core/parachain/validator/signer.hpp index 324fee331b..7d1870dc44 100644 --- a/core/parachain/validator/signer.hpp +++ b/core/parachain/validator/signer.hpp @@ -26,6 +26,7 @@ namespace kagome::parachain { /// Make signable message for payload. template auto signable(const T &payload) const { + // TODO(turuslan): Statement requires conversion return scale::encode(std::tie(payload, *this)); }