18 case E::PARENT_FACTORY_EXPIRED:
19 return "The parent factory has expired";
21 return "Failed to obtain the required block from storage";
22 case E::ABSENT_HEAP_BASE:
23 return "Failed to extract heap base from a module";
24 case E::FAILED_TO_SET_STORAGE_STATE:
25 return "Failed to set the storage state to the desired value";
27 return "Unknown runtime environment construction error";
34 std::shared_ptr<ModuleInstance> module_instance,
35 std::shared_ptr<const MemoryProvider> memory_provider,
36 std::shared_ptr<TrieStorageProvider> storage_provider,
38 : module_instance{std::move(module_instance)},
49 std::weak_ptr<const RuntimeEnvironmentFactory> parent_factory,
64 outcome::result<std::unique_ptr<RuntimeEnvironment>>
68 if (parent_factory ==
nullptr) {
74 parent_factory->logger_->error(
75 "Failed to obtain the block {} when initializing a runtime " 76 "environment; Reason: {}",
78 header_res.error().message());
83 parent_factory->module_repo_->getInstanceAt(
84 parent_factory->code_provider_,
88 const auto &
env = instance->getEnvironment();
92 SL_DEBUG(parent_factory->logger_,
93 "Failed to set the storage state to hash {:l} when initializing a " 94 "runtime environment; Reason: {}",
96 res.error().message());
102 SL_DEBUG(parent_factory->logger_,
103 "Failed to set the storage state to hash {:l} when initializing a " 104 "runtime environment; Reason: {}",
106 res.error().message());
111 OUTCOME_TRY(opt_heap_base, instance->getGlobal(
"__heap_base"));
112 if (!opt_heap_base.has_value()) {
113 parent_factory->logger_->error(
114 "__heap_base global variable is not found in a runtime module");
117 int32_t heap_base = boost::get<int32_t>(opt_heap_base.value());
119 OUTCOME_TRY(
env.memory_provider->resetMemory(heap_base));
121 auto heappages_key =
":heappages"_buf;
123 env.storage_provider->getCurrentBatch()->get(heappages_key);
124 if (heappages_res.has_value()) {
125 const auto &heappages = heappages_res.value().get();
126 if (
sizeof(uint64_t) != heappages.size()) {
127 parent_factory->logger_->error(
128 "Unable to read :heappages value. Type size mismatch. " 129 "Required {} bytes, but {} available",
134 env.memory_provider->getCurrentMemory()->get().resize(
136 parent_factory->logger_->trace(
137 "Creating wasm module with non-default :heappages value set to {}",
141 != heappages_res.error()) {
142 return heappages_res.error();
145 auto &memory =
env.memory_provider->getCurrentMemory()->get();
146 instance->forDataSegment([&memory](
auto offset,
auto segment) {
147 memory.storeBuffer(offset, segment);
150 SL_DEBUG(parent_factory->logger_,
151 "Runtime environment at {}, state: {:l}",
155 auto runtime_env = std::make_unique<RuntimeEnvironment>(
162 std::shared_ptr<const runtime::RuntimeCodeProvider> code_provider,
163 std::shared_ptr<ModuleRepository> module_repo,
164 std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo)
174 std::unique_ptr<RuntimeEnvironmentFactory::RuntimeEnvironmentTemplate>
178 return std::make_unique<RuntimeEnvironmentTemplate>(
179 weak_from_this(), blockchain_state, storage_state);
183 std::unique_ptr<RuntimeEnvironmentFactory::RuntimeEnvironmentTemplate>>
186 OUTCOME_TRY(header,
header_repo_->getBlockHeader(block_hash));
187 return start({header.number, std::move(block_hash)},
188 std::move(header.state_root));
192 std::unique_ptr<RuntimeEnvironmentFactory::RuntimeEnvironmentTemplate>>
197 "Failed to obtain the genesis block for runtime executor " 198 "initialization; Reason: {}",
199 genesis_hash.error().message());
202 return start(genesis_hash.value());
primitives::BlockInfo blockchain_state_
#define KAGOME_PROFILE_END(scope)
virtual outcome::result< std::unique_ptr< RuntimeEnvironmentTemplate > > start() const
returns a handle to make a RuntimeEnvironment at genesis block state
uint64_t le_bytes_to_uint64(gsl::span< const uint8_t, 8 > bytes)
const std::shared_ptr< const MemoryProvider > memory_provider
static const wasm::Name env
const std::shared_ptr< TrieStorageProvider > storage_provider
std::weak_ptr< const RuntimeEnvironmentFactory > parent_factory_
RuntimeEnvironment(std::shared_ptr< ModuleInstance > module_instance, std::shared_ptr< const MemoryProvider > memory_provider, std::shared_ptr< TrieStorageProvider > storage_provider, primitives::BlockInfo blockchain_state)
RuntimeEnvironmentFactory(std::shared_ptr< const runtime::RuntimeCodeProvider > code_provider, std::shared_ptr< ModuleRepository > module_repo, std::shared_ptr< const blockchain::BlockHeaderRepository > header_repo)
std::shared_ptr< const blockchain::BlockHeaderRepository > header_repo_
virtual outcome::result< std::unique_ptr< RuntimeEnvironment > > make()
std::shared_ptr< const runtime::RuntimeCodeProvider > code_provider_
constexpr size_t kMemoryPageSize
std::shared_ptr< ModuleRepository > module_repo_
OUTCOME_CPP_DEFINE_CATEGORY(kagome::runtime, RuntimeEnvironmentFactory::Error, e)
virtual RuntimeEnvironmentTemplate & persistent()
#define KAGOME_PROFILE_START(scope)
RuntimeEnvironmentTemplate(std::weak_ptr< const RuntimeEnvironmentFactory > parent_factory_, const primitives::BlockInfo &blockchain_state, const storage::trie::RootHash &storage_state)
storage::trie::RootHash storage_state_
Logger createLogger(const std::string &tag)
const std::shared_ptr< ModuleInstance > module_instance
primitives::BlockInfo blockchain_state_