From 6d7108293637a0f0400c455923e08a84441dc343 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Mon, 31 Oct 2022 23:23:46 +0800 Subject: [PATCH 01/13] feature: runtime properties cache Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/injector/CMakeLists.txt | 1 + core/injector/application_injector.cpp | 12 +++--- .../binaryen/core_api_factory_impl.cpp | 4 +- core/runtime/common/executor.hpp | 8 +++- core/runtime/runtime_api/impl/CMakeLists.txt | 7 ++++ core/runtime/runtime_api/impl/core.cpp | 2 +- .../impl/runtime_properties_cache_impl.cpp | 33 +++++++++++++++ .../impl/runtime_properties_cache_impl.hpp | 34 +++++++++++++++ core/runtime/runtime_properties_cache.hpp | 41 +++++++++++++++++++ core/runtime/wavm/core_api_factory_impl.cpp | 4 +- 10 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 core/runtime/runtime_api/impl/runtime_properties_cache_impl.cpp create mode 100644 core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp create mode 100644 core/runtime/runtime_properties_cache.hpp diff --git a/core/injector/CMakeLists.txt b/core/injector/CMakeLists.txt index 003bbdb129..0e2929aa91 100644 --- a/core/injector/CMakeLists.txt +++ b/core/injector/CMakeLists.txt @@ -82,6 +82,7 @@ target_link_libraries(application_injector rpc_thread_pool runtime_upgrade_tracker runtime_environment_factory + runtime_properties_cache executor secp256k1_provider soralog::fallback_configurator diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 038fb0e9cc..36b8eb92d8 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -134,6 +134,7 @@ #include "runtime/runtime_api/impl/metadata.hpp" #include "runtime/runtime_api/impl/offchain_worker_api.hpp" #include "runtime/runtime_api/impl/parachain_host.hpp" +#include "runtime/runtime_api/impl/runtime_properties_cache_impl.hpp" #include "runtime/runtime_api/impl/session_keys_api.hpp" #include "runtime/runtime_api/impl/tagged_transaction_queue.hpp" #include "runtime/runtime_api/impl/transaction_payment_api.hpp" @@ -914,12 +915,10 @@ namespace { if (!initialized) { auto env_factory = injector.template create< std::shared_ptr<runtime::RuntimeEnvironmentFactory>>(); - auto header_repo = injector.template create< - std::shared_ptr<blockchain::BlockHeaderRepository>>(); - auto storage = injector.template create< - std::shared_ptr<storage::trie::TrieStorage>>(); - initialized = - std::make_shared<runtime::Executor>(std::move(env_factory)); + auto cache = injector.template create< + std::shared_ptr<runtime::RuntimePropertiesCache>>(); + initialized = std::make_shared<runtime::Executor>( + std::move(env_factory), std::move(cache)); } return initialized.value(); }), @@ -942,6 +941,7 @@ namespace { di::bind<runtime::AccountNonceApi>.template to<runtime::AccountNonceApiImpl>(), di::bind<runtime::AuthorityDiscoveryApi>.template to<runtime::AuthorityDiscoveryApiImpl>(), di::bind<runtime::SingleModuleCache>.template to<runtime::SingleModuleCache>(), + di::bind<runtime::RuntimePropertiesCache>.template to<runtime::RuntimePropertiesCacheImpl>(), std::forward<Ts>(args)...); } diff --git a/core/runtime/binaryen/core_api_factory_impl.cpp b/core/runtime/binaryen/core_api_factory_impl.cpp index 0d01ec4886..8e3f9b74c2 100644 --- a/core/runtime/binaryen/core_api_factory_impl.cpp +++ b/core/runtime/binaryen/core_api_factory_impl.cpp @@ -12,6 +12,7 @@ #include "runtime/common/executor.hpp" #include "runtime/common/trie_storage_provider_impl.hpp" #include "runtime/runtime_api/impl/core.hpp" +#include "runtime/runtime_api/impl/runtime_properties_cache_impl.hpp" namespace kagome::runtime::binaryen { @@ -75,7 +76,8 @@ namespace kagome::runtime::binaryen { std::make_shared<OneModuleRepository>(runtime_code, instance_env_factory_), header_repo_); - auto executor = std::make_unique<Executor>(env_factory); + auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); + auto executor = std::make_unique<Executor>(env_factory, cache); return std::make_unique<CoreImpl>( std::move(executor), changes_tracker_, header_repo_); } diff --git a/core/runtime/common/executor.hpp b/core/runtime/common/executor.hpp index 4fbf53797b..68826cb811 100644 --- a/core/runtime/common/executor.hpp +++ b/core/runtime/common/executor.hpp @@ -21,6 +21,7 @@ #include "runtime/module_repository.hpp" #include "runtime/persistent_result.hpp" #include "runtime/runtime_environment_factory.hpp" +#include "runtime/runtime_properties_cache.hpp" #include "runtime/trie_storage_provider.hpp" #include "scale/scale.hpp" #include "storage/trie/trie_batches.hpp" @@ -37,8 +38,10 @@ namespace kagome::runtime { public: using Buffer = common::Buffer; - Executor(std::shared_ptr<RuntimeEnvironmentFactory> env_factory) - : env_factory_{std::move(env_factory)}, + Executor(std::shared_ptr<RuntimeEnvironmentFactory> env_factory, + std::shared_ptr<RuntimePropertiesCache> cache) + : env_factory_(std::move(env_factory)), + cache_(std::move(cache)), logger_{log::createLogger("Executor", "runtime")} { BOOST_ASSERT(env_factory_ != nullptr); } @@ -254,6 +257,7 @@ namespace kagome::runtime { } std::shared_ptr<RuntimeEnvironmentFactory> env_factory_; + std::shared_ptr<RuntimePropertiesCache> cache_; log::Logger logger_; }; diff --git a/core/runtime/runtime_api/impl/CMakeLists.txt b/core/runtime/runtime_api/impl/CMakeLists.txt index 1afe4fd392..125ecee707 100644 --- a/core/runtime/runtime_api/impl/CMakeLists.txt +++ b/core/runtime/runtime_api/impl/CMakeLists.txt @@ -26,4 +26,11 @@ target_link_libraries(offchain_worker_api offchain_worker) add_library(session_keys_api session_keys_api.cpp) target_link_libraries(session_keys_api executor) +add_library(runtime_properties_cache + runtime_properties_cache_impl.cpp + ) +target_link_libraries(runtime_properties_cache + executor + ) + diff --git a/core/runtime/runtime_api/impl/core.cpp b/core/runtime/runtime_api/impl/core.cpp index c4a9e027e4..466d7b8ac6 100644 --- a/core/runtime/runtime_api/impl/core.cpp +++ b/core/runtime/runtime_api/impl/core.cpp @@ -24,7 +24,7 @@ namespace kagome::runtime { } outcome::result<primitives::Version> CoreImpl::version( - primitives::BlockHash const &block) { + const primitives::BlockHash &block) { return executor_->callAt<primitives::Version>(block, "Core_version"); } diff --git a/core/runtime/runtime_api/impl/runtime_properties_cache_impl.cpp b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.cpp new file mode 100644 index 0000000000..4675169641 --- /dev/null +++ b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.cpp @@ -0,0 +1,33 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "runtime_properties_cache_impl.hpp" + +namespace kagome::runtime { + + outcome::result<primitives::Version> RuntimePropertiesCacheImpl::getVersion( + const common::Hash256 &hash, + std::function<outcome::result<primitives::Version>()> obtainer) { + auto it = cached_versions_.find(hash); + if (it == cached_versions_.end()) { + OUTCOME_TRY(version, obtainer()); + it = cached_versions_.emplace(hash, std::move(version)).first; + } + return it->second; + } + + outcome::result<primitives::OpaqueMetadata> + RuntimePropertiesCacheImpl::getMetadata( + const common::Hash256 &hash, + std::function<outcome::result<primitives::OpaqueMetadata>()> obtainer) { + auto it = cached_metadata_.find(hash); + if (it == cached_metadata_.end()) { + OUTCOME_TRY(metadata, obtainer()); + it = cached_metadata_.emplace(hash, std::move(metadata)).first; + } + return it->second; + } + +} // namespace kagome::runtime diff --git a/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp new file mode 100644 index 0000000000..c380efb19a --- /dev/null +++ b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp @@ -0,0 +1,34 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEIMPL +#define KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEIMPL + +#include "runtime/runtime_properties_cache.hpp" + +namespace kagome::runtime { + + class RuntimePropertiesCacheImpl final : public RuntimePropertiesCache { + public: + RuntimePropertiesCacheImpl() {} + + outcome::result<primitives::Version> getVersion( + const common::Hash256 &hash, + std::function<outcome::result<primitives::Version>()> obtainer) + override; + + outcome::result<primitives::OpaqueMetadata> getMetadata( + const common::Hash256 &hash, + std::function<outcome::result<primitives::OpaqueMetadata>()> obtainer) + override; + + private: + std::map<common::Hash256, primitives::Version> cached_versions_; + std::map<common::Hash256, primitives::OpaqueMetadata> cached_metadata_; + }; + +} // namespace kagome::runtime + +#endif // KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEIMPL diff --git a/core/runtime/runtime_properties_cache.hpp b/core/runtime/runtime_properties_cache.hpp new file mode 100644 index 0000000000..b12c811e14 --- /dev/null +++ b/core/runtime/runtime_properties_cache.hpp @@ -0,0 +1,41 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHE +#define KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHE + +#include "common/blob.hpp" +#include "outcome/outcome.hpp" +#include "primitives/opaque_metadata.hpp" +#include "primitives/version.hpp" + +namespace kagome::runtime { + + /** + * Cache for runtime properties (as Version and Metadata) + * Allows loading and compiling a module directly from its web assembly byte + * code and instantiating a runtime module at an arbitrary block + */ + class RuntimePropertiesCache { + public: + virtual ~RuntimePropertiesCache() = default; + + virtual outcome::result<primitives::Version> getVersion( + const common::Hash256 &hash, + std::function<outcome::result<primitives::Version>()> obtainer) = 0; + + virtual outcome::result<primitives::OpaqueMetadata> getMetadata( + const common::Hash256 &hash, + std::function<outcome::result<primitives::OpaqueMetadata>()> + obtainer) = 0; + }; + +} // namespace kagome::runtime + +#endif // KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHE diff --git a/core/runtime/wavm/core_api_factory_impl.cpp b/core/runtime/wavm/core_api_factory_impl.cpp index 82faf372b4..49686e7846 100644 --- a/core/runtime/wavm/core_api_factory_impl.cpp +++ b/core/runtime/wavm/core_api_factory_impl.cpp @@ -10,6 +10,7 @@ #include "runtime/common/trie_storage_provider_impl.hpp" #include "runtime/module_repository.hpp" #include "runtime/runtime_api/impl/core.hpp" +#include "runtime/runtime_api/impl/runtime_properties_cache_impl.hpp" #include "runtime/runtime_environment_factory.hpp" #include "runtime/wavm/compartment_wrapper.hpp" #include "runtime/wavm/instance_environment_factory.hpp" @@ -126,7 +127,8 @@ namespace kagome::runtime::wavm { runtime_code.size())}, last_compiled_module_), block_header_repo_); - auto executor = std::make_unique<runtime::Executor>(env_factory); + auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); + auto executor = std::make_unique<runtime::Executor>(env_factory, cache); return std::make_unique<CoreImpl>( std::move(executor), changes_tracker_, block_header_repo_); } From ea7ef78b55a174e52730bb6f08b5aacfa903d0ab Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Wed, 2 Nov 2022 14:41:38 +0800 Subject: [PATCH 02/13] feature: remember code hash with module Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/injector/application_injector.cpp | 3 ++- core/runtime/binaryen/core_api_factory_impl.cpp | 17 ++++++++++++----- .../binaryen/module/module_factory_impl.cpp | 10 +++++++--- .../binaryen/module/module_factory_impl.hpp | 8 +++++++- core/runtime/binaryen/module/module_impl.cpp | 17 ++++++++++------- core/runtime/binaryen/module/module_impl.hpp | 9 ++++++--- .../binaryen/module/module_instance_impl.cpp | 4 +++- .../binaryen/module/module_instance_impl.hpp | 9 ++++++++- core/runtime/common/runtime_instances_pool.cpp | 11 +++++++++++ core/runtime/module_instance.hpp | 2 ++ core/runtime/wavm/core_api_factory_impl.cpp | 7 ++++++- core/runtime/wavm/module.cpp | 12 ++++++++---- core/runtime/wavm/module.hpp | 8 ++++++-- core/runtime/wavm/module_factory_impl.cpp | 16 ++++++++++++---- core/runtime/wavm/module_factory_impl.hpp | 7 ++++++- core/runtime/wavm/module_instance.cpp | 4 +++- core/runtime/wavm/module_instance.hpp | 9 ++++++++- 17 files changed, 117 insertions(+), 36 deletions(-) diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 36b8eb92d8..2cd771f47e 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -901,7 +901,8 @@ namespace { sptr<runtime::wavm::InstanceEnvironmentFactory>>(), injector .template create<sptr<runtime::wavm::IntrinsicModule>>(), - module_cache_opt); + module_cache_opt, + injector.template create<sptr<crypto::Hasher>>()); }), di::bind<runtime::ModuleFactory>.template to( [method](const auto &injector) { diff --git a/core/runtime/binaryen/core_api_factory_impl.cpp b/core/runtime/binaryen/core_api_factory_impl.cpp index 8e3f9b74c2..712ccb2348 100644 --- a/core/runtime/binaryen/core_api_factory_impl.cpp +++ b/core/runtime/binaryen/core_api_factory_impl.cpp @@ -20,8 +20,11 @@ namespace kagome::runtime::binaryen { public: OneModuleRepository( const std::vector<uint8_t> &code, - std::shared_ptr<const InstanceEnvironmentFactory> env_factory) - : env_factory_{std::move(env_factory)}, code_{code} { + std::shared_ptr<const InstanceEnvironmentFactory> env_factory, + const common::Hash256 &code_hash) + : env_factory_{std::move(env_factory)}, + code_{code}, + code_hash_(code_hash) { BOOST_ASSERT(env_factory_); } @@ -30,7 +33,9 @@ namespace kagome::runtime::binaryen { const primitives::BlockInfo &, const primitives::BlockHeader &) override { if (instance_ == nullptr) { - OUTCOME_TRY(module, ModuleImpl::createFromCode(code_, env_factory_)); + OUTCOME_TRY( + module, + ModuleImpl::createFromCode(code_, env_factory_, code_hash_)); OUTCOME_TRY(inst, module->instantiate()); instance_ = std::move(inst); } @@ -41,6 +46,7 @@ namespace kagome::runtime::binaryen { std::shared_ptr<ModuleInstance> instance_; std::shared_ptr<const InstanceEnvironmentFactory> env_factory_; const std::vector<uint8_t> &code_; + const common::Hash256 code_hash_; }; class OneCodeProvider final : public RuntimeCodeProvider { @@ -71,10 +77,11 @@ namespace kagome::runtime::binaryen { std::unique_ptr<Core> CoreApiFactoryImpl::make( std::shared_ptr<const crypto::Hasher> hasher, const std::vector<uint8_t> &runtime_code) const { + auto code_hash = hasher->sha2_256(runtime_code); auto env_factory = std::make_shared<runtime::RuntimeEnvironmentFactory>( std::make_shared<OneCodeProvider>(runtime_code), - std::make_shared<OneModuleRepository>(runtime_code, - instance_env_factory_), + std::make_shared<OneModuleRepository>( + runtime_code, instance_env_factory_, code_hash), header_repo_); auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); auto executor = std::make_unique<Executor>(env_factory, cache); diff --git a/core/runtime/binaryen/module/module_factory_impl.cpp b/core/runtime/binaryen/module/module_factory_impl.cpp index c5cbd64af2..9662dbf5e9 100644 --- a/core/runtime/binaryen/module/module_factory_impl.cpp +++ b/core/runtime/binaryen/module/module_factory_impl.cpp @@ -17,8 +17,11 @@ namespace kagome::runtime::binaryen { ModuleFactoryImpl::ModuleFactoryImpl( std::shared_ptr<InstanceEnvironmentFactory> env_factory, - std::shared_ptr<storage::trie::TrieStorage> storage) - : env_factory_{std::move(env_factory)}, storage_{std::move(storage)} { + std::shared_ptr<storage::trie::TrieStorage> storage, + std::shared_ptr<crypto::Hasher> hasher) + : env_factory_{std::move(env_factory)}, + storage_{std::move(storage)}, + hasher_(std::move(hasher)) { BOOST_ASSERT(env_factory_ != nullptr); BOOST_ASSERT(storage_ != nullptr); } @@ -26,7 +29,8 @@ namespace kagome::runtime::binaryen { outcome::result<std::unique_ptr<Module>> ModuleFactoryImpl::make( gsl::span<const uint8_t> code) const { std::vector<uint8_t> code_vec{code.begin(), code.end()}; - auto res = ModuleImpl::createFromCode(code_vec, env_factory_); + auto res = ModuleImpl::createFromCode( + code_vec, env_factory_, hasher_->sha2_256(code)); if (res.has_value()) { return std::unique_ptr<Module>(std::move(res.value())); } diff --git a/core/runtime/binaryen/module/module_factory_impl.hpp b/core/runtime/binaryen/module/module_factory_impl.hpp index ebfd01272f..e09e5cafa3 100644 --- a/core/runtime/binaryen/module/module_factory_impl.hpp +++ b/core/runtime/binaryen/module/module_factory_impl.hpp @@ -12,6 +12,10 @@ namespace kagome::runtime { class TrieStorageProvider; } +namespace kagome::crypto { + class Hasher; +} + namespace kagome::host_api { class HostApiFactory; } @@ -35,7 +39,8 @@ namespace kagome::runtime::binaryen { class ModuleFactoryImpl final : public ModuleFactory { public: ModuleFactoryImpl(std::shared_ptr<InstanceEnvironmentFactory> env_factory, - std::shared_ptr<storage::trie::TrieStorage> storage); + std::shared_ptr<storage::trie::TrieStorage> storage, + std::shared_ptr<crypto::Hasher> hasher); outcome::result<std::unique_ptr<Module>> make( gsl::span<const uint8_t> code) const override; @@ -43,6 +48,7 @@ namespace kagome::runtime::binaryen { private: std::shared_ptr<InstanceEnvironmentFactory> env_factory_; std::shared_ptr<storage::trie::TrieStorage> storage_; + std::shared_ptr<crypto::Hasher> hasher_; }; } // namespace kagome::runtime::binaryen diff --git a/core/runtime/binaryen/module/module_impl.cpp b/core/runtime/binaryen/module/module_impl.cpp index 6e6d0efc1f..8ce400c4c3 100644 --- a/core/runtime/binaryen/module/module_impl.cpp +++ b/core/runtime/binaryen/module/module_impl.cpp @@ -34,15 +34,19 @@ namespace kagome::runtime::binaryen { ModuleImpl::ModuleImpl( std::unique_ptr<wasm::Module> &&module, - std::shared_ptr<const InstanceEnvironmentFactory> env_factory) - : env_factory_{std::move(env_factory)}, module_{std::move(module)} { + std::shared_ptr<const InstanceEnvironmentFactory> env_factory, + const common::Hash256 &code_hash) + : env_factory_{std::move(env_factory)}, + module_{std::move(module)}, + code_hash_(code_hash) { BOOST_ASSERT(module_ != nullptr); BOOST_ASSERT(env_factory_ != nullptr); } outcome::result<std::unique_ptr<ModuleImpl>> ModuleImpl::createFromCode( const std::vector<uint8_t> &code, - std::shared_ptr<const InstanceEnvironmentFactory> env_factory) { + std::shared_ptr<const InstanceEnvironmentFactory> env_factory, + const common::Hash256 &code_hash) { auto log = log::createLogger("wasm_module", "binaryen"); // that nolint suppresses false positive in a library function // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker) @@ -54,8 +58,7 @@ namespace kagome::runtime::binaryen { { wasm::WasmBinaryBuilder parser( *module, - reinterpret_cast<std::vector<char> const &>( // NOLINT - code), + reinterpret_cast<std::vector<char> const &>(code), // NOLINT false); try { @@ -71,7 +74,7 @@ namespace kagome::runtime::binaryen { module->memory.initial = kDefaultHeappages; std::unique_ptr<ModuleImpl> wasm_module_impl( - new ModuleImpl(std::move(module), std::move(env_factory))); + new ModuleImpl(std::move(module), std::move(env_factory), code_hash)); return wasm_module_impl; } @@ -79,7 +82,7 @@ namespace kagome::runtime::binaryen { const { auto env = env_factory_->make(); return std::make_shared<ModuleInstanceImpl>( - std::move(env.env), module_, env.rei); + std::move(env.env), module_, env.rei, code_hash_); } } // namespace kagome::runtime::binaryen diff --git a/core/runtime/binaryen/module/module_impl.hpp b/core/runtime/binaryen/module/module_impl.hpp index 71ad05ce64..656f1c3b39 100644 --- a/core/runtime/binaryen/module/module_impl.hpp +++ b/core/runtime/binaryen/module/module_impl.hpp @@ -36,7 +36,7 @@ namespace kagome::runtime::binaryen { enum class Error { EMPTY_STATE_CODE = 1, INVALID_STATE_CODE }; ModuleImpl(ModuleImpl &&) = default; - ModuleImpl &operator=(ModuleImpl &&) = default; + // ModuleImpl &operator=(ModuleImpl &&) = default; ModuleImpl(const ModuleImpl &) = delete; ModuleImpl &operator=(const ModuleImpl &) = delete; @@ -45,17 +45,20 @@ namespace kagome::runtime::binaryen { static outcome::result<std::unique_ptr<ModuleImpl>> createFromCode( const std::vector<uint8_t> &code, - std::shared_ptr<const InstanceEnvironmentFactory> env_factory_); + std::shared_ptr<const InstanceEnvironmentFactory> env_factory_, + const common::Hash256 &code_hash); outcome::result<std::shared_ptr<ModuleInstance>> instantiate() const override; private: ModuleImpl(std::unique_ptr<wasm::Module> &&module, - std::shared_ptr<const InstanceEnvironmentFactory> env_factory); + std::shared_ptr<const InstanceEnvironmentFactory> env_factory, + const common::Hash256 &code_hash); std::shared_ptr<const InstanceEnvironmentFactory> env_factory_; std::shared_ptr<wasm::Module> module_; // shared to module instances + const common::Hash256 code_hash_; }; } // namespace kagome::runtime::binaryen diff --git a/core/runtime/binaryen/module/module_instance_impl.cpp b/core/runtime/binaryen/module/module_instance_impl.cpp index 4c89136f9a..eeda17abc0 100644 --- a/core/runtime/binaryen/module/module_instance_impl.cpp +++ b/core/runtime/binaryen/module/module_instance_impl.cpp @@ -76,10 +76,12 @@ namespace kagome::runtime::binaryen { ModuleInstanceImpl::ModuleInstanceImpl( InstanceEnvironment &&env, std::shared_ptr<wasm::Module> parent, - std::shared_ptr<RuntimeExternalInterface> rei) + std::shared_ptr<RuntimeExternalInterface> rei, + const common::Hash256 &code_hash) : env_{std::move(env)}, rei_{std::move(rei)}, parent_{std::move(parent)}, + code_hash_(code_hash), module_instance_{ std::make_unique<wasm::ModuleInstance>(*parent_, rei_.get())}, logger_{log::createLogger("ModuleInstance", "binaryen")} { diff --git a/core/runtime/binaryen/module/module_instance_impl.hpp b/core/runtime/binaryen/module/module_instance_impl.hpp index 24259aa76b..e661df6073 100644 --- a/core/runtime/binaryen/module/module_instance_impl.hpp +++ b/core/runtime/binaryen/module/module_instance_impl.hpp @@ -30,7 +30,12 @@ namespace kagome::runtime::binaryen { ModuleInstanceImpl(InstanceEnvironment &&env, std::shared_ptr<wasm::Module> parent, - std::shared_ptr<RuntimeExternalInterface> rei); + std::shared_ptr<RuntimeExternalInterface> rei, + const common::Hash256 &code_hash); + + const common::Hash256 &getCodeHash() const override { + return code_hash_; + } outcome::result<PtrSize> callExportFunction( std::string_view name, common::BufferView args) const override; @@ -50,6 +55,8 @@ namespace kagome::runtime::binaryen { std::shared_ptr<wasm::Module> parent_; // must be kept alive because binaryen's module instance keeps // a reference to it + common::Hash256 code_hash_; + std::unique_ptr<wasm::ModuleInstance> module_instance_; log::Logger logger_; }; diff --git a/core/runtime/common/runtime_instances_pool.cpp b/core/runtime/common/runtime_instances_pool.cpp index d7e2db4795..ae1679ba0b 100644 --- a/core/runtime/common/runtime_instances_pool.cpp +++ b/core/runtime/common/runtime_instances_pool.cpp @@ -32,20 +32,28 @@ namespace kagome::runtime { } } + const common::Hash256 &getCodeHash() const override { + return instance_->getCodeHash(); + } + outcome::result<PtrSize> callExportFunction( std::string_view name, common::BufferView encoded_args) const override { return instance_->callExportFunction(name, encoded_args); } + outcome::result<std::optional<WasmValue>> getGlobal( std::string_view name) const override { return instance_->getGlobal(name); } + void forDataSegment(DataSegmentProcessor const &callback) const override { return instance_->forDataSegment(callback); } + InstanceEnvironment const &getEnvironment() const override { return instance_->getEnvironment(); } + outcome::result<void> resetEnvironment() override { return instance_->resetEnvironment(); } @@ -86,15 +94,18 @@ namespace kagome::runtime { pool.emplace(std::move(instance)); } + std::optional<std::shared_ptr<Module>> RuntimeInstancesPool::getModule( const RuntimeInstancesPool::RootHash &state) { std::lock_guard guard{mt_}; return modules_.get(state); } + void RuntimeInstancesPool::putModule( const RuntimeInstancesPool::RootHash &state, std::shared_ptr<Module> module) { std::lock_guard guard{mt_}; modules_.put(state, std::move(module)); } + } // namespace kagome::runtime diff --git a/core/runtime/module_instance.hpp b/core/runtime/module_instance.hpp index 0f96781ab7..27574f0e04 100644 --- a/core/runtime/module_instance.hpp +++ b/core/runtime/module_instance.hpp @@ -31,6 +31,8 @@ namespace kagome::runtime { public: virtual ~ModuleInstance() = default; + virtual const common::Hash256 &getCodeHash() const = 0; + /** * Call the instance's function * @param name - name of the function diff --git a/core/runtime/wavm/core_api_factory_impl.cpp b/core/runtime/wavm/core_api_factory_impl.cpp index 49686e7846..18ff4246fe 100644 --- a/core/runtime/wavm/core_api_factory_impl.cpp +++ b/core/runtime/wavm/core_api_factory_impl.cpp @@ -31,6 +31,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<IntrinsicModule> intrinsic_module, std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory, gsl::span<const uint8_t> code, + const common::Hash256 &code_hash, std::shared_ptr<SingleModuleCache> last_compiled_module) : instance_env_factory_{std::move(instance_env_factory)}, compartment_{compartment}, @@ -53,7 +54,8 @@ namespace kagome::runtime::wavm { *module_params_, intrinsic_module_, instance_env_factory_, - code_); + code_, + code_hash_); OUTCOME_TRY(inst, module->instantiate()); last_compiled_module_->set(std::move(module)); instance_ = std::move(inst); @@ -68,6 +70,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<ModuleParams> module_params_; std::shared_ptr<IntrinsicModule> intrinsic_module_; gsl::span<const uint8_t> code_; + const common::Hash256 code_hash_; std::shared_ptr<SingleModuleCache> last_compiled_module_; }; @@ -114,6 +117,7 @@ namespace kagome::runtime::wavm { std::unique_ptr<Core> CoreApiFactoryImpl::make( std::shared_ptr<const crypto::Hasher> hasher, const std::vector<uint8_t> &runtime_code) const { + auto code_hash = hasher->sha2_256(runtime_code); auto env_factory = std::make_shared<runtime::RuntimeEnvironmentFactory>( std::make_shared<OneCodeProvider>(runtime_code), std::make_shared<OneModuleRepository>( @@ -125,6 +129,7 @@ namespace kagome::runtime::wavm { runtime_code.data(), static_cast<gsl::span<const uint8_t>::index_type>( runtime_code.size())}, + code_hash, last_compiled_module_), block_header_repo_); auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); diff --git a/core/runtime/wavm/module.cpp b/core/runtime/wavm/module.cpp index a8aab8b758..b1d7811bef 100644 --- a/core/runtime/wavm/module.cpp +++ b/core/runtime/wavm/module.cpp @@ -25,7 +25,8 @@ namespace kagome::runtime::wavm { ModuleParams &module_params, std::shared_ptr<IntrinsicModule> intrinsic_module, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, - gsl::span<const uint8_t> code) { + gsl::span<const uint8_t> code, + const common::Hash256 &code_hash) { std::shared_ptr<WAVM::Runtime::Module> module = nullptr; WAVM::WASM::LoadError loadError; WAVM::IR::FeatureSpec featureSpec; @@ -53,18 +54,21 @@ namespace kagome::runtime::wavm { new ModuleImpl{std::move(compartment), std::move(intrinsic_module), std::move(env_factory), - std::move(module)}); + std::move(module), + code_hash}); } ModuleImpl::ModuleImpl( std::shared_ptr<CompartmentWrapper> compartment, std::shared_ptr<const IntrinsicModule> intrinsic_module, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, - std::shared_ptr<WAVM::Runtime::Module> module) + std::shared_ptr<WAVM::Runtime::Module> module, + const common::Hash256 &code_hash) : env_factory_{std::move(env_factory)}, compartment_{std::move(compartment)}, intrinsic_module_{std::move(intrinsic_module)}, module_{std::move(module)}, + code_hash_(code_hash), logger_{log::createLogger("WAVM Module", "wavm")} { BOOST_ASSERT(compartment_); BOOST_ASSERT(env_factory_); @@ -103,7 +107,7 @@ namespace kagome::runtime::wavm { memory_origin, internal_instance, new_intrinsic_module_instance); auto instance = std::make_shared<ModuleInstanceImpl>( - std::move(env), internal_instance, module_, compartment_); + std::move(env), internal_instance, module_, compartment_, code_hash_); return instance; } diff --git a/core/runtime/wavm/module.hpp b/core/runtime/wavm/module.hpp index 71eccb55b4..4cac549ef9 100644 --- a/core/runtime/wavm/module.hpp +++ b/core/runtime/wavm/module.hpp @@ -10,6 +10,7 @@ #include <memory> +#include "common/blob.hpp" #include "log/logger.hpp" namespace WAVM::Runtime { @@ -34,7 +35,8 @@ namespace kagome::runtime::wavm { ModuleParams &module_params, std::shared_ptr<IntrinsicModule> intrinsic_module, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, - gsl::span<const uint8_t> code); + gsl::span<const uint8_t> code, + const common::Hash256 &code_hash); outcome::result<std::shared_ptr<ModuleInstance>> instantiate() const override; @@ -43,7 +45,8 @@ namespace kagome::runtime::wavm { ModuleImpl(std::shared_ptr<CompartmentWrapper> compartment, std::shared_ptr<const IntrinsicModule> intrinsic_module, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, - std::shared_ptr<WAVM::Runtime::Module> module); + std::shared_ptr<WAVM::Runtime::Module> module, + const common::Hash256 &code_hash); WAVM::Runtime::ImportBindings link(IntrinsicResolver &resolver) const; @@ -51,6 +54,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<CompartmentWrapper> compartment_; std::shared_ptr<const IntrinsicModule> intrinsic_module_; std::shared_ptr<WAVM::Runtime::Module> module_; + const common::Hash256 code_hash_; log::Logger logger_; }; diff --git a/core/runtime/wavm/module_factory_impl.cpp b/core/runtime/wavm/module_factory_impl.cpp index 763c4306ec..9d5fc6866f 100644 --- a/core/runtime/wavm/module_factory_impl.cpp +++ b/core/runtime/wavm/module_factory_impl.cpp @@ -5,6 +5,7 @@ #include "runtime/wavm/module_factory_impl.hpp" +#include "crypto/hasher.hpp" #include "runtime/wavm/module.hpp" #include "runtime/wavm/module_cache.hpp" #include "runtime/wavm/module_params.hpp" @@ -16,15 +17,18 @@ namespace kagome::runtime::wavm { std::shared_ptr<ModuleParams> module_params, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, std::shared_ptr<IntrinsicModule> intrinsic_module, - std::optional<std::shared_ptr<ModuleCache>> module_cache) + std::optional<std::shared_ptr<ModuleCache>> module_cache, + std::shared_ptr<crypto::Hasher> hasher) : compartment_{std::move(compartment)}, module_params_{std::move(module_params)}, env_factory_{std::move(env_factory)}, - intrinsic_module_{std::move(intrinsic_module)} { + intrinsic_module_{std::move(intrinsic_module)}, + hasher_(std::move(hasher)) { BOOST_ASSERT(compartment_ != nullptr); BOOST_ASSERT(module_params_ != nullptr); BOOST_ASSERT(env_factory_ != nullptr); BOOST_ASSERT(intrinsic_module_ != nullptr); + BOOST_ASSERT(hasher_ != nullptr); if (module_cache.has_value()) { WAVM::Runtime::setGlobalObjectCache(std::move(module_cache.value())); @@ -33,8 +37,12 @@ namespace kagome::runtime::wavm { outcome::result<std::unique_ptr<Module>> ModuleFactoryImpl::make( gsl::span<const uint8_t> code) const { - return ModuleImpl::compileFrom( - compartment_, *module_params_, intrinsic_module_, env_factory_, code); + return ModuleImpl::compileFrom(compartment_, + *module_params_, + intrinsic_module_, + env_factory_, + code, + hasher_->sha2_256(code)); } } // namespace kagome::runtime::wavm diff --git a/core/runtime/wavm/module_factory_impl.hpp b/core/runtime/wavm/module_factory_impl.hpp index 6d70d1d4f0..1b6c36f46a 100644 --- a/core/runtime/wavm/module_factory_impl.hpp +++ b/core/runtime/wavm/module_factory_impl.hpp @@ -13,6 +13,9 @@ namespace kagome::application { class AppConfiguration; } +namespace kagome::crypto { + class Hasher; +} namespace kagome::runtime::wavm { @@ -29,7 +32,8 @@ namespace kagome::runtime::wavm { std::shared_ptr<ModuleParams> module_params, std::shared_ptr<const InstanceEnvironmentFactory> env_factory, std::shared_ptr<IntrinsicModule> intrinsic_module, - std::optional<std::shared_ptr<ModuleCache>> module_cache); + std::optional<std::shared_ptr<ModuleCache>> module_cache, + std::shared_ptr<crypto::Hasher> hasher); outcome::result<std::unique_ptr<Module>> make( gsl::span<const uint8_t> code) const override; @@ -39,6 +43,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<ModuleParams> module_params_; std::shared_ptr<const InstanceEnvironmentFactory> env_factory_; std::shared_ptr<IntrinsicModule> intrinsic_module_; + std::shared_ptr<crypto::Hasher> hasher_; }; } // namespace kagome::runtime::wavm diff --git a/core/runtime/wavm/module_instance.cpp b/core/runtime/wavm/module_instance.cpp index ef91035de9..89d5e78ee6 100644 --- a/core/runtime/wavm/module_instance.cpp +++ b/core/runtime/wavm/module_instance.cpp @@ -86,11 +86,13 @@ namespace kagome::runtime::wavm { InstanceEnvironment &&env, WAVM::Runtime::GCPointer<WAVM::Runtime::Instance> instance, WAVM::Runtime::ModuleRef module, - std::shared_ptr<const CompartmentWrapper> compartment) + std::shared_ptr<const CompartmentWrapper> compartment, + const common::Hash256 &code_hash) : env_{std::move(env)}, instance_{std::move(instance)}, module_{std::move(module)}, compartment_{std::move(compartment)}, + code_hash_(code_hash), logger_{log::createLogger("ModuleInstance", "wavm")} { BOOST_ASSERT(instance_ != nullptr); BOOST_ASSERT(compartment_ != nullptr); diff --git a/core/runtime/wavm/module_instance.hpp b/core/runtime/wavm/module_instance.hpp index fe8449d5a6..8b13e9cc20 100644 --- a/core/runtime/wavm/module_instance.hpp +++ b/core/runtime/wavm/module_instance.hpp @@ -36,11 +36,17 @@ namespace kagome::runtime::wavm { EXECUTION_ERROR, WRONG_RETURN_TYPE }; + ModuleInstanceImpl( InstanceEnvironment &&env, WAVM::Runtime::GCPointer<WAVM::Runtime::Instance> instance, WAVM::Runtime::ModuleRef module, - std::shared_ptr<const CompartmentWrapper> compartment); + std::shared_ptr<const CompartmentWrapper> compartment, + const common::Hash256 &code_hash); + + const common::Hash256 &getCodeHash() const override { + return code_hash_; + } outcome::result<PtrSize> callExportFunction( std::string_view name, common::BufferView encoded_args) const override; @@ -58,6 +64,7 @@ namespace kagome::runtime::wavm { WAVM::Runtime::GCPointer<WAVM::Runtime::Instance> instance_; WAVM::Runtime::ModuleRef module_; std::shared_ptr<const CompartmentWrapper> compartment_; + common::Hash256 code_hash_; log::Logger logger_; }; From 8fdc5fba9ec15ec35cd7c81a7794d4f75131ff99 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Wed, 2 Nov 2022 14:43:02 +0800 Subject: [PATCH 03/13] feature: use cache at obtaining of version and metadata Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/runtime/common/executor.hpp | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/core/runtime/common/executor.hpp b/core/runtime/common/executor.hpp index 68826cb811..a4a170e777 100644 --- a/core/runtime/common/executor.hpp +++ b/core/runtime/common/executor.hpp @@ -20,6 +20,7 @@ #include "runtime/module_instance.hpp" #include "runtime/module_repository.hpp" #include "runtime/persistent_result.hpp" +#include "runtime/runtime_api/metadata.hpp" #include "runtime/runtime_environment_factory.hpp" #include "runtime/runtime_properties_cache.hpp" #include "runtime/trie_storage_provider.hpp" @@ -27,6 +28,15 @@ #include "storage/trie/trie_batches.hpp" #include "storage/trie/trie_storage.hpp" +#ifdef __has_builtin +#if __has_builtin(__builtin_expect) +#define unlikely(x) __builtin_expect((x), 0) +#endif +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif + namespace kagome::runtime { /** @@ -134,6 +144,25 @@ namespace kagome::runtime { std::string_view name, Args &&...args) { OUTCOME_TRY(env, env_factory_->start(block_info, storage_state)->make()); + + if constexpr (std::is_same_v<Result, primitives::Version>) { + if (unlikely(name == "Core_version")) { + return cache_->getVersion(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + + if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { + if (unlikely(name == "Metadata_metadata")) { + return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + return callInternal<Result>(*env, name, std::forward<Args>(args)...); } @@ -148,6 +177,25 @@ namespace kagome::runtime { Args &&...args) { OUTCOME_TRY(env_template, env_factory_->start(block_hash)); OUTCOME_TRY(env, env_template->make()); + + if constexpr (std::is_same_v<Result, primitives::Version>) { + if (unlikely(name == "Core_version")) { + return cache_->getVersion(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + + if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { + if (unlikely(name == "Metadata_metadata")) { + return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + return callInternal<Result>(*env, name, std::forward<Args>(args)...); } @@ -161,6 +209,25 @@ namespace kagome::runtime { Args &&...args) { OUTCOME_TRY(env_template, env_factory_->start()); OUTCOME_TRY(env, env_template->make()); + + if constexpr (std::is_same_v<Result, primitives::Version>) { + if (unlikely(name == "Core_version")) { + return cache_->getVersion(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + + if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { + if (unlikely(name == "Metadata_metadata")) { + return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { + return callInternal<Result>( + *env, name, std::forward<Args>(args)...); + }); + } + } + return callInternal<Result>(*env, name, std::forward<Args>(args)...); } @@ -263,4 +330,6 @@ namespace kagome::runtime { } // namespace kagome::runtime +#undef unlikely + #endif // KAGOME_CORE_RUNTIME_COMMON_EXECUTOR_HPP From 2b2f807d4562a06f4bce30dcea9f8a13c62a3261 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Wed, 2 Nov 2022 17:13:21 +0800 Subject: [PATCH 04/13] fix: tests Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- .../binaryen/core_api_factory_impl.cpp | 10 +++--- .../binaryen/core_api_factory_impl.hpp | 5 ++- .../binaryen/instance_environment_factory.cpp | 9 ++++-- .../binaryen/instance_environment_factory.hpp | 8 ++++- core/runtime/wavm/core_api_factory_impl.cpp | 10 +++--- core/runtime/wavm/core_api_factory_impl.hpp | 5 ++- .../wavm/instance_environment_factory.cpp | 10 ++++-- .../wavm/instance_environment_factory.hpp | 7 ++-- test/core/runtime/CMakeLists.txt | 10 +++--- .../binaryen/binaryen_runtime_test.hpp | 7 ++-- test/core/runtime/executor_test.cpp | 18 +++++++++-- test/core/runtime/runtime_test_base.hpp | 15 ++++++++- test/core/runtime/wavm/wasm_executor_test.cpp | 25 +++++++++++---- test/core/runtime/wavm/wavm_runtime_test.hpp | 8 +++-- .../core/runtime/module_instance_mock.hpp | 2 ++ .../runtime/runtime_properties_cache_mock.hpp | 32 +++++++++++++++++++ 16 files changed, 142 insertions(+), 39 deletions(-) create mode 100644 test/mock/core/runtime/runtime_properties_cache_mock.hpp diff --git a/core/runtime/binaryen/core_api_factory_impl.cpp b/core/runtime/binaryen/core_api_factory_impl.cpp index 712ccb2348..30477d099b 100644 --- a/core/runtime/binaryen/core_api_factory_impl.cpp +++ b/core/runtime/binaryen/core_api_factory_impl.cpp @@ -65,13 +65,16 @@ namespace kagome::runtime::binaryen { CoreApiFactoryImpl::CoreApiFactoryImpl( std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory, std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo, - std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker) + std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, + std::shared_ptr<runtime::RuntimePropertiesCache> cache) : instance_env_factory_{std::move(instance_env_factory)}, header_repo_{std::move(header_repo)}, - changes_tracker_{std::move(changes_tracker)} { + changes_tracker_{std::move(changes_tracker)}, + cache_(std::move(cache)) { BOOST_ASSERT(instance_env_factory_ != nullptr); BOOST_ASSERT(header_repo_ != nullptr); BOOST_ASSERT(changes_tracker_ != nullptr); + BOOST_ASSERT(cache_ != nullptr); } std::unique_ptr<Core> CoreApiFactoryImpl::make( @@ -83,8 +86,7 @@ namespace kagome::runtime::binaryen { std::make_shared<OneModuleRepository>( runtime_code, instance_env_factory_, code_hash), header_repo_); - auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); - auto executor = std::make_unique<Executor>(env_factory, cache); + auto executor = std::make_unique<Executor>(env_factory, cache_); return std::make_unique<CoreImpl>( std::move(executor), changes_tracker_, header_repo_); } diff --git a/core/runtime/binaryen/core_api_factory_impl.hpp b/core/runtime/binaryen/core_api_factory_impl.hpp index f7752b4b9a..5c939abde9 100644 --- a/core/runtime/binaryen/core_api_factory_impl.hpp +++ b/core/runtime/binaryen/core_api_factory_impl.hpp @@ -25,6 +25,7 @@ namespace kagome::runtime { class TrieStorageProvider; class Memory; class RuntimeEnvironmentFactory; + class RuntimePropertiesCache; } // namespace kagome::runtime namespace kagome::runtime::binaryen { @@ -39,7 +40,8 @@ namespace kagome::runtime::binaryen { CoreApiFactoryImpl( std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory, std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo, - std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker); + std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, + std::shared_ptr<runtime::RuntimePropertiesCache> cache); std::unique_ptr<Core> make( std::shared_ptr<const crypto::Hasher> hasher, @@ -49,6 +51,7 @@ namespace kagome::runtime::binaryen { std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory_; std::shared_ptr<const blockchain::BlockHeaderRepository> header_repo_; std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker_; + std::shared_ptr<runtime::RuntimePropertiesCache> cache_; }; } // namespace kagome::runtime::binaryen diff --git a/core/runtime/binaryen/instance_environment_factory.cpp b/core/runtime/binaryen/instance_environment_factory.cpp index 02a4ff6cf7..42d4b02f29 100644 --- a/core/runtime/binaryen/instance_environment_factory.cpp +++ b/core/runtime/binaryen/instance_environment_factory.cpp @@ -17,17 +17,20 @@ namespace kagome::runtime::binaryen { std::shared_ptr<storage::trie::TrieSerializer> serializer, std::shared_ptr<host_api::HostApiFactory> host_api_factory, std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, - std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker) + std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, + std::shared_ptr<runtime::RuntimePropertiesCache> cache) : storage_{std::move(storage)}, serializer_{std::move(serializer)}, host_api_factory_{std::move(host_api_factory)}, block_header_repo_{std::move(block_header_repo)}, - changes_tracker_{std::move(changes_tracker)} { + changes_tracker_{std::move(changes_tracker)}, + cache_(std::move(cache)) { BOOST_ASSERT(storage_); BOOST_ASSERT(serializer_); BOOST_ASSERT(host_api_factory_); BOOST_ASSERT(block_header_repo_); BOOST_ASSERT(changes_tracker_); + BOOST_ASSERT(cache_); } BinaryenInstanceEnvironment InstanceEnvironmentFactory::make() const { @@ -37,7 +40,7 @@ namespace kagome::runtime::binaryen { auto new_storage_provider = std::make_shared<TrieStorageProviderImpl>(storage_, serializer_); auto core_factory = std::make_shared<CoreApiFactoryImpl>( - shared_from_this(), block_header_repo_, changes_tracker_); + shared_from_this(), block_header_repo_, changes_tracker_, cache_); auto host_api = std::shared_ptr<host_api::HostApi>(host_api_factory_->make( core_factory, new_memory_provider, new_storage_provider)); auto rei = std::make_shared<RuntimeExternalInterface>(host_api); diff --git a/core/runtime/binaryen/instance_environment_factory.hpp b/core/runtime/binaryen/instance_environment_factory.hpp index 44efea914b..edca5dcc68 100644 --- a/core/runtime/binaryen/instance_environment_factory.hpp +++ b/core/runtime/binaryen/instance_environment_factory.hpp @@ -25,6 +25,10 @@ namespace kagome::blockchain { class BlockHeaderRepository; } +namespace kagome::runtime { + class RuntimePropertiesCache; +} + namespace kagome::runtime::binaryen { class RuntimeExternalInterface; @@ -42,7 +46,8 @@ namespace kagome::runtime::binaryen { std::shared_ptr<storage::trie::TrieSerializer> serializer, std::shared_ptr<host_api::HostApiFactory> host_api_factory, std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, - std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker); + std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, + std::shared_ptr<RuntimePropertiesCache> cache); [[nodiscard]] BinaryenInstanceEnvironment make() const; @@ -52,6 +57,7 @@ namespace kagome::runtime::binaryen { std::shared_ptr<host_api::HostApiFactory> host_api_factory_; std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo_; std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker_; + std::shared_ptr<RuntimePropertiesCache> cache_; }; } // namespace kagome::runtime::binaryen diff --git a/core/runtime/wavm/core_api_factory_impl.cpp b/core/runtime/wavm/core_api_factory_impl.cpp index 18ff4246fe..6cbd747117 100644 --- a/core/runtime/wavm/core_api_factory_impl.cpp +++ b/core/runtime/wavm/core_api_factory_impl.cpp @@ -95,7 +95,8 @@ namespace kagome::runtime::wavm { std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory, std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, - std::shared_ptr<SingleModuleCache> last_compiled_module) + std::shared_ptr<SingleModuleCache> last_compiled_module, + std::shared_ptr<runtime::RuntimePropertiesCache> cache) : instance_env_factory_{std::move(instance_env_factory)}, compartment_{compartment}, module_params_{std::move(module_params)}, @@ -103,7 +104,8 @@ namespace kagome::runtime::wavm { storage_{std::move(storage)}, block_header_repo_{std::move(block_header_repo)}, changes_tracker_{std::move(changes_tracker)}, - last_compiled_module_{last_compiled_module} { + last_compiled_module_{last_compiled_module}, + cache_(std::move(cache)) { BOOST_ASSERT(compartment_); BOOST_ASSERT(module_params_); BOOST_ASSERT(intrinsic_module_); @@ -112,6 +114,7 @@ namespace kagome::runtime::wavm { BOOST_ASSERT(instance_env_factory_); BOOST_ASSERT(changes_tracker_); BOOST_ASSERT(last_compiled_module_); + BOOST_ASSERT(cache_); } std::unique_ptr<Core> CoreApiFactoryImpl::make( @@ -132,8 +135,7 @@ namespace kagome::runtime::wavm { code_hash, last_compiled_module_), block_header_repo_); - auto cache = std::make_shared<runtime::RuntimePropertiesCacheImpl>(); - auto executor = std::make_unique<runtime::Executor>(env_factory, cache); + auto executor = std::make_unique<runtime::Executor>(env_factory, cache_); return std::make_unique<CoreImpl>( std::move(executor), changes_tracker_, block_header_repo_); } diff --git a/core/runtime/wavm/core_api_factory_impl.hpp b/core/runtime/wavm/core_api_factory_impl.hpp index bdfa3a2186..941fd071a1 100644 --- a/core/runtime/wavm/core_api_factory_impl.hpp +++ b/core/runtime/wavm/core_api_factory_impl.hpp @@ -26,6 +26,7 @@ namespace kagome::runtime { class Memory; class ModuleRepository; class SingleModuleCache; + class RuntimePropertiesCache; } // namespace kagome::runtime namespace kagome::runtime::wavm { @@ -47,7 +48,8 @@ namespace kagome::runtime::wavm { std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, std::shared_ptr<const InstanceEnvironmentFactory> instance_env_factory, std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, - std::shared_ptr<SingleModuleCache> last_compiled_module); + std::shared_ptr<SingleModuleCache> last_compiled_module, + std::shared_ptr<runtime::RuntimePropertiesCache> cache); [[nodiscard]] std::unique_ptr<Core> make( std::shared_ptr<const crypto::Hasher> hasher, @@ -62,6 +64,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo_; std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker_; std::shared_ptr<SingleModuleCache> last_compiled_module_; + std::shared_ptr<runtime::RuntimePropertiesCache> cache_; }; } // namespace kagome::runtime::wavm diff --git a/core/runtime/wavm/instance_environment_factory.cpp b/core/runtime/wavm/instance_environment_factory.cpp index d29bbb35d2..23ce7e5b3c 100644 --- a/core/runtime/wavm/instance_environment_factory.cpp +++ b/core/runtime/wavm/instance_environment_factory.cpp @@ -25,7 +25,8 @@ namespace kagome::runtime::wavm { std::shared_ptr<host_api::HostApiFactory> host_api_factory, std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, - std::shared_ptr<kagome::runtime::SingleModuleCache> last_compiled_module) + std::shared_ptr<kagome::runtime::SingleModuleCache> last_compiled_module, + std::shared_ptr<runtime::RuntimePropertiesCache> cache) : storage_{std::move(storage)}, serializer_{std::move(serializer)}, compartment_{std::move(compartment)}, @@ -34,7 +35,8 @@ namespace kagome::runtime::wavm { host_api_factory_{std::move(host_api_factory)}, block_header_repo_{std::move(block_header_repo)}, changes_tracker_{std::move(changes_tracker)}, - last_compiled_module_{std::move(last_compiled_module)} { + last_compiled_module_{std::move(last_compiled_module)}, + cache_(std::move(cache)) { BOOST_ASSERT(storage_ != nullptr); BOOST_ASSERT(serializer_ != nullptr); BOOST_ASSERT(compartment_ != nullptr); @@ -44,6 +46,7 @@ namespace kagome::runtime::wavm { BOOST_ASSERT(block_header_repo_ != nullptr); BOOST_ASSERT(changes_tracker_ != nullptr); BOOST_ASSERT(last_compiled_module_ != nullptr); + BOOST_ASSERT(cache_ != nullptr); } InstanceEnvironment InstanceEnvironmentFactory::make( @@ -60,7 +63,8 @@ namespace kagome::runtime::wavm { block_header_repo_, shared_from_this(), changes_tracker_, - last_compiled_module_); + last_compiled_module_, + cache_); std::shared_ptr<MemoryProvider> memory_provider; switch (memory_origin) { diff --git a/core/runtime/wavm/instance_environment_factory.hpp b/core/runtime/wavm/instance_environment_factory.hpp index 628859c82f..4f5dac4304 100644 --- a/core/runtime/wavm/instance_environment_factory.hpp +++ b/core/runtime/wavm/instance_environment_factory.hpp @@ -31,7 +31,8 @@ namespace WAVM::Runtime { namespace kagome::runtime { class SingleModuleCache; -} + class RuntimePropertiesCache; +} // namespace kagome::runtime namespace kagome::runtime::wavm { class IntrinsicModule; @@ -52,7 +53,8 @@ namespace kagome::runtime::wavm { std::shared_ptr<host_api::HostApiFactory> host_api_factory, std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo, std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker, - std::shared_ptr<SingleModuleCache> last_compiled_module); + std::shared_ptr<SingleModuleCache> last_compiled_module, + std::shared_ptr<RuntimePropertiesCache> cache); enum class MemoryOrigin { EXTERNAL, INTERNAL }; [[nodiscard]] InstanceEnvironment make( @@ -70,6 +72,7 @@ namespace kagome::runtime::wavm { std::shared_ptr<blockchain::BlockHeaderRepository> block_header_repo_; std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker_; std::shared_ptr<SingleModuleCache> last_compiled_module_; + std::shared_ptr<RuntimePropertiesCache> cache_; }; } // namespace kagome::runtime::wavm diff --git a/test/core/runtime/CMakeLists.txt b/test/core/runtime/CMakeLists.txt index 487e0e360a..15ff726a03 100644 --- a/test/core/runtime/CMakeLists.txt +++ b/test/core/runtime/CMakeLists.txt @@ -62,9 +62,9 @@ target_link_libraries(runtime_upgrade_tracker_test ) addtest(small_lru_cache_test - small_lru_cache_test.cpp - ) + small_lru_cache_test.cpp + ) target_link_libraries(small_lru_cache_test - module_repository - blob - ) + module_repository + blob + ) diff --git a/test/core/runtime/binaryen/binaryen_runtime_test.hpp b/test/core/runtime/binaryen/binaryen_runtime_test.hpp index 6cc8abc9b9..227781ed5f 100644 --- a/test/core/runtime/binaryen/binaryen_runtime_test.hpp +++ b/test/core/runtime/binaryen/binaryen_runtime_test.hpp @@ -18,7 +18,7 @@ class BinaryenRuntimeTest : public RuntimeTestBase { public: - virtual std::shared_ptr<kagome::runtime::ModuleFactory> createModuleFactory() + std::shared_ptr<kagome::runtime::ModuleFactory> createModuleFactory() override { auto memory_factory = std::make_shared<kagome::runtime::binaryen::BinaryenMemoryFactory>(); @@ -32,11 +32,12 @@ class BinaryenRuntimeTest : public RuntimeTestBase { serializer_, host_api_factory_, header_repo_, - changes_tracker_); + changes_tracker_, + cache_); auto module_factory = std::make_shared<kagome::runtime::binaryen::ModuleFactoryImpl>( - instance_env_factory, trie_storage_); + instance_env_factory, trie_storage_, hasher_); return module_factory; } }; diff --git a/test/core/runtime/executor_test.cpp b/test/core/runtime/executor_test.cpp index 886303d294..ed15666325 100644 --- a/test/core/runtime/executor_test.cpp +++ b/test/core/runtime/executor_test.cpp @@ -15,6 +15,7 @@ #include "mock/core/runtime/module_instance_mock.hpp" #include "mock/core/runtime/module_repository_mock.hpp" #include "mock/core/runtime/runtime_environment_factory_mock.hpp" +#include "mock/core/runtime/runtime_properties_cache_mock.hpp" #include "mock/core/runtime/trie_storage_provider_mock.hpp" #include "mock/core/storage/trie/trie_batches_mock.hpp" #include "mock/core/storage/trie/trie_storage_mock.hpp" @@ -37,6 +38,7 @@ using kagome::runtime::ModuleRepositoryMock; using kagome::runtime::PtrSize; using kagome::runtime::RuntimeEnvironment; using kagome::runtime::RuntimeEnvironmentTemplateMock; +using kagome::runtime::RuntimePropertiesCacheMock; using kagome::runtime::TrieStorageProviderMock; using kagome::storage::trie::PersistentTrieBatch; using kagome::storage::trie::PersistentTrieBatchMock; @@ -54,14 +56,25 @@ class ExecutorTest : public testing::Test { void SetUp() override { memory_ = std::make_unique<MemoryMock>(); + + header_repo_ = std::make_shared<BlockHeaderRepositoryMock>(); + auto code_provider = std::make_shared<BasicCodeProvider>( boost::filesystem::path(__FILE__).parent_path().string() + "/wasm/sumtwo.wasm"); auto module_repo = std::make_shared<ModuleRepositoryMock>(); - header_repo_ = std::make_shared<BlockHeaderRepositoryMock>(); env_factory_ = std::make_shared<kagome::runtime::RuntimeEnvironmentFactoryMock>( code_provider, module_repo, header_repo_); + + cache_ = std::make_shared<RuntimePropertiesCacheMock>(); + ON_CALL(*cache_, getVersion(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); + ON_CALL(*cache_, getMetadata(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); + storage_ = std::make_shared<kagome::storage::trie::TrieStorageMock>(); } @@ -190,12 +203,13 @@ class ExecutorTest : public testing::Test { protected: std::unique_ptr<MemoryMock> memory_; std::shared_ptr<kagome::runtime::RuntimeEnvironmentFactoryMock> env_factory_; + std::shared_ptr<kagome::runtime::RuntimePropertiesCacheMock> cache_; std::shared_ptr<BlockHeaderRepositoryMock> header_repo_; std::shared_ptr<kagome::storage::trie::TrieStorageMock> storage_; }; TEST_F(ExecutorTest, LatestStateSwitchesCorrectly) { - Executor executor{env_factory_}; + Executor executor{env_factory_, cache_}; kagome::primitives::BlockInfo block_info1{42, "block_hash1"_hash256}; kagome::primitives::BlockInfo block_info2{43, "block_hash2"_hash256}; kagome::primitives::BlockInfo block_info3{44, "block_hash3"_hash256}; diff --git a/test/core/runtime/runtime_test_base.hpp b/test/core/runtime/runtime_test_base.hpp index 20fe91cb0e..750fad6294 100644 --- a/test/core/runtime/runtime_test_base.hpp +++ b/test/core/runtime/runtime_test_base.hpp @@ -25,8 +25,10 @@ #include "mock/core/application/app_configuration_mock.hpp" #include "mock/core/blockchain/block_header_repository_mock.hpp" #include "mock/core/blockchain/block_storage_mock.hpp" +#include "mock/core/crypto/hasher_mock.hpp" #include "mock/core/offchain/offchain_persistent_storage_mock.hpp" #include "mock/core/offchain/offchain_worker_pool_mock.hpp" +#include "mock/core/runtime/runtime_properties_cache_mock.hpp" #include "mock/core/runtime/trie_storage_provider_mock.hpp" #include "mock/core/storage/changes_trie/changes_tracker_mock.hpp" #include "mock/core/storage/trie/polkadot_trie_cursor_mock.h" @@ -132,6 +134,15 @@ class RuntimeTestBase : public ::testing::Test { initStorage(); trie_storage_ = std::make_shared<storage::trie::TrieStorageMock>(); serializer_ = std::make_shared<storage::trie::TrieSerializerMock>(); + hasher_ = std::make_shared<crypto::HasherMock>(); + + cache_ = std::make_shared<runtime::RuntimePropertiesCacheMock>(); + ON_CALL(*cache_, getVersion(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); + ON_CALL(*cache_, getMetadata(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); auto module_factory = createModuleFactory(); @@ -156,7 +167,8 @@ class RuntimeTestBase : public ::testing::Test { runtime_env_factory_ = std::make_shared<runtime::RuntimeEnvironmentFactory>( std::move(wasm_provider_), std::move(module_repo), header_repo_); - executor_ = std::make_shared<runtime::Executor>(runtime_env_factory_); + executor_ = + std::make_shared<runtime::Executor>(runtime_env_factory_, cache_); } void preparePersistentStorageExpects() { @@ -237,6 +249,7 @@ class RuntimeTestBase : public ::testing::Test { std::shared_ptr<storage::trie::TrieStorageMock> trie_storage_; std::shared_ptr<storage::trie::TrieSerializerMock> serializer_; std::shared_ptr<runtime::RuntimeEnvironmentFactory> runtime_env_factory_; + std::shared_ptr<runtime::RuntimePropertiesCacheMock> cache_; std::shared_ptr<runtime::Executor> executor_; std::shared_ptr<storage::changes_trie::ChangesTrackerMock> changes_tracker_; std::shared_ptr<offchain::OffchainPersistentStorageMock> offchain_storage_; diff --git a/test/core/runtime/wavm/wasm_executor_test.cpp b/test/core/runtime/wavm/wasm_executor_test.cpp index 8f98169246..932223e03f 100644 --- a/test/core/runtime/wavm/wasm_executor_test.cpp +++ b/test/core/runtime/wavm/wasm_executor_test.cpp @@ -21,6 +21,7 @@ #include "mock/core/blockchain/block_header_repository_mock.hpp" #include "mock/core/offchain/offchain_persistent_storage_mock.hpp" #include "mock/core/offchain/offchain_worker_pool_mock.hpp" +#include "mock/core/runtime/runtime_properties_cache_mock.hpp" #include "mock/core/runtime/runtime_upgrade_tracker_mock.hpp" #include "mock/core/storage/changes_trie/changes_tracker_mock.hpp" #include "runtime/common/executor.hpp" @@ -32,8 +33,6 @@ #include "runtime/wavm/core_api_factory_impl.hpp" #include "runtime/wavm/instance_environment_factory.hpp" #include "runtime/wavm/intrinsics/intrinsic_module.hpp" -#include "runtime/wavm/intrinsics/intrinsic_module_instance.hpp" -#include "runtime/wavm/intrinsics/intrinsic_resolver_impl.hpp" #include "runtime/wavm/module_cache.hpp" #include "runtime/wavm/module_factory_impl.hpp" #include "runtime/wavm/module_params.hpp" @@ -70,6 +69,7 @@ using kagome::runtime::Executor; using kagome::runtime::RuntimeCodeProvider; using kagome::runtime::RuntimeEnvironmentFactory; using kagome::runtime::RuntimeInstancesPool; +using kagome::runtime::RuntimePropertiesCacheMock; using kagome::runtime::TrieStorageProvider; using kagome::runtime::TrieStorageProviderImpl; using kagome::runtime::wavm::ModuleParams; @@ -180,7 +180,8 @@ class WasmExecutorTest : public ::testing::Test { host_api_factory, header_repo_, changes_tracker, - bogus_smc); + bogus_smc, + cache_); auto module_factory = std::make_shared<kagome::runtime::wavm::ModuleFactoryImpl>( @@ -188,7 +189,8 @@ class WasmExecutorTest : public ::testing::Test { module_params, instance_env_factory, intrinsic_module, - std::nullopt); + std::nullopt, + hasher); auto module_repo = std::make_shared<kagome::runtime::ModuleRepositoryImpl>( std::make_shared<RuntimeInstancesPool>(), runtime_upgrade_tracker_, @@ -204,14 +206,24 @@ class WasmExecutorTest : public ::testing::Test { header_repo_, instance_env_factory, changes_tracker, - std::make_shared<kagome::runtime::SingleModuleCache>()); + std::make_shared<kagome::runtime::SingleModuleCache>(), + cache_); auto host_api = std::shared_ptr<kagome::host_api::HostApi>{host_api_factory->make( core_provider, memory_provider, storage_provider_)}; auto env_factory = std::make_shared<RuntimeEnvironmentFactory>( wasm_provider_, module_repo, header_repo_); - executor_ = std::make_shared<Executor>(env_factory); + + cache_ = std::make_shared<RuntimePropertiesCacheMock>(); + ON_CALL(*cache_, getVersion(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); + ON_CALL(*cache_, getMetadata(_, _)) + .WillByDefault(testing::Invoke( + [](const auto &hash, auto func) { return func(); })); + + executor_ = std::make_shared<Executor>(env_factory, cache_); } protected: @@ -219,6 +231,7 @@ class WasmExecutorTest : public ::testing::Test { std::shared_ptr<TrieStorageProvider> storage_provider_; std::shared_ptr<RuntimeCodeProvider> wasm_provider_; std::shared_ptr<BlockHeaderRepositoryMock> header_repo_; + std::shared_ptr<RuntimePropertiesCacheMock> cache_; std::shared_ptr<kagome::runtime::RuntimeUpgradeTrackerMock> runtime_upgrade_tracker_; }; diff --git a/test/core/runtime/wavm/wavm_runtime_test.hpp b/test/core/runtime/wavm/wavm_runtime_test.hpp index 6abd540042..0ec47805e0 100644 --- a/test/core/runtime/wavm/wavm_runtime_test.hpp +++ b/test/core/runtime/wavm/wavm_runtime_test.hpp @@ -24,7 +24,7 @@ class WavmRuntimeTest : public RuntimeTestBase { public: - virtual std::shared_ptr<kagome::runtime::ModuleFactory> createModuleFactory() + std::shared_ptr<kagome::runtime::ModuleFactory> createModuleFactory() override { auto compartment = std::make_shared<kagome::runtime::wavm::CompartmentWrapper>( @@ -52,7 +52,8 @@ class WavmRuntimeTest : public RuntimeTestBase { host_api_factory_, header_repo_, changes_tracker, - std::make_shared<kagome::runtime::SingleModuleCache>()); + std::make_shared<kagome::runtime::SingleModuleCache>(), + cache_); auto module_factory = std::make_shared<kagome::runtime::wavm::ModuleFactoryImpl>( @@ -60,7 +61,8 @@ class WavmRuntimeTest : public RuntimeTestBase { module_params, instance_env_factory, intrinsic_module, - std::nullopt); + std::nullopt, + hasher_); return module_factory; } diff --git a/test/mock/core/runtime/module_instance_mock.hpp b/test/mock/core/runtime/module_instance_mock.hpp index 0134dd0388..7063a72b4e 100644 --- a/test/mock/core/runtime/module_instance_mock.hpp +++ b/test/mock/core/runtime/module_instance_mock.hpp @@ -14,6 +14,8 @@ namespace kagome::runtime { class ModuleInstanceMock : public ModuleInstance { public: + MOCK_METHOD(const common::Hash256 &, getCodeHash, (), (const, override)); + MOCK_METHOD(outcome::result<PtrSize>, callExportFunction, (std::string_view name, common::BufferView args), diff --git a/test/mock/core/runtime/runtime_properties_cache_mock.hpp b/test/mock/core/runtime/runtime_properties_cache_mock.hpp new file mode 100644 index 0000000000..8939184865 --- /dev/null +++ b/test/mock/core/runtime/runtime_properties_cache_mock.hpp @@ -0,0 +1,32 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEMOCK +#define KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEMOCK + +#include "runtime/runtime_properties_cache.hpp" + +#include <gmock/gmock.h> + +namespace kagome::runtime { + + class RuntimePropertiesCacheMock : public RuntimePropertiesCache { + public: + MOCK_METHOD(outcome::result<primitives::Version>, + getVersion, + (const common::Hash256 &, + std::function<outcome::result<primitives::Version>()>), + (override)); + + MOCK_METHOD(outcome::result<primitives::OpaqueMetadata>, + getMetadata, + (const common::Hash256 &, + std::function<outcome::result<primitives::OpaqueMetadata>()>), + (override)); + }; + +} // namespace kagome::runtime + +#endif // KAGOME_RUNTIME_RUNTIMEPROPERTIESCACHEMOCK From eaabfdcb96ef96685f6e44d3581c91454158e80d Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Wed, 2 Nov 2022 19:48:30 +0800 Subject: [PATCH 05/13] fix: tests Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- test/core/runtime/executor_test.cpp | 8 ++++---- test/core/runtime/runtime_test_base.hpp | 9 +++++---- test/core/runtime/wavm/wasm_executor_test.cpp | 10 ++++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/test/core/runtime/executor_test.cpp b/test/core/runtime/executor_test.cpp index ed15666325..f674cee8ad 100644 --- a/test/core/runtime/executor_test.cpp +++ b/test/core/runtime/executor_test.cpp @@ -69,11 +69,11 @@ class ExecutorTest : public testing::Test { cache_ = std::make_shared<RuntimePropertiesCacheMock>(); ON_CALL(*cache_, getVersion(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); ON_CALL(*cache_, getMetadata(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); storage_ = std::make_shared<kagome::storage::trie::TrieStorageMock>(); } diff --git a/test/core/runtime/runtime_test_base.hpp b/test/core/runtime/runtime_test_base.hpp index 750fad6294..7750fe237e 100644 --- a/test/core/runtime/runtime_test_base.hpp +++ b/test/core/runtime/runtime_test_base.hpp @@ -52,6 +52,7 @@ #include "testutil/runtime/common/basic_code_provider.hpp" using testing::_; +using testing::Invoke; using testing::Return; using namespace kagome; @@ -138,11 +139,11 @@ class RuntimeTestBase : public ::testing::Test { cache_ = std::make_shared<runtime::RuntimePropertiesCacheMock>(); ON_CALL(*cache_, getVersion(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); ON_CALL(*cache_, getMetadata(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); auto module_factory = createModuleFactory(); diff --git a/test/core/runtime/wavm/wasm_executor_test.cpp b/test/core/runtime/wavm/wasm_executor_test.cpp index 932223e03f..03f6643af2 100644 --- a/test/core/runtime/wavm/wasm_executor_test.cpp +++ b/test/core/runtime/wavm/wasm_executor_test.cpp @@ -80,6 +80,8 @@ using kagome::storage::trie::PolkadotTrieImpl; using kagome::storage::trie::TrieSerializerImpl; using kagome::storage::trie::TrieStorage; using kagome::storage::trie::TrieStorageImpl; +using testing::_; +using testing::Invoke; using testing::Return; namespace fs = boost::filesystem; @@ -217,11 +219,11 @@ class WasmExecutorTest : public ::testing::Test { cache_ = std::make_shared<RuntimePropertiesCacheMock>(); ON_CALL(*cache_, getVersion(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); ON_CALL(*cache_, getMetadata(_, _)) - .WillByDefault(testing::Invoke( - [](const auto &hash, auto func) { return func(); })); + .WillByDefault( + Invoke([](const auto &hash, auto func) { return func(); })); executor_ = std::make_shared<Executor>(env_factory, cache_); } From efb26c87ebd6b9fb8d331b9d4b7b01aacf95a428 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Thu, 3 Nov 2022 15:41:00 +0800 Subject: [PATCH 06/13] refactor: move obtaining of version from block tree to core api Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/api/service/impl/api_service_impl.cpp | 13 +++++++++---- core/api/service/impl/api_service_impl.hpp | 7 ++++++- core/blockchain/block_tree.hpp | 6 ------ core/blockchain/impl/block_tree_impl.hpp | 5 ----- core/injector/application_injector.cpp | 4 +++- test/core/api/transport/listener_test.hpp | 6 +++++- test/mock/core/blockchain/block_tree_mock.hpp | 5 ----- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/core/api/service/impl/api_service_impl.cpp b/core/api/service/impl/api_service_impl.cpp index eb8c5608f8..47cb55bd84 100644 --- a/core/api/service/impl/api_service_impl.cpp +++ b/core/api/service/impl/api_service_impl.cpp @@ -16,6 +16,7 @@ #include "common/hexutil.hpp" #include "primitives/common.hpp" #include "primitives/transaction.hpp" +#include "runtime/runtime_api/core.hpp" #include "storage/trie/trie_storage.hpp" #include "subscription/extrinsic_event_key_repository.hpp" #include "subscription/subscriber.hpp" @@ -127,13 +128,15 @@ namespace kagome::api { std::shared_ptr<subscription::ExtrinsicEventKeyRepository> extrinsic_event_key_repo, std::shared_ptr<blockchain::BlockTree> block_tree, - std::shared_ptr<storage::trie::TrieStorage> trie_storage) + std::shared_ptr<storage::trie::TrieStorage> trie_storage, + std::shared_ptr<runtime::Core> core) : thread_pool_(std::move(thread_pool)), listeners_(std::move(listeners.listeners)), server_(std::move(server)), logger_{log::createLogger("ApiService", "api")}, block_tree_{std::move(block_tree)}, trie_storage_{std::move(trie_storage)}, + core_(std::move(core)), subscription_engines_{.storage = std::move(storage_sub_engine), .chain = std::move(chain_sub_engine), .ext = std::move(ext_sub_engine)}, @@ -141,6 +144,7 @@ namespace kagome::api { BOOST_ASSERT(thread_pool_); BOOST_ASSERT(block_tree_); BOOST_ASSERT(trie_storage_); + BOOST_ASSERT(core_); BOOST_ASSERT( std::all_of(listeners_.cbegin(), listeners_.cend(), [](auto &listener) { return listener != nullptr; @@ -402,14 +406,15 @@ namespace kagome::api { session->subscribe( id, primitives::events::ChainEventType::kFinalizedRuntimeVersion); - auto ver = block_tree_->runtimeVersion(); - if (ver) { + auto version_res = core_->version(); + if (version_res.has_value()) { + const auto &version = version_res.value(); session_context.messages = uploadMessagesListFromCache(); forJsonData(server_, logger_, id, kRpcEventRuntimeVersion, - makeValue(*ver), + makeValue(version), [&](const auto &result) { session_context.messages->emplace_back( uploadFromCache(result.data())); diff --git a/core/api/service/impl/api_service_impl.hpp b/core/api/service/impl/api_service_impl.hpp index df8eaa27bc..a90e9f1594 100644 --- a/core/api/service/impl/api_service_impl.hpp +++ b/core/api/service/impl/api_service_impl.hpp @@ -41,6 +41,9 @@ namespace kagome::primitives { namespace kagome::storage::trie { class TrieStorage; } +namespace kagome::runtime { + class Core; +} namespace kagome::subscription { class ExtrinsicEventKeyRepository; } @@ -135,7 +138,8 @@ namespace kagome::api { std::shared_ptr<subscription::ExtrinsicEventKeyRepository> extrinsic_event_key_repo, std::shared_ptr<blockchain::BlockTree> block_tree, - std::shared_ptr<storage::trie::TrieStorage> trie_storage); + std::shared_ptr<storage::trie::TrieStorage> trie_storage, + std::shared_ptr<runtime::Core> core); ~ApiServiceImpl() override = default; @@ -241,6 +245,7 @@ namespace kagome::api { log::Logger logger_; std::shared_ptr<blockchain::BlockTree> block_tree_; std::shared_ptr<storage::trie::TrieStorage> trie_storage_; + std::shared_ptr<runtime::Core> core_; std::mutex subscribed_sessions_cs_; std::unordered_map<Session::SessionId, diff --git a/core/blockchain/block_tree.hpp b/core/blockchain/block_tree.hpp index d3596e926f..aafc9b302b 100644 --- a/core/blockchain/block_tree.hpp +++ b/core/blockchain/block_tree.hpp @@ -72,12 +72,6 @@ namespace kagome::blockchain { virtual outcome::result<primitives::Justification> getBlockJustification( const primitives::BlockId &block) const = 0; - /** - * Method to get actual runtime version. - * @return runtime version. - */ - virtual std::optional<primitives::Version> runtimeVersion() const = 0; - /** * Adds header to the storage * @param header that we are adding diff --git a/core/blockchain/impl/block_tree_impl.hpp b/core/blockchain/impl/block_tree_impl.hpp index 59456b8b18..9927592450 100644 --- a/core/blockchain/impl/block_tree_impl.hpp +++ b/core/blockchain/impl/block_tree_impl.hpp @@ -113,10 +113,6 @@ namespace kagome::blockchain { const primitives::BlockHash &ancestor, const primitives::BlockHash &descendant) const override; - std::optional<primitives::Version> runtimeVersion() const override { - return actual_runtime_version_; - } - bool hasDirectChain(const primitives::BlockHash &ancestor, const primitives::BlockHash &descendant) const override; @@ -190,7 +186,6 @@ namespace kagome::blockchain { justification_storage_policy_; std::optional<primitives::BlockHash> genesis_block_hash_; - std::optional<primitives::Version> actual_runtime_version_; log::Logger log_ = log::createLogger("BlockTree", "blockchain"); diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 2cd771f47e..3bdd86444c 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -534,6 +534,7 @@ namespace { auto block_tree = injector.template create<sptr<blockchain::BlockTree>>(); auto trie_storage = injector.template create<sptr<storage::trie::TrieStorage>>(); + auto core = injector.template create<sptr<runtime::Core>>(); auto api_service = std::make_shared<api::ApiServiceImpl>(asmgr, @@ -546,7 +547,8 @@ namespace { ext_sub_engine, extrinsic_event_key_repo, block_tree, - trie_storage); + trie_storage, + core); auto child_state_api = injector.template create<std::shared_ptr<api::ChildStateApi>>(); diff --git a/test/core/api/transport/listener_test.hpp b/test/core/api/transport/listener_test.hpp index 2dba778f45..e9419e9be1 100644 --- a/test/core/api/transport/listener_test.hpp +++ b/test/core/api/transport/listener_test.hpp @@ -21,6 +21,7 @@ #include "mock/core/api/transport/jrpc_processor_stub.hpp" #include "mock/core/application/app_state_manager_mock.hpp" #include "mock/core/blockchain/block_tree_mock.hpp" +#include "mock/core/runtime/core_mock.hpp" #include "mock/core/storage/trie/trie_storage_mock.hpp" #include "primitives/event_types.hpp" #include "subscription/extrinsic_event_key_repository.hpp" @@ -43,6 +44,7 @@ using kagome::primitives::events::ExtrinsicSubscriptionEngine; using kagome::primitives::events::ExtrinsicSubscriptionEnginePtr; using kagome::primitives::events::StorageSubscriptionEngine; using kagome::primitives::events::StorageSubscriptionEnginePtr; +using kagome::runtime::CoreMock; using kagome::storage::trie::TrieStorage; using kagome::storage::trie::TrieStorageMock; using kagome::subscription::ExtrinsicEventKeyRepository; @@ -129,6 +131,7 @@ struct ListenerTest : public ::testing::Test { std::shared_ptr<BlockTree> block_tree = std::make_shared<BlockTreeMock>(); std::shared_ptr<TrieStorage> trie_storage = std::make_shared<TrieStorageMock>(); + std::shared_ptr<CoreMock> core = std::make_shared<CoreMock>(); sptr<ApiService> service = std::make_shared<ApiServiceImpl>( app_state_manager, @@ -141,7 +144,8 @@ struct ListenerTest : public ::testing::Test { ext_events_engine, ext_event_key_repo, block_tree, - trie_storage); + trie_storage, + core); }; #endif // KAGOME_TEST_CORE_API_TRANSPORT_LISTENER_TEST_HPP diff --git a/test/mock/core/blockchain/block_tree_mock.hpp b/test/mock/core/blockchain/block_tree_mock.hpp index be1273027e..ee9d36425a 100644 --- a/test/mock/core/blockchain/block_tree_mock.hpp +++ b/test/mock/core/blockchain/block_tree_mock.hpp @@ -37,11 +37,6 @@ namespace kagome::blockchain { (const primitives::BlockId &), (const, override)); - MOCK_METHOD(std::optional<primitives::Version>, - runtimeVersion, - (), - (const, override)); - MOCK_METHOD(outcome::result<void>, addBlockHeader, (const primitives::BlockHeader &), From e0d1d8f498714e9e12625b7d08e8e3d96ac7986a Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Fri, 11 Nov 2022 19:22:00 +0800 Subject: [PATCH 07/13] fix: external project test Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/runtime/runtime_api/impl/CMakeLists.txt | 109 ++++++++++++++---- .../impl/runtime_properties_cache_impl.hpp | 2 +- test/external-project-test/src/main.cpp | 5 +- 3 files changed, 90 insertions(+), 26 deletions(-) diff --git a/core/runtime/runtime_api/impl/CMakeLists.txt b/core/runtime/runtime_api/impl/CMakeLists.txt index 125ecee707..50764b2169 100644 --- a/core/runtime/runtime_api/impl/CMakeLists.txt +++ b/core/runtime/runtime_api/impl/CMakeLists.txt @@ -1,30 +1,89 @@ -add_library(core_api core.cpp) -target_link_libraries(core_api executor primitives) +add_library(core_api + core.cpp) +target_link_libraries(core_api + executor + primitives + ) kagome_install(core_api) -add_library(account_nonce_api account_nonce_api.cpp) -target_link_libraries(account_nonce_api executor) -add_library(authority_discovery_api authority_discovery_api.cpp) -target_link_libraries(authority_discovery_api executor) -add_library(babe_api babe_api.cpp) -target_link_libraries(babe_api executor) -add_library(block_builder_api block_builder.cpp) -target_link_libraries(block_builder_api executor primitives) -add_library(grandpa_api grandpa_api.cpp) -target_link_libraries(grandpa_api block_header_repository executor) -add_library(metadata_api metadata.cpp) -target_link_libraries(metadata_api executor) -add_library(parachain_host_api parachain_host.cpp parachain_host_types_serde.cpp) -target_link_libraries(parachain_host_api executor) -add_library(tagged_transaction_queue_api tagged_transaction_queue.cpp) -target_link_libraries(tagged_transaction_queue_api executor) -add_library(transaction_payment_api transaction_payment_api.cpp) -target_link_libraries(transaction_payment_api executor) -add_library(offchain_worker_api offchain_worker_api.cpp) -target_link_libraries(offchain_worker_api offchain_worker) -add_library(session_keys_api session_keys_api.cpp) -target_link_libraries(session_keys_api executor) +add_library(account_nonce_api + account_nonce_api.cpp + ) +target_link_libraries(account_nonce_api + executor + ) + +add_library(authority_discovery_api + authority_discovery_api.cpp) +target_link_libraries(authority_discovery_api + executor + ) + +add_library(babe_api + babe_api.cpp + ) +target_link_libraries(babe_api + executor + ) + +add_library(block_builder_api + block_builder.cpp + ) +target_link_libraries(block_builder_api + executor primitives + ) + +add_library(grandpa_api + grandpa_api.cpp + ) +target_link_libraries(grandpa_api + block_header_repository + executor + ) + +add_library(metadata_api + metadata.cpp + ) +target_link_libraries(metadata_api + executor + ) + +add_library(parachain_host_api + parachain_host.cpp + parachain_host_types_serde.cpp + ) +target_link_libraries(parachain_host_api + executor + ) + +add_library(tagged_transaction_queue_api + tagged_transaction_queue.cpp + ) +target_link_libraries(tagged_transaction_queue_api + executor + ) + +add_library(transaction_payment_api + transaction_payment_api.cpp + ) +target_link_libraries(transaction_payment_api + executor + ) + +add_library(offchain_worker_api + offchain_worker_api.cpp + ) +target_link_libraries(offchain_worker_api + offchain_worker + ) + +add_library(session_keys_api + session_keys_api.cpp + ) +target_link_libraries(session_keys_api + executor + ) add_library(runtime_properties_cache runtime_properties_cache_impl.cpp @@ -32,5 +91,7 @@ add_library(runtime_properties_cache target_link_libraries(runtime_properties_cache executor ) +kagome_install(runtime_properties_cache) + diff --git a/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp index c380efb19a..a67e1af994 100644 --- a/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp +++ b/core/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp @@ -12,7 +12,7 @@ namespace kagome::runtime { class RuntimePropertiesCacheImpl final : public RuntimePropertiesCache { public: - RuntimePropertiesCacheImpl() {} + RuntimePropertiesCacheImpl() = default; outcome::result<primitives::Version> getVersion( const common::Hash256 &hash, diff --git a/test/external-project-test/src/main.cpp b/test/external-project-test/src/main.cpp index 29bcde99fd..735c84a70b 100644 --- a/test/external-project-test/src/main.cpp +++ b/test/external-project-test/src/main.cpp @@ -26,6 +26,7 @@ #include <kagome/runtime/common/runtime_upgrade_tracker_impl.hpp> #include <kagome/runtime/common/storage_code_provider.hpp> #include <kagome/runtime/module.hpp> +#include <kagome/runtime/runtime_api/impl/runtime_properties_cache_impl.hpp> #include <kagome/runtime/wavm/compartment_wrapper.hpp> #include <kagome/runtime/wavm/instance_environment_factory.hpp> #include <kagome/runtime/wavm/intrinsics/intrinsic_module.hpp> @@ -218,8 +219,10 @@ int main() { auto env_factory = std::make_shared<kagome::runtime::RuntimeEnvironmentFactory>( code_provider, module_repo, header_repo); + auto cache = std::make_shared<kagome::runtime::RuntimePropertiesCacheImpl>(); - [[maybe_unused]] auto executor = kagome::runtime::Executor(env_factory); + [[maybe_unused]] auto executor = + kagome::runtime::Executor(env_factory, cache); // TODO(Harrm): Currently, the test only checks if kagome builds as // a dependency in some project. However, we can use the test to run From 8f5293f96cdbab6d18a3f7a124d076c5ab31df12 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Fri, 11 Nov 2022 19:33:19 +0800 Subject: [PATCH 08/13] fix: review issues Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/runtime/binaryen/module/module_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/runtime/binaryen/module/module_impl.hpp b/core/runtime/binaryen/module/module_impl.hpp index 656f1c3b39..92634cc395 100644 --- a/core/runtime/binaryen/module/module_impl.hpp +++ b/core/runtime/binaryen/module/module_impl.hpp @@ -36,7 +36,7 @@ namespace kagome::runtime::binaryen { enum class Error { EMPTY_STATE_CODE = 1, INVALID_STATE_CODE }; ModuleImpl(ModuleImpl &&) = default; - // ModuleImpl &operator=(ModuleImpl &&) = default; + ModuleImpl &operator=(ModuleImpl &&) = default; ModuleImpl(const ModuleImpl &) = delete; ModuleImpl &operator=(const ModuleImpl &) = delete; From 5346cf8c053f1afe8bee8f578e9139277a77f5cd Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Fri, 11 Nov 2022 19:55:34 +0800 Subject: [PATCH 09/13] fix: review issues Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/runtime/binaryen/module/module_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/runtime/binaryen/module/module_impl.hpp b/core/runtime/binaryen/module/module_impl.hpp index 92634cc395..42177152ed 100644 --- a/core/runtime/binaryen/module/module_impl.hpp +++ b/core/runtime/binaryen/module/module_impl.hpp @@ -36,7 +36,7 @@ namespace kagome::runtime::binaryen { enum class Error { EMPTY_STATE_CODE = 1, INVALID_STATE_CODE }; ModuleImpl(ModuleImpl &&) = default; - ModuleImpl &operator=(ModuleImpl &&) = default; + ModuleImpl &operator=(ModuleImpl &&) = delete; ModuleImpl(const ModuleImpl &) = delete; ModuleImpl &operator=(const ModuleImpl &) = delete; From 91d9de5c456d878bc61a5ccfdc8d244b596073ec Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Fri, 11 Nov 2022 21:07:27 +0800 Subject: [PATCH 10/13] fix: external project test Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- test/external-project-test/src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/external-project-test/src/main.cpp b/test/external-project-test/src/main.cpp index 735c84a70b..d26d69987f 100644 --- a/test/external-project-test/src/main.cpp +++ b/test/external-project-test/src/main.cpp @@ -193,7 +193,10 @@ int main() { offchain_persistent_storage, offchain_worker_pool); + auto cache = std::make_shared<kagome::runtime::RuntimePropertiesCacheImpl>(); + auto smc = std::make_shared<kagome::runtime::SingleModuleCache>(); + auto instance_env_factory = std::make_shared<const kagome::runtime::wavm::InstanceEnvironmentFactory>( trie_storage, @@ -204,7 +207,8 @@ int main() { host_api_factory, header_repo, changes_tracker, - smc); + smc, + cache); auto module_factory = std::make_shared<kagome::runtime::wavm::ModuleFactoryImpl>( compartment, @@ -219,7 +223,6 @@ int main() { auto env_factory = std::make_shared<kagome::runtime::RuntimeEnvironmentFactory>( code_provider, module_repo, header_repo); - auto cache = std::make_shared<kagome::runtime::RuntimePropertiesCacheImpl>(); [[maybe_unused]] auto executor = kagome::runtime::Executor(env_factory, cache); From 3b4fddacac9c7f8bdb7a545b6212e6763f7be0a7 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Sat, 12 Nov 2022 01:42:06 +0800 Subject: [PATCH 11/13] fix: external project test Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- test/external-project-test/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/external-project-test/src/main.cpp b/test/external-project-test/src/main.cpp index d26d69987f..6a2826c840 100644 --- a/test/external-project-test/src/main.cpp +++ b/test/external-project-test/src/main.cpp @@ -215,7 +215,8 @@ int main() { module_params, instance_env_factory, intrinsic_module, - std::nullopt); + std::nullopt, + hasher); auto runtime_instances_pool = std::make_shared<kagome::runtime::RuntimeInstancesPool>(); auto module_repo = std::make_shared<kagome::runtime::ModuleRepositoryImpl>( From 412ede918b94b1701387f36c82548dfa2083d2b0 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Sat, 12 Nov 2022 04:38:44 +0800 Subject: [PATCH 12/13] fix: external project test Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- test/external-project-test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/external-project-test/CMakeLists.txt b/test/external-project-test/CMakeLists.txt index fd11602feb..e9872bbc87 100644 --- a/test/external-project-test/CMakeLists.txt +++ b/test/external-project-test/CMakeLists.txt @@ -58,4 +58,5 @@ target_link_libraries(main kagome::offchain_worker_pool kagome::block_header_repository kagome::runtime_upgrade_tracker + kagome::runtime_properties_cache ) From 14191c1689040b860d5f319f73a0c03aa6a77292 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> Date: Sat, 12 Nov 2022 05:43:57 +0800 Subject: [PATCH 13/13] fix: review issues Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com> --- core/api/service/impl/api_service_impl.cpp | 2 +- core/injector/application_injector.cpp | 12 --- core/runtime/common/executor.hpp | 104 ++++++++------------- 3 files changed, 41 insertions(+), 77 deletions(-) diff --git a/core/api/service/impl/api_service_impl.cpp b/core/api/service/impl/api_service_impl.cpp index 47cb55bd84..6b2571986e 100644 --- a/core/api/service/impl/api_service_impl.cpp +++ b/core/api/service/impl/api_service_impl.cpp @@ -406,7 +406,7 @@ namespace kagome::api { session->subscribe( id, primitives::events::ChainEventType::kFinalizedRuntimeVersion); - auto version_res = core_->version(); + auto version_res = core_->version(block_tree_->getLastFinalized().hash); if (version_res.has_value()) { const auto &version = version_res.value(); session_context.messages = uploadMessagesListFromCache(); diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 3bdd86444c..8b367644f9 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -913,18 +913,6 @@ namespace { runtime::binaryen::ModuleFactoryImpl, runtime::wavm::ModuleFactoryImpl>(injector, method); }), - di::bind<runtime::Executor>.template to([](const auto &injector) { - static std::optional<std::shared_ptr<runtime::Executor>> initialized; - if (!initialized) { - auto env_factory = injector.template create< - std::shared_ptr<runtime::RuntimeEnvironmentFactory>>(); - auto cache = injector.template create< - std::shared_ptr<runtime::RuntimePropertiesCache>>(); - initialized = std::make_shared<runtime::Executor>( - std::move(env_factory), std::move(cache)); - } - return initialized.value(); - }), di::bind<runtime::RawExecutor>.template to<runtime::Executor>(), di::bind<runtime::TaggedTransactionQueue>.template to<runtime::TaggedTransactionQueueImpl>(), di::bind<runtime::ParachainHost>.template to<runtime::ParachainHostImpl>(), diff --git a/core/runtime/common/executor.hpp b/core/runtime/common/executor.hpp index a4a170e777..479ccd7a72 100644 --- a/core/runtime/common/executor.hpp +++ b/core/runtime/common/executor.hpp @@ -30,11 +30,11 @@ #ifdef __has_builtin #if __has_builtin(__builtin_expect) -#define unlikely(x) __builtin_expect((x), 0) +#define likely(x) __builtin_expect((x), 1) #endif #endif -#ifndef unlikely -#define unlikely(x) (x) +#ifndef likely +#define likely(x) (x) #endif namespace kagome::runtime { @@ -144,26 +144,8 @@ namespace kagome::runtime { std::string_view name, Args &&...args) { OUTCOME_TRY(env, env_factory_->start(block_info, storage_state)->make()); - - if constexpr (std::is_same_v<Result, primitives::Version>) { - if (unlikely(name == "Core_version")) { - return cache_->getVersion(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { - if (unlikely(name == "Metadata_metadata")) { - return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - return callInternal<Result>(*env, name, std::forward<Args>(args)...); + return callMediateInternal<Result>( + *env, name, std::forward<Args>(args)...); } /** @@ -177,26 +159,8 @@ namespace kagome::runtime { Args &&...args) { OUTCOME_TRY(env_template, env_factory_->start(block_hash)); OUTCOME_TRY(env, env_template->make()); - - if constexpr (std::is_same_v<Result, primitives::Version>) { - if (unlikely(name == "Core_version")) { - return cache_->getVersion(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { - if (unlikely(name == "Metadata_metadata")) { - return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - return callInternal<Result>(*env, name, std::forward<Args>(args)...); + return callMediateInternal<Result>( + *env, name, std::forward<Args>(args)...); } /** @@ -209,26 +173,8 @@ namespace kagome::runtime { Args &&...args) { OUTCOME_TRY(env_template, env_factory_->start()); OUTCOME_TRY(env, env_template->make()); - - if constexpr (std::is_same_v<Result, primitives::Version>) { - if (unlikely(name == "Core_version")) { - return cache_->getVersion(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { - if (unlikely(name == "Metadata_metadata")) { - return cache_->getMetadata(env->module_instance->getCodeHash(), [&] { - return callInternal<Result>( - *env, name, std::forward<Args>(args)...); - }); - } - } - - return callInternal<Result>(*env, name, std::forward<Args>(args)...); + return callMediateInternal<Result>( + *env, name, std::forward<Args>(args)...); } outcome::result<common::Buffer> callAtRaw( @@ -255,6 +201,36 @@ namespace kagome::runtime { } private: + /** + * Internal method for calling a Runtime API method + * Resets the runtime memory with the module's heap base, + * encodes the arguments with SCALE codec, calls the method from the + * provided module instance and returns a result, decoded from SCALE. + * Changes, made to the Host API state, are reset after the call. + */ + template <typename Result, typename... Args> + inline outcome::result<Result> callMediateInternal(RuntimeEnvironment &env, + std::string_view name, + Args &&...args) { + if constexpr (std::is_same_v<Result, primitives::Version>) { + if (likely(name == "Core_version")) { + return cache_->getVersion(env.module_instance->getCodeHash(), [&] { + return callInternal<Result>(env, name, std::forward<Args>(args)...); + }); + } + } + + if constexpr (std::is_same_v<Result, primitives::OpaqueMetadata>) { + if (likely(name == "Metadata_metadata")) { + return cache_->getMetadata(env.module_instance->getCodeHash(), [&] { + return callInternal<Result>(env, name, std::forward<Args>(args)...); + }); + } + } + + return callInternal<Result>(env, name, std::forward<Args>(args)...); + } + /** * Internal method for calling a Runtime API method * Resets the runtime memory with the module's heap base, @@ -330,6 +306,6 @@ namespace kagome::runtime { } // namespace kagome::runtime -#undef unlikely +#undef likely #endif // KAGOME_CORE_RUNTIME_COMMON_EXECUTOR_HPP