16 outcome::result<std::unique_ptr<RuntimeUpgradeTrackerImpl>>
18 std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo,
19 std::shared_ptr<storage::BufferStorage> storage,
20 std::shared_ptr<const primitives::CodeSubstituteBlockIds>
22 std::shared_ptr<blockchain::BlockStorage> block_storage) {
23 BOOST_ASSERT(header_repo);
24 BOOST_ASSERT(storage);
25 BOOST_ASSERT(code_substitutes);
26 BOOST_ASSERT(block_storage);
28 OUTCOME_TRY(encoded_opt,
31 std::vector<RuntimeUpgradeData> saved_data{};
32 if (encoded_opt.has_value()) {
35 scale::decode<std::vector<RuntimeUpgradeData>>(encoded_opt.value()));
36 saved_data = std::move(decoded);
38 return std::unique_ptr<RuntimeUpgradeTrackerImpl>{
41 std::move(code_substitutes),
42 std::move(saved_data),
43 std::move(block_storage))};
47 std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo,
48 std::shared_ptr<storage::BufferStorage> storage,
49 std::shared_ptr<const primitives::CodeSubstituteBlockIds>
51 std::vector<RuntimeUpgradeData> &&saved_data,
52 std::shared_ptr<blockchain::BlockStorage> block_storage)
75 last_finalized = block_info;
77 if (last_finalized.
number >= state.number) {
83 bool has_direct_chain =
84 block_tree_->hasDirectChain(state.hash, chain_end.hash);
86 return has_direct_chain;
89 outcome::result<std::optional<storage::trie::RootHash>>
92 std::vector<RuntimeUpgradeData>::const_reverse_iterator latest_upgrade_it)
95 OUTCOME_TRY(in_chain,
isStateInChain(latest_upgrade_it->block, block));
100 "Pick runtime state at block {} for block {}",
101 latest_upgrade_it->block,
104 return latest_upgrade_it->state;
110 outcome::result<storage::trie::RootHash>
122 OUTCOME_TRY(state,
push(block.
hash));
124 logger_,
"Pick runtime state at block {} for the same block", block);
125 return std::move(state);
129 auto block_number = block.
number;
130 auto latest_upgrade =
134 [](
auto block_number,
auto const &upgrade_data) {
135 return block_number < upgrade_data.block.number;
144 logger_,
"Pick runtime state at block {} for the same block", block);
145 return block_header.state_root;
149 auto reverse_latest_upgrade = std::make_reverse_iterator(latest_upgrade);
156 OUTCOME_TRY(proper_fork,
findProperFork(block, reverse_latest_upgrade));
158 if (proper_fork.has_value()) {
159 return proper_fork.value();
164 logger_->warn(
"Block {}, a child of block {} is orphan",
167 block_header.parent_hash));
168 return block_header.state_root;
171 outcome::result<primitives::BlockInfo>
174 auto it = std::find_if(
177 [&state](
const auto &item) {
return state == item.state; });
185 std::shared_ptr<primitives::events::ChainSubscriptionEngine>
187 std::shared_ptr<const blockchain::BlockTree> block_tree) {
192 std::make_shared<primitives::events::ChainEventSubscriber>(
196 auto chain_subscription_set_id =
199 chain_subscription_set_id,
209 const auto &block_hash =
210 boost::get<primitives::events::NewRuntimeEventParams>(
213 SL_INFO(
logger_,
"Runtime upgrade at block {}", block_hash.toHex());
214 (void)
push(block_hash);
220 OUTCOME_TRY(header,
header_repo_->getBlockHeader(hash));
222 std::move(header.state_root));
225 [](
const auto &lhs,
const auto &rhs) {
226 return lhs.block.number < rhs.block.number;
229 return header.state_root;
234 if (encoded_res.has_value()) {
237 if (not put_res.has_value()) {
239 "Could not store hashes of blocks changing runtime: {}",
240 put_res.error().message());
244 "Could not store hashes of blocks changing runtime: {}",
245 encoded_res.error().message());
254 return "Block hash for the given state not found among runtime upgrades.";
256 return "unknown error";
#define KAGOME_PROFILE_END(scope)
Class represents arbitrary (including empty) byte buffer.
std::vector< RuntimeUpgradeData > runtime_upgrades_
void subscribeToBlockchainEvents(std::shared_ptr< primitives::events::ChainSubscriptionEngine > chain_sub_engine, std::shared_ptr< const blockchain::BlockTree > block_tree)
outcome::result< std::optional< storage::trie::RootHash > > findProperFork(const primitives::BlockInfo &block, std::vector< RuntimeUpgradeData >::const_reverse_iterator latest_upgrade_it) const
#define SL_TRACE_FUNC_CALL(logger, ret,...)
std::shared_ptr< primitives::events::ChainEventSubscriber > chain_subscription_
boost::variant< std::nullopt_t, HeadsEventParams, RuntimeVersionEventParams, NewRuntimeEventParams > ChainEventParams
static outcome::result< std::unique_ptr< RuntimeUpgradeTrackerImpl > > create(std::shared_ptr< const blockchain::BlockHeaderRepository > header_repo, std::shared_ptr< storage::BufferStorage > storage, std::shared_ptr< const primitives::CodeSubstituteBlockIds > code_substitutes, std::shared_ptr< blockchain::BlockStorage > block_storage)
std::shared_ptr< storage::BufferStorage > storage_
outcome::result< primitives::BlockInfo > getLastCodeUpdateBlockInfo(const storage::trie::RootHash &state) const override
std::shared_ptr< const blockchain::BlockHeaderRepository > header_repo_
std::shared_ptr< const primitives::CodeSubstituteBlockIds > known_code_substitutes_
std::shared_ptr< blockchain::BlockStorage > block_storage_
RuntimeUpgradeTrackerError
bool hasCodeSubstitute(const kagome::primitives::BlockInfo &block_info) const
outcome::result< storage::trie::RootHash > getLastCodeUpdateState(const primitives::BlockInfo &block) override
OUTCOME_CPP_DEFINE_CATEGORY(kagome::runtime, RuntimeUpgradeTrackerError, e)
#define KAGOME_PROFILE_START(scope)
outcome::result< bool > isStateInChain(const primitives::BlockInfo &state, const primitives::BlockInfo &chain_end) const noexcept
std::shared_ptr< const blockchain::BlockTree > block_tree_
Logger createLogger(const std::string &tag)
outcome::result< storage::trie::RootHash > push(const primitives::BlockHash &hash)
RuntimeUpgradeTrackerImpl(std::shared_ptr< const blockchain::BlockHeaderRepository > header_repo, std::shared_ptr< storage::BufferStorage > storage, std::shared_ptr< const primitives::CodeSubstituteBlockIds > code_substitutes, std::vector< RuntimeUpgradeData > &&saved_data, std::shared_ptr< blockchain::BlockStorage > block_storage)
const common::Buffer kRuntimeHashesLookupKey