Skip to content

src/runtime/binaryen/runtime_external_interface.cpp

Namespaces

Name
sgns
sgns::runtime
sgns::runtime::binaryen

Attributes

Name
const wasm::Name env
const wasm::Name ext_malloc
const wasm::Name ext_free
const wasm::Name ext_clear_prefix
const wasm::Name ext_clear_storage
const wasm::Name ext_exists_storage
const wasm::Name ext_get_allocated_storage
const wasm::Name ext_get_storage_into
const wasm::Name ext_set_storage
const wasm::Name ext_storage_read_version_1
const wasm::Name ext_blake2_256_enumerated_trie_root
const wasm::Name ext_storage_changes_root
const wasm::Name ext_storage_root
const wasm::Name ext_child_storage_root
const wasm::Name ext_clear_child_storage
const wasm::Name ext_exists_child_storage
const wasm::Name ext_get_allocated_child_storage
const wasm::Name ext_get_child_storage_into
const wasm::Name ext_kill_child_storage
const wasm::Name ext_set_child_storage
const wasm::Name ext_print_hex
const wasm::Name ext_logging_log_version_1
const wasm::Name ext_print_num
const wasm::Name ext_print_utf8
const wasm::Name ext_blake2_128
const wasm::Name ext_blake2_256
const wasm::Name ext_keccak_256
const wasm::Name ext_ed25519_verify
const wasm::Name ext_sr25519_verify
const wasm::Name ext_twox_64
const wasm::Name ext_twox_128
const wasm::Name ext_twox_256
const wasm::Name ext_ed25519_public_keys_v1
const wasm::Name ext_ed25519_generate_v1
const wasm::Name ext_ed25519_sign_v1
const wasm::Name ext_ed25519_verify_v1
const wasm::Name ext_sr25519_public_keys_v1
const wasm::Name ext_sr25519_generate_v1
const wasm::Name ext_sr25519_sign_v1
const wasm::Name ext_sr25519_verify_v2
const wasm::Name ext_secp256k1_ecdsa_recover_v1
const wasm::Name ext_secp256k1_ecdsa_recover_compressed_v1
const wasm::Name ext_chain_id

Attributes Documentation

variable env

static const wasm::Name env = "env";

variable ext_malloc

static const wasm::Name ext_malloc = "ext_malloc";

variable ext_free

static const wasm::Name ext_free = "ext_free";

variable ext_clear_prefix

static const wasm::Name ext_clear_prefix = "ext_clear_prefix";

variable ext_clear_storage

static const wasm::Name ext_clear_storage = "ext_clear_storage";

variable ext_exists_storage

static const wasm::Name ext_exists_storage = "ext_exists_storage";

variable ext_get_allocated_storage

static const wasm::Name ext_get_allocated_storage                                               =
"ext_get_allocated_storage";

variable ext_get_storage_into

static const wasm::Name ext_get_storage_into = "ext_get_storage_into";

variable ext_set_storage

static const wasm::Name ext_set_storage = "ext_set_storage";

variable ext_storage_read_version_1

static const wasm::Name ext_storage_read_version_1                                                =
"ext_storage_read_version_1";

variable ext_blake2_256_enumerated_trie_root

static const wasm::Name ext_blake2_256_enumerated_trie_root                                                         =
"ext_blake2_256_enumerated_trie_root";

variable ext_storage_changes_root

static const wasm::Name ext_storage_changes_root = "ext_storage_changes_root";

variable ext_storage_root

static const wasm::Name ext_storage_root = "ext_storage_root";

variable ext_child_storage_root

static const wasm::Name ext_child_storage_root = "ext_child_storage_root";

variable ext_clear_child_storage

static const wasm::Name ext_clear_child_storage = "ext_clear_child_storage";

variable ext_exists_child_storage

static const wasm::Name ext_exists_child_storage = "ext_exists_child_storage";

variable ext_get_allocated_child_storage

static const wasm::Name ext_get_allocated_child_storage                                                     =
"ext_get_allocated_child_storage";

variable ext_get_child_storage_into

static const wasm::Name ext_get_child_storage_into                                                =
"ext_get_child_storage_into";

variable ext_kill_child_storage

static const wasm::Name ext_kill_child_storage = "ext_kill_child_storage";

