-
Notifications
You must be signed in to change notification settings - Fork 34
/
calculate_genesis_state.hpp
77 lines (69 loc) · 2.99 KB
/
calculate_genesis_state.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "application/chain_spec.hpp"
#include "runtime/common/uncompress_code_if_needed.hpp"
#include "runtime/heap_alloc_strategy_heappages.hpp"
#include "runtime/runtime_api/impl/core.hpp"
#include "runtime/runtime_instances_pool.hpp"
#include "runtime/wabt/version.hpp"
#include "storage/predefined_keys.hpp"
#include "storage/trie/polkadot_trie/polkadot_trie_impl.hpp"
#include "storage/trie/serialization/trie_serializer.hpp"
#include "storage/trie_pruner/trie_pruner.hpp"
namespace kagome::injector {
inline outcome::result<storage::trie::RootHash> calculate_genesis_state(
const application::ChainSpec &chain_spec,
const crypto::Hasher &hasher,
runtime::RuntimeInstancesPool &module_factory,
storage::trie::TrieSerializer &trie_serializer,
std::shared_ptr<runtime::RuntimePropertiesCache> runtime_cache) {
auto trie_from = [](const application::GenesisRawData &kv) {
auto trie = storage::trie::PolkadotTrieImpl::createEmpty();
for (auto &[k, v] : kv) {
trie->put(k, common::BufferView{v}).value();
}
return trie;
};
auto top_trie = trie_from(chain_spec.getGenesisTopSection());
OUTCOME_TRY(code, top_trie->get(storage::kRuntimeCodeKey));
auto code_hash = hasher.blake2b_256(code);
BOOST_OUTCOME_TRY(code, runtime::uncompressCodeIfNeeded(code));
OUTCOME_TRY(runtime_version, runtime::readEmbeddedVersion(code));
if (not runtime_version) {
runtime::MemoryLimits config;
BOOST_OUTCOME_TRY(config.heap_alloc_strategy,
heapAllocStrategyHeappagesDefault(*top_trie));
OUTCOME_TRY(instance,
module_factory.instantiateFromCode(
code_hash,
[&] { return std::make_shared<Buffer>(code); },
{config}));
OUTCOME_TRY(ctx, runtime::RuntimeContextFactory::stateless(instance));
auto version_res =
runtime_cache->getVersion(ctx.module_instance->getCodeHash(), [&] {
return ctx.module_instance
->callAndDecodeExportFunction<primitives::Version>(
ctx, "Core_version");
});
OUTCOME_TRY(version_res);
runtime_version = std::move(version_res.value());
}
auto version = storage::trie::StateVersion{runtime_version->state_version};
std::vector<std::shared_ptr<storage::trie::PolkadotTrie>> child_tries;
for (auto &[child, kv] : chain_spec.getGenesisChildrenDefaultSection()) {
child_tries.emplace_back(trie_from(kv));
OUTCOME_TRY(root,
trie_serializer.storeTrie(*child_tries.back(), version));
common::Buffer child2;
child2 += storage::kChildStorageDefaultPrefix;
child2 += child;
top_trie->put(child2, common::BufferView{root}).value();
}
OUTCOME_TRY(trie_hash, trie_serializer.storeTrie(*top_trie, version));
return trie_hash;
}
} // namespace kagome::injector