Kagome
Polkadot Runtime Engine in C++17
digest.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_CORE_PRIMITIVES_DIGEST
7 #define KAGOME_CORE_PRIMITIVES_DIGEST
8 
9 #include <boost/variant.hpp>
10 
11 #include "common/buffer.hpp"
12 #include "common/tagged.hpp"
13 #include "common/unused.hpp"
15 #include "consensus/constants.hpp"
18 #include "scale/scale.hpp"
19 #include "scale/tie.hpp"
20 
21 namespace kagome::primitives {
24 
25  inline const auto kBabeEngineId =
26  ConsensusEngineId::fromString("BABE").value();
27 
28  inline const auto kGrandpaEngineId =
29  ConsensusEngineId::fromString("FRNK").value();
30 
31  inline const auto kUnsupportedEngineId_POL1 =
32  ConsensusEngineId::fromString("POL1").value();
33 
34  inline const auto kUnsupportedEngineId_BEEF =
35  ConsensusEngineId::fromString("BEEF").value();
36 
37  struct Other : public common::Buffer {};
38 
39  namespace detail {
41  SCALE_TIE(2);
42 
44 
46  };
47  } // namespace detail
48 
56 
58  using BabeDigest =
60  boost::variant<Unused<0>,
61  NextEpochData, // 1: (Auth C; R)
62  OnDisabled, // 2: Auth ID
63  NextConfigData>; // 3: c, S2nd
64 
66  using GrandpaDigest =
68  boost::variant<Unused<0>,
69  ScheduledChange, // 1: (Auth C; N delay)
70  ForcedChange, // 2: (Auth C; N delay)
71  OnDisabled, // 3: Auth ID
72  Pause, // 4: N delay
73  Resume>; // 5: N delay
74 
77 
79  static outcome::result<DecodedConsensusMessage> create(
80  ConsensusEngineId engine_id, const common::Buffer &data) {
81  if (engine_id == primitives::kBabeEngineId) {
82  OUTCOME_TRY(payload, scale::decode<BabeDigest>(data));
83  return DecodedConsensusMessage{engine_id, std::move(payload)};
84  } else if (engine_id == primitives::kGrandpaEngineId) {
85  OUTCOME_TRY(payload, scale::decode<GrandpaDigest>(data));
86  return DecodedConsensusMessage{engine_id, std::move(payload)};
87  } else if (engine_id == primitives::kUnsupportedEngineId_POL1) {
88  OUTCOME_TRY(payload, scale::decode<UnsupportedDigest_POL1>(data));
89  return DecodedConsensusMessage{engine_id, std::move(payload)};
90  } else if (engine_id == primitives::kUnsupportedEngineId_BEEF) {
91  OUTCOME_TRY(payload, scale::decode<UnsupportedDigest_BEEF>(data));
92  return DecodedConsensusMessage{engine_id, std::move(payload)};
93  }
94  BOOST_ASSERT_MSG(false, "Invalid consensus engine id");
95  BOOST_UNREACHABLE_RETURN({})
96  }
97 
98  const BabeDigest &asBabeDigest() const {
99  BOOST_ASSERT(consensus_engine_id == primitives::kBabeEngineId);
100  return boost::relaxed_get<BabeDigest>(digest);
101  }
102 
103  template <typename T>
104  bool isBabeDigestOf() const {
105  return consensus_engine_id == primitives::kBabeEngineId
106  && boost::get<T>(&asBabeDigest()) != nullptr;
107  }
108 
110  BOOST_ASSERT(consensus_engine_id == primitives::kGrandpaEngineId);
111  return boost::relaxed_get<GrandpaDigest>(digest);
112  }
113 
114  template <typename T>
115  bool isGrandpaDigestOf() const {
116  return consensus_engine_id == primitives::kGrandpaEngineId
117  && boost::get<T>(&asGrandpaDigest()) != nullptr;
118  }
119 
121  boost::variant<BabeDigest,
125  digest{};
126 
127  private:
128  DecodedConsensusMessage() = default;
129  };
130 
135  Consensus() = default;
136 
137  // Note: this ctor is needed only for tests
138  template <class A>
139  Consensus(const A &a) {
140  // clang-format off
141  if constexpr (std::is_same_v<A, NextEpochData>
142  or std::is_same_v<A, NextConfigData>) {
143  consensus_engine_id = primitives::kBabeEngineId;
144  data = common::Buffer(scale::encode(BabeDigest(a)).value());
145  } else if constexpr (std::is_same_v<A, ScheduledChange>
146  or std::is_same_v<A, ForcedChange>
147  or std::is_same_v<A, OnDisabled>
148  or std::is_same_v<A, Pause>
149  or std::is_same_v<A, Resume>) {
150  consensus_engine_id = primitives::kGrandpaEngineId;
151  data = common::Buffer(scale::encode(GrandpaDigest(a)).value());
152  } else {
153  BOOST_UNREACHABLE_RETURN();
154  }
155  // clang-format on
156  }
157 
158  outcome::result<DecodedConsensusMessage> decode() const {
159  return DecodedConsensusMessage::create(consensus_engine_id, data);
160  }
161  };
162 
165  struct Seal : public detail::DigestItemCommon {};
166 
168  struct RuntimeEnvironmentUpdated : public Empty {};
169 
174  using DigestItem = boost::variant<Other, // 0
175  Unused<1>, // 1
176  Unused<2>, // 2
177  Unused<3>, // 3
178  Consensus, // 4
179  Seal, // 5
180  PreRuntime, // 6
181  Unused<7>, // 7
183 
184  namespace {
185  // This value is enough to disable each of validators in each of two
186  // consensus engines
187  constexpr auto kMaxItemsInDigest = consensus::kMaxValidatorsNumber * 4;
188  } // namespace
189 
195 
196 } // namespace kagome::primitives
197 
198 #endif // KAGOME_CORE_PRIMITIVES_DIGEST
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
boost::variant< Unused< 0 >, ScheduledChange, ForcedChange, OnDisabled, Pause, Resume > GrandpaDigest
https://github.com/paritytech/substrate/blob/polkadot-v0.9.8/primitives/finality-grandpa/src/lib.rs#L92
Definition: digest.hpp:73
const GrandpaDigest & asGrandpaDigest() const
Definition: digest.hpp:109
Runtime code or heap pages updated.
Definition: digest.hpp:168
const auto kUnsupportedEngineId_POL1
Definition: digest.hpp:31
#define SCALE_TIE(N)
Definition: tie.hpp:11
const auto kUnsupportedEngineId_BEEF
Definition: digest.hpp:34
Tagged< Empty, struct POL1 > UnsupportedDigest_POL1
Definition: digest.hpp:75
const BabeDigest & asBabeDigest() const
Definition: digest.hpp:98
SLBuffer< std::numeric_limits< size_t >::max()> Buffer
Definition: buffer.hpp:244
static outcome::result< Blob< size_ > > fromString(std::string_view data)
Definition: blob.hpp:169
constexpr size_t kMaxValidatorsNumber
Definition: constants.hpp:11
boost::variant< Unused< 0 >, NextConfigDataV1 > NextConfigData
static outcome::result< DecodedConsensusMessage > create(ConsensusEngineId engine_id, const common::Buffer &data)
Definition: digest.hpp:79
boost::variant< Other, Unused< 1 >, Unused< 2 >, Unused< 3 >, Consensus, Seal, PreRuntime, Unused< 7 >, RuntimeEnvironmentUpdated > DigestItem
Definition: digest.hpp:182
common::SLBuffer< consensus::kMaxValidatorsNumber *1024 > data
Definition: digest.hpp:45
const auto kGrandpaEngineId
Definition: digest.hpp:28
const auto kBabeEngineId
Definition: digest.hpp:25
boost::variant< Unused< 0 >, NextEpochData, OnDisabled, NextConfigData > BabeDigest
https://github.com/paritytech/substrate/blob/polkadot-v0.9.8/primitives/consensus/babe/src/lib.rs#L130
Definition: digest.hpp:63
outcome::result< DecodedConsensusMessage > decode() const
Definition: digest.hpp:158