diff --git a/src/binaryen.cpp b/src/binaryen.cpp index 8e29acdc7..5e38032a8 100644 --- a/src/binaryen.cpp +++ b/src/binaryen.cpp @@ -463,6 +463,14 @@ class BinaryenEthereumInterface : public wasm::ShellExternalInterface, EthereumI eeiSelfDestruct(addressOffset); } + if (import->base == wasm::Name("isAccountEmpty")) { + heraAssert(arguments.size() == 1, string("Argument count mismatch in: ") + import->base.str); + + uint32_t addressOffset = static_cast(arguments[0].geti32()); + + return wasm::Literal(eeiIsAccountEmpty(addressOffset)); + } + heraAssert(false, string("Unsupported import called: ") + import->module.str + "::" + import->base.str + " (" + to_string(arguments.size()) + "arguments)"); } @@ -628,7 +636,8 @@ void BinaryenEngine::verifyContract(wasm::Module & module) { wasm::Name("callDelegate"), createFunctionType({ wasm::Type::i64, wasm::Type::i32, wasm::Type::i32, wasm::Type::i32 }, wasm::Type::i32) }, { wasm::Name("callStatic"), createFunctionType({ wasm::Type::i64, wasm::Type::i32, wasm::Type::i32, wasm::Type::i32 }, wasm::Type::i32) }, { wasm::Name("create"), createFunctionType({ wasm::Type::i32, wasm::Type::i32, wasm::Type::i32, wasm::Type::i32 }, wasm::Type::i32) }, - { wasm::Name("selfDestruct"), createFunctionType({ wasm::Type::i32 }, wasm::Type::none) } + { wasm::Name("selfDestruct"), createFunctionType({ wasm::Type::i32 }, wasm::Type::none) }, + { wasm::Name("isAccountEmpty"), createFunctionType({ wasm::Type::i32 }, wasm::Type::i32) } }; for (auto const& import: module.imports) { diff --git a/src/eei.cpp b/src/eei.cpp index a846a0c08..a2fc4a147 100644 --- a/src/eei.cpp +++ b/src/eei.cpp @@ -651,6 +651,15 @@ void WasmEngine::collectBenchmarkingData() throw EndExecution{}; } + uint32_t EthereumInterface::eeiIsAccountEmpty(uint32_t addressOffset) + { + HERA_DEBUG << depthToString() << " isAccountEmpty " << hex << addressOffset << dec << "\n"; + + evmc_address address = loadAddress(addressOffset); + + return m_host.account_exists(address) ? 0 : 1; + } + void EthereumInterface::takeGas(int64_t gas) { // NOTE: gas >= 0 is validated by the callers of this method diff --git a/src/eei.h b/src/eei.h index 4ba40c6d1..3a4bae04c 100644 --- a/src/eei.h +++ b/src/eei.h @@ -161,6 +161,7 @@ class EthereumInterface { uint32_t eeiCall(EEICallKind kind, int64_t gas, uint32_t addressOffset, uint32_t valueOffset, uint32_t dataOffset, uint32_t dataLength); uint32_t eeiCreate(uint32_t valueOffset, uint32_t dataOffset, uint32_t length, uint32_t resultOffset); void eeiSelfDestruct(uint32_t addressOffset); + uint32_t eeiIsAccountEmpty(uint32_t addressOffset); private: void eeiRevertOrFinish(bool revert, uint32_t offset, uint32_t size);