Skip to content

Commit

Permalink
make justification ancestry (#2014)
Browse files Browse the repository at this point in the history
Signed-off-by: turuslan <[email protected]>
  • Loading branch information
turuslan authored Mar 22, 2024
1 parent 3848227 commit bda9f87
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 5 deletions.
7 changes: 4 additions & 3 deletions core/common/span_adl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ auto operator<=>(const SpanAdl<T> &l_, const auto &r_)
}

template <typename T>
bool operator==(const SpanAdl<T> &l_, const auto &r)
requires(requires { std::span<const T>{r}; })
bool operator==(const SpanAdl<T> &l_, const auto &r_)
requires(requires { std::span<const T>{r_}; })
{
return (l_ <=> r) == 0;
std::span r{r_};
return l_.v.size() == r.size() and (l_ <=> r) == 0;
}
3 changes: 3 additions & 0 deletions core/consensus/grandpa/environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ namespace kagome::consensus::grandpa {
/// authority set changes.
virtual outcome::result<void> reportEquivocation(
const VotingRound &round, const Equivocation &equivocation) const = 0;

virtual outcome::result<void> makeAncestry(
GrandpaJustification &justification) const = 0;
};

} // namespace kagome::consensus::grandpa
5 changes: 5 additions & 0 deletions core/consensus/grandpa/impl/environment_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "consensus/grandpa/has_authority_set_change.hpp"
#include "consensus/grandpa/i_verified_justification_queue.hpp"
#include "consensus/grandpa/justification_observer.hpp"
#include "consensus/grandpa/make_ancestry.hpp"
#include "consensus/grandpa/movable_round_state.hpp"
#include "consensus/grandpa/voting_round.hpp"
#include "consensus/grandpa/voting_round_error.hpp"
Expand Down Expand Up @@ -504,4 +505,8 @@ namespace kagome::consensus::grandpa {
return outcome::success();
}

outcome::result<void> EnvironmentImpl::makeAncestry(
GrandpaJustification &justification) const {
return grandpa::makeAncestry(justification, *block_tree_);
}
} // namespace kagome::consensus::grandpa
3 changes: 3 additions & 0 deletions core/consensus/grandpa/impl/environment_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ namespace kagome::consensus::grandpa {
const VotingRound &round,
const Equivocation &equivocation) const override;

outcome::result<void> makeAncestry(
GrandpaJustification &justification) const override;

private:
std::shared_ptr<blockchain::BlockTree> block_tree_;
std::shared_ptr<blockchain::BlockHeaderRepository> header_repository_;
Expand Down
5 changes: 4 additions & 1 deletion core/consensus/grandpa/impl/voting_round_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,10 @@ namespace kagome::consensus::grandpa {
.round_number = round_number_,
.block_info = block,
.items = getPrecommitJustification(block, precommits_->getMessages())};
// TODO(turuslan): #1931, make justification ancestry

if (auto r = env_->makeAncestry(justification); not r) {
SL_ERROR(logger_, "doCommit: makeAncestry: {}", r.error());
}

SL_DEBUG(logger_,
"Round #{}: Sending commit message for block {}",
Expand Down
40 changes: 40 additions & 0 deletions core/consensus/grandpa/make_ancestry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <unordered_set>

#include "blockchain/block_tree.hpp"
#include "consensus/grandpa/structs.hpp"
#include "consensus/grandpa/voting_round_error.hpp"

namespace kagome::consensus::grandpa {
/**
* Make ancestry merke proof for GrandpaJustification.
* https://github.com/paritytech/polkadot-sdk/blob/4842faf65d3628586d304fbcb6cb19b17b4a629c/substrate/client/consensus/grandpa/src/justification.rs#L64-L126
*/
inline outcome::result<void> makeAncestry(
GrandpaJustification &justification,
const blockchain::BlockTree &block_tree) {
std::vector<primitives::BlockHeader> blocks;
std::unordered_set<primitives::BlockInfo> seen;
for (auto &m : justification.items) {
auto info = m.getBlockInfo();
while (info != justification.block_info and not seen.contains(info)) {
if (info.number <= justification.block_info.number) {
return VotingRoundError::CANT_MAKE_ANCESTRY;
}
OUTCOME_TRY(block, block_tree.getBlockHeader(info.hash));
seen.emplace(info);
info = *block.parentInfo();
blocks.emplace_back(std::move(block));
}
}
justification.votes_ancestries = blocks;
return outcome::success();
}
} // namespace kagome::consensus::grandpa
2 changes: 2 additions & 0 deletions core/consensus/grandpa/voting_round_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ OUTCOME_CPP_DEFINE_CATEGORY(kagome::consensus::grandpa, VotingRoundError, e) {
return "Can't get best prevote candidate";
case E::ROUND_IS_NOT_FINALIZABLE:
return "Round is not finalizable";
case E::CANT_MAKE_ANCESTRY:
return "Can't make ancestry";
}
return "Unknown error (invalid VotingRoundError)";
}
3 changes: 2 additions & 1 deletion core/consensus/grandpa/voting_round_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace kagome::consensus::grandpa {
EQUIVOCATED_VOTE,
VOTE_OF_KNOWN_EQUIVOCATOR,
NO_PREVOTE_CANDIDATE,
ROUND_IS_NOT_FINALIZABLE
ROUND_IS_NOT_FINALIZABLE,
CANT_MAKE_ANCESTRY,
};

}
Expand Down
5 changes: 5 additions & 0 deletions test/mock/core/consensus/grandpa/environment_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ namespace kagome::consensus::grandpa {
std::vector<SignedPrecommit> precommit_justification,
BlockInfo best_final_candidate),
(override));

MOCK_METHOD(outcome::result<void>,
makeAncestry,
(GrandpaJustification &),
(const, override));
};

} // namespace kagome::consensus::grandpa

0 comments on commit bda9f87

Please sign in to comment.