Skip to content

Commit

Permalink
Merge branch 'feature/kusama-fast-sync-fix' of github.com:soramitsu/k…
Browse files Browse the repository at this point in the history
…agome into feature/kusama-fast-sync-fix
  • Loading branch information
Harrm committed Oct 12, 2022
2 parents 9355c20 + bf70c8f commit 79663aa
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 25 deletions.
69 changes: 56 additions & 13 deletions core/consensus/authority/impl/authority_manager_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,25 +346,27 @@ namespace kagome::authority {
OUTCOME_TRY(root_header,
block_tree_->getBlockHeader(graph_root_block.hash));

OUTCOME_TRY(set_id_from_runtime, readSetIdFromRuntime(root_header));
auto set_id_from_runtime_res = readSetIdFromRuntime(root_header);

OUTCOME_TRY(opt_root, fetchScheduleGraphRoot(*persistent_storage_));
auto last_finalized_block = block_tree_->getLastFinalized();

if (opt_root
&& opt_root.value()->current_block.number
<= last_finalized_block.number) {
// FIXME: Correction to bypass bug where after finishing syncing and
// restarting the node we get a set id off by one
if (set_id_from_runtime.has_value()
// TODO(Harrm): #1334
// Correction to bypass the bug where after finishing syncing
// and restarting the node we get a set id off by one
if (set_id_from_runtime_res.has_value()
&& opt_root.value()->current_authorities->id
== set_id_from_runtime.value() - 1) {
== set_id_from_runtime_res.value() - 1) {
auto &authority_list =
opt_root.value()->current_authorities->authorities;
opt_root.value()->current_authorities =
std::make_shared<primitives::AuthoritySet>(
set_id_from_runtime.value(), authority_list);
set_id_from_runtime_res.value(), authority_list);
}

root_ = std::move(opt_root.value());
SL_DEBUG(log_,
"Fetched authority set graph root from database with id {}",
Expand All @@ -377,7 +379,7 @@ namespace kagome::authority {
std::make_shared<primitives::AuthoritySet>(
0, std::move(initial_authorities)),
{0, genesis_hash});
} else if (set_id_from_runtime.has_value()) {
} else if (set_id_from_runtime_res.has_value()){
SL_WARN(
log_,
"Storage does not contain valid info about the root authority set; "
Expand All @@ -387,7 +389,7 @@ namespace kagome::authority {
grandpa_api_->authorities(graph_root_block.hash));

auto authority_set = std::make_shared<primitives::AuthoritySet>(
set_id_from_runtime.value(), std::move(authorities));
set_id_from_runtime_res.value(), std::move(authorities));
root_ = authority::ScheduleNode::createAsRoot(authority_set,
graph_root_block);

Expand All @@ -397,11 +399,8 @@ namespace kagome::authority {
"storage",
root_->current_authorities->id);
} else {
SL_ERROR(log_,
"Fail to initialize authority manager: cannot retrieve the "
"current authority set id from either the database, the trie "
"storage, or the runtime API. Try --recovery.");
return AuthorityManagerError::FAILED_TO_INITIALIZE_SET_ID;
SL_ERROR(log_, "Failed to initialize authority manager; Try running recovery mode");
return set_id_from_runtime_res.as_failure();
}

while (not collected_msgs.empty()) {
Expand Down Expand Up @@ -613,12 +612,56 @@ namespace kagome::authority {
return outcome::success();
};

KAGOME_PROFILE_START(is_ancestor_node_finalized)
IsBlockFinalized is_ancestor_node_finalized =
ancestor_node->current_block == block_tree_->getLastFinalized()
or directChainExists(ancestor_node->current_block,
block_tree_->getLastFinalized());
KAGOME_PROFILE_END(is_ancestor_node_finalized)

// maybe_set contains last planned authority set, if present
std::optional<std::shared_ptr<const primitives::AuthoritySet>> maybe_set =
std::nullopt;
if (not is_ancestor_node_finalized) {
std::shared_ptr<const ScheduleNode> last_node = ancestor_node;
while (last_node and last_node != root_) {
if (const auto *action =
boost::get<ScheduleNode::ScheduledChange>(&last_node->action);
action != nullptr) {
if (block.number <= action->applied_block) {
// It's mean, that new Scheduled Changes would be scheduled before
// previous is activated. So we ignore it
return outcome::success();
}

if (action->new_authorities->id
> ancestor_node->current_authorities->id) {
maybe_set = action->new_authorities;
}
break;
}

last_node = last_node->parent.lock();
}
}

if (ancestor_node->current_block == block) {
if (maybe_set.has_value()) {
ancestor_node->current_authorities = maybe_set.value();
} else {
ancestor_node->adjust(is_ancestor_node_finalized);
}

OUTCOME_TRY(schedule_change(ancestor_node));
} else {
KAGOME_PROFILE_START(make_descendant)
auto new_node = ancestor_node->makeDescendant(block, true);
KAGOME_PROFILE_END(make_descendant)

if (maybe_set.has_value()) {
new_node->current_authorities = maybe_set.value();
}

SL_DEBUG(log_,
"Make a schedule node for block {}, with actual set id {}",
block,
Expand Down
2 changes: 1 addition & 1 deletion core/network/impl/peer_manager_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ namespace kagome::network {
kTimeoutForConnecting);
}

void PeerManagerImpl::disconnectFromPeer(const PeerId &peer_id) {
void PeerManagerImpl::disconnectFromPeer(PeerId peer_id) {
if (peer_id == own_peer_info_.id) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion core/network/impl/peer_manager_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ namespace kagome::network {
void connectToPeer(const PeerId &peer_id);

/// Closes all streams of provided peer
void disconnectFromPeer(const PeerId &peer_id);
void disconnectFromPeer(PeerId peer_id);

std::vector<scale::PeerInfoSerializable> loadLastActivePeers();

Expand Down
23 changes: 23 additions & 0 deletions core/network/types/collator_messages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "common/blob.hpp"
#include "consensus/grandpa/common.hpp"
#include "crypto/hasher.hpp"
#include "primitives/common.hpp"
#include "primitives/compact_integer.hpp"
#include "primitives/digest.hpp"
Expand Down Expand Up @@ -246,6 +247,28 @@ namespace kagome::network {
ViewUpdate /// view update message
>;

inline CandidateHash candidateHash(const crypto::Hasher &hasher,
const CandidateReceipt &receipt) {
return hasher.blake2b_256(scale::encode(receipt).value());
}

inline CandidateHash candidateHash(const crypto::Hasher &hasher,
const CommittedCandidateReceipt &receipt) {
return candidateHash(
hasher,
CandidateReceipt{
receipt.descriptor,
hasher.blake2b_256(scale::encode(receipt.commitments).value()),
});
}

inline CandidateHash candidateHash(const crypto::Hasher &hasher,
const CandidateState &statement) {
if (auto receipt = boost::get<CommittedCandidateReceipt>(&statement)) {
return candidateHash(hasher, *receipt);
}
return boost::get<CandidateHash>(statement);
}
} // namespace kagome::network

#endif // KAGOME_COLLATOR_DECLARE_HPP
2 changes: 1 addition & 1 deletion core/parachain/availability/bitfield/signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace kagome::parachain {
}

outcome::result<void> BitfieldSigner::sign(const ValidatorSigner &signer) {
auto &relay_parent = signer.context().relay_parent;
auto &relay_parent = signer.relayParent();
scale::BitVec bitfield;
OUTCOME_TRY(cores, parachain_api_->availability_cores(relay_parent));
bitfield.bits.reserve(cores.size());
Expand Down
9 changes: 7 additions & 2 deletions core/parachain/validator/signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,30 @@ namespace kagome::parachain {
ValidatorIndex validator_index,
SigningContext context,
std::shared_ptr<crypto::Sr25519Keypair> keypair,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider)
: validator_index_{validator_index},
context_{context},
keypair_{std::move(keypair)},
hasher_{std::move(hasher)},
sr25519_provider_{std::move(sr25519_provider)} {}

ValidatorSigner::ValidatorIndex ValidatorSigner::validatorIndex() const {
return validator_index_;
}

const SigningContext &ValidatorSigner::context() const {
return context_;
const primitives::BlockHash &ValidatorSigner::relayParent() const {
return context_.relay_parent;
}

ValidatorSignerFactory::ValidatorSignerFactory(
std::shared_ptr<runtime::ParachainHost> parachain_api,
std::shared_ptr<crypto::SessionKeys> session_keys,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider)
: parachain_api_{std::move(parachain_api)},
session_keys_{std::move(session_keys)},
hasher_{std::move(hasher)},
sr25519_provider_{std::move(sr25519_provider)} {}

outcome::result<std::optional<ValidatorSigner>> ValidatorSignerFactory::at(
Expand All @@ -58,6 +62,7 @@ namespace kagome::parachain {
validator_index,
context,
keypair,
hasher_,
sr25519_provider_,
};
}
Expand Down
30 changes: 23 additions & 7 deletions core/parachain/validator/signer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,19 @@

namespace kagome::parachain {
/// A type returned by runtime with current session index and a parent hash.
struct SigningContext {
class SigningContext {
private:
static auto &toSignable(const crypto::Hasher &, const scale::BitVec &v) {
return v;
}
static auto toSignable(const crypto::Hasher &hasher,
const network::CandidateState &v) {
constexpr std::array<uint8_t, 4> kMagic{'B', 'K', 'N', 'G'};
return std::make_tuple(
kMagic, static_cast<uint8_t>(v.which()), candidateHash(hasher, v));
}

public:
SCALE_TIE(2);

/// Make signing context for given block.
Expand All @@ -25,9 +37,9 @@ namespace kagome::parachain {

/// Make signable message for payload.
template <typename T>
auto signable(const T &payload) const {
// TODO(turuslan): Statement requires conversion
return scale::encode(std::tie(payload, *this));
auto signable(const crypto::Hasher &hasher, const T &payload) const {
auto &&signable = toSignable(hasher, payload);
return scale::encode(std::tie(signable, *this)).value();
}

/// Current session index.
Expand All @@ -44,12 +56,13 @@ namespace kagome::parachain {
ValidatorSigner(ValidatorIndex validator_index,
SigningContext context,
std::shared_ptr<crypto::Sr25519Keypair> keypair,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider);

/// Sign payload.
template <typename T>
outcome::result<network::Signed<T>> sign(T payload) const {
OUTCOME_TRY(data, context_.signable(payload));
auto data = context_.signable(*hasher_, payload);
OUTCOME_TRY(signature, sr25519_provider_->sign(*keypair_, data));
return network::Signed<T>{
std::move(payload),
Expand All @@ -61,13 +74,14 @@ namespace kagome::parachain {
/// Get validator index.
ValidatorIndex validatorIndex() const;

/// Get signing context.
const SigningContext &context() const;
/// Get relay parent hash.
const primitives::BlockHash &relayParent() const;

private:
ValidatorIndex validator_index_;
SigningContext context_;
std::shared_ptr<crypto::Sr25519Keypair> keypair_;
std::shared_ptr<crypto::Hasher> hasher_;
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider_;
};

Expand All @@ -77,6 +91,7 @@ namespace kagome::parachain {
ValidatorSignerFactory(
std::shared_ptr<runtime::ParachainHost> parachain_api,
std::shared_ptr<crypto::SessionKeys> session_keys,
std::shared_ptr<crypto::Hasher> hasher,
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider);

/// Create validator signer if keypair belongs to validator at given block.
Expand All @@ -86,6 +101,7 @@ namespace kagome::parachain {
private:
std::shared_ptr<runtime::ParachainHost> parachain_api_;
std::shared_ptr<crypto::SessionKeys> session_keys_;
std::shared_ptr<crypto::Hasher> hasher_;
std::shared_ptr<crypto::Sr25519Provider> sr25519_provider_;
};
} // namespace kagome::parachain
Expand Down
Loading

0 comments on commit 79663aa

Please sign in to comment.