variable ext_set_child_storage

static const wasm::Name ext_set_child_storage = "ext_set_child_storage";

variable ext_print_hex

static const wasm::Name ext_print_hex = "ext_print_hex";

variable ext_logging_log_version_1

static const wasm::Name ext_logging_log_version_1                                               =
"ext_logging_log_version_1";

variable ext_print_num

static const wasm::Name ext_print_num = "ext_print_num";

variable ext_print_utf8

static const wasm::Name ext_print_utf8 = "ext_print_utf8";

variable ext_blake2_128

static const wasm::Name ext_blake2_128 = "ext_blake2_128";

variable ext_blake2_256

static const wasm::Name ext_blake2_256 = "ext_blake2_256";

variable ext_keccak_256

static const wasm::Name ext_keccak_256 = "ext_keccak_256";

variable ext_ed25519_verify

static const wasm::Name ext_ed25519_verify = "ext_ed25519_verify";

variable ext_sr25519_verify

static const wasm::Name ext_sr25519_verify = "ext_sr25519_verify";

variable ext_twox_64

static const wasm::Name ext_twox_64 = "ext_twox_64";

variable ext_twox_128

static const wasm::Name ext_twox_128 = "ext_twox_128";

variable ext_twox_256

static const wasm::Name ext_twox_256 = "ext_twox_256";

variable ext_ed25519_public_keys_v1

static const wasm::Name ext_ed25519_public_keys_v1                                                =
"ext_crypto_ed25519_public_keys_version_1";

variable ext_ed25519_generate_v1

static const wasm::Name ext_ed25519_generate_v1                                             =
"ext_crypto_ed25519_generate_version_1";

variable ext_ed25519_sign_v1

static const wasm::Name ext_ed25519_sign_v1                                         =
"ext_crypto_ed25519_sign_version_1";

variable ext_ed25519_verify_v1

static const wasm::Name ext_ed25519_verify_v1                                           =
"ext_crypto_ed25519_verify_version_1";

variable ext_sr25519_public_keys_v1

static const wasm::Name ext_sr25519_public_keys_v1                                                =
"ext_crypto_sr25519_public_keys_version_1";

variable ext_sr25519_generate_v1

static const wasm::Name ext_sr25519_generate_v1                                             =
"ext_crypto_sr25519_generate_version_1";

variable ext_sr25519_sign_v1

static const wasm::Name ext_sr25519_sign_v1                                         =
"ext_crypto_sr25519_sign_version_1";

variable ext_sr25519_verify_v2

static const wasm::Name ext_sr25519_verify_v2                                           =
"ext_crypto_sr25519_verify_version_2";

variable ext_secp256k1_ecdsa_recover_v1

static const wasm::Name ext_secp256k1_ecdsa_recover_v1                                                    =
"ext_crypto_secp256k1_ecdsa_recover_version_1";

variable ext_secp256k1_ecdsa_recover_compressed_v1

static const wasm::Name ext_secp256k1_ecdsa_recover_compressed_v1                                                               =
"ext_crypto_secp256k1_ecdsa_recover_compressed_version_1";

variable ext_chain_id

static const wasm::Name ext_chain_id = "ext_chain_id";

Source code

#include "runtime/binaryen/runtime_external_interface.hpp"

#include "runtime/binaryen/wasm_memory_impl.hpp"

namespace sgns::runtime::binaryen {

  const static wasm::Name env = "env";

  const static wasm::Name ext_malloc = "ext_malloc";
  const static wasm::Name ext_free = "ext_free";

  const static wasm::Name ext_clear_prefix = "ext_clear_prefix";
  const static wasm::Name ext_clear_storage = "ext_clear_storage";
  const static wasm::Name ext_exists_storage = "ext_exists_storage";
  const static wasm::Name ext_get_allocated_storage =
      "ext_get_allocated_storage";
  const static wasm::Name ext_get_storage_into = "ext_get_storage_into";
  const static wasm::Name ext_set_storage = "ext_set_storage";
  const static wasm::Name ext_storage_read_version_1 =
      "ext_storage_read_version_1";
  const static wasm::Name ext_blake2_256_enumerated_trie_root =
      "ext_blake2_256_enumerated_trie_root";
  const static wasm::Name ext_storage_changes_root = "ext_storage_changes_root";
  const static wasm::Name ext_storage_root = "ext_storage_root";
  const static wasm::Name ext_child_storage_root = "ext_child_storage_root";
  const static wasm::Name ext_clear_child_storage = "ext_clear_child_storage";
  const static wasm::Name ext_exists_child_storage = "ext_exists_child_storage";
  const static wasm::Name ext_get_allocated_child_storage =
      "ext_get_allocated_child_storage";
  const static wasm::Name ext_get_child_storage_into =
      "ext_get_child_storage_into";
  const static wasm::Name ext_kill_child_storage = "ext_kill_child_storage";
  const static wasm::Name ext_set_child_storage = "ext_set_child_storage";

  const static wasm::Name ext_print_hex = "ext_print_hex";
  const static wasm::Name ext_logging_log_version_1 =
      "ext_logging_log_version_1";
  const static wasm::Name ext_print_num = "ext_print_num";
  const static wasm::Name ext_print_utf8 = "ext_print_utf8";

  const static wasm::Name ext_blake2_128 = "ext_blake2_128";
  const static wasm::Name ext_blake2_256 = "ext_blake2_256";
  const static wasm::Name ext_keccak_256 = "ext_keccak_256";
  const static wasm::Name ext_ed25519_verify = "ext_ed25519_verify";
  const static wasm::Name ext_sr25519_verify = "ext_sr25519_verify";
  const static wasm::Name ext_twox_64 = "ext_twox_64";
  const static wasm::Name ext_twox_128 = "ext_twox_128";
  const static wasm::Name ext_twox_256 = "ext_twox_256";

  const static wasm::Name ext_ed25519_public_keys_v1 =
      "ext_crypto_ed25519_public_keys_version_1";
  const static wasm::Name ext_ed25519_generate_v1 =
      "ext_crypto_ed25519_generate_version_1";
  const static wasm::Name ext_ed25519_sign_v1 =
      "ext_crypto_ed25519_sign_version_1";
  const static wasm::Name ext_ed25519_verify_v1 =
      "ext_crypto_ed25519_verify_version_1";

  const static wasm::Name ext_sr25519_public_keys_v1 =
      "ext_crypto_sr25519_public_keys_version_1";
  const static wasm::Name ext_sr25519_generate_v1 =
      "ext_crypto_sr25519_generate_version_1";
  const static wasm::Name ext_sr25519_sign_v1 =
      "ext_crypto_sr25519_sign_version_1";
  const static wasm::Name ext_sr25519_verify_v2 =
      "ext_crypto_sr25519_verify_version_2";

  const static wasm::Name ext_secp256k1_ecdsa_recover_v1 =
      "ext_crypto_secp256k1_ecdsa_recover_version_1";
  const static wasm::Name ext_secp256k1_ecdsa_recover_compressed_v1 =
      "ext_crypto_secp256k1_ecdsa_recover_compressed_version_1";

  const static wasm::Name ext_chain_id = "ext_chain_id";

  RuntimeExternalInterface::RuntimeExternalInterface(
      const std::shared_ptr<extensions::ExtensionFactory> &extension_factory,
      std::shared_ptr<TrieStorageProvider> storage_provider) {
    BOOST_ASSERT_MSG(extension_factory != nullptr,
                     "extension factory is nullptr");
    BOOST_ASSERT_MSG(storage_provider != nullptr,
                     "storage provider is nullptr");
    auto memory_impl =
        std::make_shared<WasmMemoryImpl>(&(ShellExternalInterface::memory));
    extension_ = extension_factory->createExtension(
        memory_impl, std::move(storage_provider));
  }

  wasm::Literal RuntimeExternalInterface::callImport(
      wasm::Function *import, wasm::LiteralList &arguments) {
    // TODO(kamilsa): PRE-359 Replace ifs with switch case
    if (import->module == env) {
      if (import->base == ext_malloc) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        auto ptr = extension_->ext_malloc(arguments.at(0).geti32());
        return wasm::Literal(ptr);
      }
      if (import->base == ext_free) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        extension_->ext_free(arguments.at(0).geti32());
        return wasm::Literal();
      }

      if (import->base == ext_clear_prefix) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        extension_->ext_clear_prefix(arguments.at(0).geti32(),
                                     arguments.at(1).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_clear_storage) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        extension_->ext_clear_storage(arguments.at(0).geti32(),
                                      arguments.at(1).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_exists_storage) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        auto storage_exists = extension_->ext_exists_storage(
            arguments.at(0).geti32(), arguments.at(1).geti32());
        return wasm::Literal(storage_exists);
      }
      if (import->base == ext_get_allocated_storage) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto ptr =
            extension_->ext_get_allocated_storage(arguments.at(0).geti32(),
                                                  arguments.at(1).geti32(),
                                                  arguments.at(2).geti32());
        return wasm::Literal(ptr);
      }
      if (import->base == ext_get_storage_into) {
        checkArguments(import->base.c_str(), 5, arguments.size());
        auto res = extension_->ext_get_storage_into(arguments.at(0).geti32(),
                                                    arguments.at(1).geti32(),
                                                    arguments.at(2).geti32(),
                                                    arguments.at(3).geti32(),
                                                    arguments.at(4).geti32());
        return wasm::Literal(res);
      }
      if (import->base == ext_storage_read_version_1) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res =
            extension_->ext_storage_read_version_1(arguments.at(0).geti64(),
                                                   arguments.at(1).geti64(),
                                                   arguments.at(2).geti32());
        return wasm::Literal(res);
      }
      if (import->base == ext_set_storage) {
        checkArguments(import->base.c_str(), 4, arguments.size());
        extension_->ext_set_storage(arguments.at(0).geti32(),
                                    arguments.at(1).geti32(),
                                    arguments.at(2).geti32(),
                                    arguments.at(3).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_blake2_256_enumerated_trie_root) {
        checkArguments(import->base.c_str(), 4, arguments.size());
        extension_->ext_blake2_256_enumerated_trie_root(
            arguments.at(0).geti32(),
            arguments.at(1).geti32(),
            arguments.at(2).geti32(),
            arguments.at(3).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_storage_changes_root) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res = extension_->ext_storage_changes_root(
            arguments.at(0).geti32(), arguments.at(2).geti32());
        return wasm::Literal(res);
      }
      if (import->base == ext_storage_root) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        extension_->ext_storage_root(arguments.at(0).geti32());
        return wasm::Literal();
      }


      if (import->base == ext_print_hex) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        extension_->ext_print_hex(arguments.at(0).geti32(),
                                  arguments.at(1).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_logging_log_version_1) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_logging_log_version_1(arguments.at(0).geti32(),
                                              arguments.at(1).geti64(),
                                              arguments.at(2).geti64());
        return wasm::Literal();
      }
      if (import->base == ext_print_num) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        extension_->ext_print_num(arguments.at(0).geti64());
        return wasm::Literal();
      }
      if (import->base == ext_print_utf8) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        extension_->ext_print_utf8(arguments.at(0).geti32(),
                                   arguments.at(1).geti32());
        return wasm::Literal();
      }

      if (import->base == ext_blake2_128) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_blake2_128(arguments.at(0).geti32(),
                                   arguments.at(1).geti32(),
                                   arguments.at(2).geti32());
        return wasm::Literal();
      }

      if (import->base == ext_blake2_256) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_blake2_256(arguments.at(0).geti32(),
                                   arguments.at(1).geti32(),
                                   arguments.at(2).geti32());
        return wasm::Literal();
      }

      if (import->base == ext_keccak_256) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_keccak_256(arguments.at(0).geti32(),
                                   arguments.at(1).geti32(),
                                   arguments.at(2).geti32());
        return wasm::Literal();
      }

      if (import->base == ext_ed25519_verify) {
        checkArguments(import->base.c_str(), 4, arguments.size());
        auto res = extension_->ext_ed25519_verify(arguments.at(0).geti32(),
                                                  arguments.at(1).geti32(),
                                                  arguments.at(2).geti32(),
                                                  arguments.at(3).geti32());
        return wasm::Literal(res);
      }
      if (import->base == ext_sr25519_verify) {
        checkArguments(import->base.c_str(), 4, arguments.size());
        auto res = extension_->ext_sr25519_verify(arguments.at(0).geti32(),
                                                  arguments.at(1).geti32(),
                                                  arguments.at(2).geti32(),
                                                  arguments.at(3).geti32());
        return wasm::Literal(res);
      }
      if (import->base == ext_twox_64) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_twox_64(arguments.at(0).geti32(),
                                arguments.at(1).geti32(),
                                arguments.at(2).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_twox_128) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        extension_->ext_twox_128(arguments.at(0).geti32(),
                                 arguments.at(1).geti32(),
                                 arguments.at(2).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_twox_256) {
        checkArguments(import->base.c_str(), 3, arguments.size());

        extension_->ext_twox_256(arguments.at(0).geti32(),
                                 arguments.at(1).geti32(),
                                 arguments.at(2).geti32());
        return wasm::Literal();
      }
      if (import->base == ext_chain_id) {
        checkArguments(import->base.c_str(), 0, arguments.size());
        auto res = extension_->ext_chain_id();
        return wasm::Literal(res);
      }

      if (import->base == ext_ed25519_public_keys_v1) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        auto res =
            extension_->ext_ed25519_public_keys_v1(arguments.at(0).geti32());
        return wasm::Literal(res);
      }

      if (import->base == ext_ed25519_generate_v1) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        auto res = extension_->ext_ed25519_generate_v1(
            arguments.at(0).geti32(), arguments.at(1).geti64());
        return wasm::Literal(res);
      }

      if (import->base == ext_ed25519_sign_v1) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res = extension_->ext_ed25519_sign_v1(arguments.at(0).geti32(),
                                                   arguments.at(1).geti32(),
                                                   arguments.at(2).geti64());
        return wasm::Literal(res);
      }

      if (import->base == ext_ed25519_verify_v1) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res = extension_->ext_ed25519_verify_v1(arguments.at(0).geti32(),
                                                     arguments.at(1).geti64(),
                                                     arguments.at(2).geti32());
        return wasm::Literal(res);
      }

      if (import->base == ext_sr25519_public_keys_v1) {
        checkArguments(import->base.c_str(), 1, arguments.size());
        auto res =
            extension_->ext_sr25519_public_keys_v1(arguments.at(0).geti32());
        return wasm::Literal(res);
      }

      if (import->base == ext_sr25519_generate_v1) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        auto res = extension_->ext_sr25519_generate_v1(
            arguments.at(0).geti32(), arguments.at(1).geti64());
        return wasm::Literal(res);
      }

      if (import->base == ext_sr25519_sign_v1) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res = extension_->ext_sr25519_sign_v1(arguments.at(0).geti32(),
                                                   arguments.at(1).geti32(),
                                                   arguments.at(2).geti64());
        return wasm::Literal(res);
      }

      if (import->base == ext_sr25519_verify_v2) {
        checkArguments(import->base.c_str(), 3, arguments.size());
        auto res = extension_->ext_sr25519_verify_v1(arguments.at(0).geti32(),
                                                     arguments.at(1).geti64(),
                                                     arguments.at(2).geti32());
        return wasm::Literal(res);
      }

      if (import->base == ext_secp256k1_ecdsa_recover_v1) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        auto res = extension_->ext_crypto_secp256k1_ecdsa_recover_v1(
            arguments.at(0).geti32(), arguments.at(1).geti32());
        return wasm::Literal(res);
      }

      if (import->base == ext_secp256k1_ecdsa_recover_compressed_v1) {
        checkArguments(import->base.c_str(), 2, arguments.size());
        auto res = extension_->ext_crypto_secp256k1_ecdsa_recover_compressed_v1(
            arguments.at(0).geti32(), arguments.at(1).geti32());
        return wasm::Literal(res);
      }
    }

    wasm::Fatal() << "callImport: unknown import: " << import->module.str << "."
                  << import->name.str;
  }

  void RuntimeExternalInterface::checkArguments(std::string_view extern_name,
                                                size_t expected,
                                                size_t actual) {
    if (expected != actual) {
      logger_->error(
          "Wrong number of arguments in {}. Expected: {}. Actual: {}",
          extern_name,
          expected,
          actual);
      std::terminate();
    }
  }

}  // namespace sgns::runtime::binaryen

Updated on 2026-03-04 at 13:10:45 -0800