From 9893e8a35dd0db0d44c37dc558e4c17a717a3831 Mon Sep 17 00:00:00 2001 From: akokoshn Date: Tue, 23 Jul 2024 14:15:51 +0300 Subject: [PATCH] Enable get account data from RPC --- .bumpversion.cfg | 21 - .dockerignore | 5 - AUTHORS | 1 - CHANGELOG.md | 561 -------- CMakeLists.txt | 1 - Dockerfile | 14 - LICENSE | 223 +-- README.md | 1 - appveyor.yml | 60 - circle.yml | 773 ----------- cmake/Config.cmake.in | 1 - codealike.json | 1 - codecov.yml | 16 - flake.lock | 96 +- flake.nix | 7 +- lib/assigner/CMakeLists.txt | 9 +- lib/assigner/evmc/evmc.h | 1198 +++++++++++++++++ lib/assigner/evmc/evmc.hpp | 964 +++++++++++++ lib/assigner/evmc/filter_iterator.hpp | 105 ++ lib/assigner/evmc/helpers.h | 318 +++++ lib/assigner/evmc/hex.hpp | 161 +++ lib/assigner/evmc/utils.h | 37 + lib/assigner/evmone/baseline.hpp | 4 +- .../evmone/baseline_instruction_table.hpp | 2 +- lib/assigner/evmone/eof.hpp | 4 +- lib/assigner/evmone/execution_state.hpp | 2 +- lib/assigner/include/assigner.hpp | 8 +- lib/assigner/include/bytecode.hpp | 6 +- lib/assigner/include/rw.hpp | 6 +- lib/assigner/include/vm_host.hpp | 101 +- lib/assigner/include/zkevm_word.hpp | 8 +- lib/assigner/test/CMakeLists.txt | 2 + lib/assigner/test/assigner_test.cpp | 3 +- nix/evmc.nix | 15 - 34 files changed, 2922 insertions(+), 1812 deletions(-) delete mode 100644 .bumpversion.cfg delete mode 100644 .dockerignore delete mode 100644 AUTHORS delete mode 100644 CHANGELOG.md delete mode 100644 Dockerfile delete mode 100644 appveyor.yml delete mode 100644 circle.yml delete mode 100644 codealike.json delete mode 100644 codecov.yml create mode 100644 lib/assigner/evmc/evmc.h create mode 100644 lib/assigner/evmc/evmc.hpp create mode 100644 lib/assigner/evmc/filter_iterator.hpp create mode 100644 lib/assigner/evmc/helpers.h create mode 100644 lib/assigner/evmc/hex.hpp create mode 100644 lib/assigner/evmc/utils.h delete mode 100644 nix/evmc.nix diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 6bddeda9..00000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[bumpversion] -current_version = 0.11.0-dev -tag = True -sign_tags = True -tag_message = evmone {new_version} -commit = True -message = evmone {new_version} - - Bump version: {current_version} -> {new_version} -parse = (?P\d+)\.(?P\d+)\.(?P\d+)(?P-dev)? -serialize = - {major}.{minor}.{patch}{prerel} - {major}.{minor}.{patch} - -[bumpversion:part:prerel] -optional_value = rel -values = - -dev - rel - -[bumpversion:file:CMakeLists.txt] diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index b99383ca..00000000 --- a/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -/.git/ -/.idea/ -/build/ -/.dockerignore -/Dockerfile diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index f4359db7..00000000 --- a/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Paweł Bylica diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 4dff642d..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,561 +0,0 @@ -# Changelog - -Documentation of all notable changes to the **evmone** project. - -The format is based on [Keep a Changelog], -and this project adheres to [Semantic Versioning]. - -## [0.10.0] — 2023-05-08 - -The highlights of this release are support for [Shanghai] execution specification upgrade -and implementation of EOF "v1.0". There are also big enhancements to the EVM testing tools -and infrastructure. In particular, we added the [t8n] command-line utility. - -As it is tradition, the EVM performance has been improved as well. -Comparing with the previous release using the "main" benchmark suite, -the Baseline interpreter is now: - -- 10–45% (mean 25%) faster for GCC builds, -- 0–19% (mean 11%) faster for Clang builds. - -### Added - -- **[Shanghai] support**: - - [EIP-3651]: Warm COINBASE (testing infrastructure only). - [#560](https://github.com/ethereum/evmone/pull/560) - - [EIP-3860]: Limit and meter initcode. - [#545](https://github.com/ethereum/evmone/pull/545) - - [EIP-4895]: Beacon chain push withdrawals as operations (testing infrastructure only). - [#614](https://github.com/ethereum/evmone/pull/614) -- **EVM Object Format "EOF v1.0"**: - - The implementation of the revisions of [EIP-3540], [EIP-3670], [EIP-4200], [EIP-4750] and [EIP-5450] - originally proposed for [Shanghai]. - [#563](https://github.com/ethereum/evmone/pull/563) - [#572](https://github.com/ethereum/evmone/pull/572) - [#594](https://github.com/ethereum/evmone/pull/594) - [#508](https://github.com/ethereum/evmone/pull/508) - - EOF is currently enabled in the [Cancun] revision but likely to be moved to Prague in the future. - [#561](https://github.com/ethereum/evmone/pull/561) - - Added `evmone-eofparse` and `evmone-eofparsefuzz` tools for testing EOF validation. - [#568](https://github.com/ethereum/evmone/pull/568) -- Implemented [EIP-663]: Unlimited SWAP and DUP instructions (enabled in EOF). - [#529](https://github.com/ethereum/evmone/pull/529) -- Added implementation of `evmc::Host`, **state transition** and block finalization for testing purposes. - [#484](https://github.com/ethereum/evmone/pull/484) - [#519](https://github.com/ethereum/evmone/pull/519) - [#575](https://github.com/ethereum/evmone/pull/575) - [#608](https://github.com/ethereum/evmone/pull/608) - [#609](https://github.com/ethereum/evmone/pull/609) -- Added **[t8n]** tool `evmone-t8n` - — a command line utility for transaction execution and state transition testing. - It allows executing and generating tests with cooperation of [retesteth] or [execution-spec-tests]. - [#552](https://github.com/ethereum/evmone/pull/552) - [#555](https://github.com/ethereum/evmone/pull/555) - [#558](https://github.com/ethereum/evmone/pull/558) - [#569](https://github.com/ethereum/evmone/pull/569) - [#583](https://github.com/ethereum/evmone/pull/583) - [#590](https://github.com/ethereum/evmone/pull/590) - [#591](https://github.com/ethereum/evmone/pull/591) - [#604](https://github.com/ethereum/evmone/pull/604) - [#606](https://github.com/ethereum/evmone/pull/606) - [#607](https://github.com/ethereum/evmone/pull/607) - [#612](https://github.com/ethereum/evmone/pull/612) -- Added partial support for EVM Precompiles - — gas cost computation and execution via _[JSON stub file](./test/state/precompiles_stub.json)_. - [#524](https://github.com/ethereum/evmone/pull/524) -- Declarative state transition unit test suite. - [#589](https://github.com/ethereum/evmone/pull/589) -- CMake option `EVMONE_X86_64_ARCH_LEVEL` to set the - [x86-64 microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels). - On Linux and Windows this is set to x86-64-v2 by default. - [#548](https://github.com/ethereum/evmone/pull/548) - -### Changed - -- C++20 is now required to build evmone. - [#502](https://github.com/ethereum/evmone/pull/502) -- Minimal tested/supported compilers versions: - [#535](https://github.com/ethereum/evmone/pull/535) - - GCC 11 - - Clang 13 - - XCode 13.4 - - Visual Studio 2022 - - CMake 3.16 -- [EVMC] has been upgraded to version [10.1.0][EVMC 10.1.0]. - [#623](https://github.com/ethereum/evmone/pull/623) -- [intx] has been upgraded to version [0.10.0][intx 0.10.0]. - [#622](https://github.com/ethereum/evmone/pull/622) -- [ethash] has been upgraded to version [1.0.0][ethash 1.0.0]. - [#540](https://github.com/ethereum/evmone/pull/540) -- [Ethereum Execution Tests] has been upgraded to version [12.2][tests 12.2]. - [#625](https://github.com/ethereum/evmone/pull/625) -- **Baseline interpreter optimizations**: - - Better stack overflow/underflow checks. - [#518](https://github.com/ethereum/evmone/pull/518) - - SWAP instructions optimization for Clang. - [#527](https://github.com/ethereum/evmone/pull/527) - - Pass gas counter to memory grow/check helpers by value. - [#598](https://github.com/ethereum/evmone/pull/598) - - Pass gas counter to instructions by value. - [#600](https://github.com/ethereum/evmone/pull/600) -- Changes to EVM tracing: - - Instruction trace prints `"gas"` and `"gasUsed"` as hex numbers to match geth. - [#592](https://github.com/ethereum/evmone/pull/592) - - C++ tracing API has separated the `gas` parameter. - [#599](https://github.com/ethereum/evmone/pull/599) -- Improvements to the JSON State Test execution tool `evmone-statetest`: - - Ability to load tests from multiple dirs/files. - [#512](https://github.com/ethereum/evmone/pull/512) - - Validate deployed EOF code before state test execution. - [#593](https://github.com/ethereum/evmone/pull/593) - [#601](https://github.com/ethereum/evmone/pull/601) - - Added `--trace` command-line flag to enable EVM execution tracing. - [#543](https://github.com/ethereum/evmone/pull/543) - - Other improvements. - [#556](https://github.com/ethereum/evmone/pull/556) - [#603](https://github.com/ethereum/evmone/pull/603) -- Benchmarks (invocable by `evmone-bench`) have been migrated to - external [evm-benchmarks] which use JSON State Test format. - [#513](https://github.com/ethereum/evmone/pull/513) - [#530](https://github.com/ethereum/evmone/pull/530) -- Removed dependency on `evmc::instructions`. - [#533](https://github.com/ethereum/evmone/pull/533) - [#534](https://github.com/ethereum/evmone/pull/534) - [#537](https://github.com/ethereum/evmone/pull/537) - -### Fixed - -- Fixed calling `Tracer.notify_execution_start`. - [#531](https://github.com/ethereum/evmone/pull/531) -- Fixed instruction tracing of EOF code. - [#536](https://github.com/ethereum/evmone/pull/536) - -### New Contributors - -- **[JSzymanskiJS](https://github.com/ethereum/evmone/commits?author=JSzymanskiJS)** - [#512](https://github.com/ethereum/evmone/pull/512) -- **[miles170](https://github.com/ethereum/evmone/commits?author=miles170)** - [#513](https://github.com/ethereum/evmone/pull/513) -- **[rodiazet](https://github.com/ethereum/evmone/commits?author=rodiazet)** - [#531](https://github.com/ethereum/evmone/pull/531) - - -## [0.9.1] — 2022-09-07 - -### Fixed - -- Resetting gas refund counter when execution state is reused. - [#504](https://github.com/ethereum/evmone/pull/504) - - -## [0.9.0] — 2022-08-30 - -In this release we have been focused on improving performance of the Baseline interpreter. -The end result is that the Baseline is **26% faster** than in previous version 0.8.0 -and **18% faster** than the current Advanced interpreter while having -over **8x smaller** code analysis cost. The Baseline is now the _default_ interpreter because -it is simpler and has become better than the Advanced. - -The Advanced also has got **4% faster** than in the previous version. - -All numbers are from running the "main" benchmark suite -on 4.0 GHz Intel Haswell CPU, using the Clang 15 compiler. - -Moreover, evmone now calculates _gas refund_ and reports it back using [EVMC 10][EVMC 10.0.0] API. - -Finally, the options `O=2` and `O=0` have been replaced by `advanced`. See below for details. - -### Added - -- Calculation of EVM gas refunds. - [#493](https://github.com/ethereum/evmone/pull/493) -- `PUSH0` instruction implementation ([EIP-3855]), enabled in [Shanghai]. - [#448](https://github.com/ethereum/evmone/pull/448) - [#432](https://github.com/ethereum/evmone/pull/432) -- Experimental [EOF] validation and execution ([EIP-3540]), enabled in [Shanghai]. - [#334](https://github.com/ethereum/evmone/pull/334) - [#366](https://github.com/ethereum/evmone/pull/366) - [#471](https://github.com/ethereum/evmone/pull/471) -- _In progress_ State Transition execution tool for testing purposes. So far we've merged: - - RLP encoding, - [#463](https://github.com/ethereum/evmone/pull/463) - - Merkle Patricia Trie root hash computing, - [#477](https://github.com/ethereum/evmone/pull/477) - [#478](https://github.com/ethereum/evmone/pull/478) - - JSON State Transition Test loader. - [#479](https://github.com/ethereum/evmone/pull/479) - -### Changed - -- EVMC options `O=0` (use Baseline) and `O=2` (use Advanced) have been replaced with single - option `advanced` to use the non-default Advanced interpreter. - [#500](https://github.com/ethereum/evmone/pull/500) -- Baseline has replaced Advanced as the default interpreter. The later can still be selected - with the `advanced` option. Reasons are explained in the introduction. - [#500](https://github.com/ethereum/evmone/pull/500) -- _A lot_ of changes related to the optimization of the Baseline interpreter, including - refactoring and optimization of instructions' implementations. -- The Baseline interpreter now uses "computed goto" dispatch if supported by C++ compiler. - The "switch" dispatch can be forced with the `cgoto=no` option. - [#495](https://github.com/ethereum/evmone/pull/495) -- Improvements to basic block metadata placement in the Advanced interpreter. - [#457](https://github.com/ethereum/evmone/pull/457) - [#474](https://github.com/ethereum/evmone/pull/474) -- [EVMC] has been upgraded to version [10.0.0][EVMC 10.0.0]. - [#499](https://github.com/ethereum/evmone/pull/499) -- [intx] has been upgrade to version [0.8.0][intx 0.8.0]. - [#446](https://github.com/ethereum/evmone/pull/446) - -### Removed - -- `evmone-fuzzer` has removed [aleth-interpreter][Aleth] as it is not maintained - and lacks the latest EVM features. - [#453](https://github.com/ethereum/evmone/pull/453) - - -## [0.8.2] — 2021-08-26 - -### Fixed - -- Fixed building of `evmone-standalone` static library when the `llvm-ar` tool is being used. - [#373](https://github.com/ethereum/evmone/pull/373) - [#374](https://github.com/ethereum/evmone/pull/374) - - -## [0.8.1] — 2021-08-03 - -### Fixed - -- baseline: Fix incorrect exit after invalid jump. - [#370](https://github.com/ethereum/evmone/pull/370) - - -## [0.8.0] — 2021-07-01 - -### Added - -- Full support for **[London]** EVM revision: - - [EVMC] upgraded to version [9.0.0][EVMC 9.0.0]. - [#348](https://github.com/ethereum/evmone/pull/348) - - Implementation of the [EIP-3198] "BASEFEE opcode". - [#333](https://github.com/ethereum/evmone/pull/333) -- Instruction tracing ([EIP-3155]) can be enabled via `trace` option in Baseline. - [#325](https://github.com/ethereum/evmone/pull/325) -- Summary of number of executed opcodes is reported if `histogram` option is enabled in Baseline. - [#323](https://github.com/ethereum/evmone/pull/323) -- The `evmone-bench` now reports time of execution without code analysis under "execute" label. - The EVMC-like analysis + execution invocation is reported as "total". - [#343](https://github.com/ethereum/evmone/pull/343) -- The `evmone-bench` has started utilizing `evmc::MockedHost` which allows using - state-access (e.g. `SLOAD`/`SSTORE`) instructions in benchmarks. - [#319](https://github.com/ethereum/evmone/pull/319) - -### Changed - -- Improvements to semi-public `evmone::baseline` API. - [#314](https://github.com/ethereum/evmone/pull/314) -- The [intx] has been upgraded to version [0.6.0][intx 0.6.0] - which increases performance of `ADDMOD` instruction. - [#345](https://github.com/ethereum/evmone/pull/345) -- The [ethash] has been upgraded to version [0.7.0][ethash 0.7.0] - which provides faster `KECCAK256` implementation. - [#332](https://github.com/ethereum/evmone/pull/332) -- Optimizations in Baseline interpreter. - [#315](https://github.com/ethereum/evmone/pull/315) - [#341](https://github.com/ethereum/evmone/pull/341) - [#344](https://github.com/ethereum/evmone/pull/344) -- The [Ethereum Execution Tests] upgraded to version [9.0.2][tests 9.0.2]. - [#349](https://github.com/ethereum/evmone/pull/349) - - -## [0.7.0] — 2021-04-27 - -### Added - -- Full support for **[Berlin]** EVM revision and [EIP-2929]. - [#289](https://github.com/ethereum/evmone/pull/289) - [#301](https://github.com/ethereum/evmone/pull/301) - -### Changed - -- [EVMC] has been upgraded to version [8.0.0][EVMC 8.0.0]. This ABI breaking - change has been required to support **Berlin** revision. - [#309](https://github.com/ethereum/evmone/pull/309) -- Optimizations to basic `JUMPDEST` analysis used by Baseline interpreter. - [#306](https://github.com/ethereum/evmone/pull/306) - [#308](https://github.com/ethereum/evmone/pull/308) -- The Baseline interpreter API has been modified to allow caching - of the `JUMPDEST` analysis. - [#305](https://github.com/ethereum/evmone/pull/305) -- The consensus testing is now driven by [Silkworm] as a replacement of - the unmaintained [Aleth]. The [Ethereum Execution Tests] [8.0.4][tests 8.0.4] are currently being used. - - -## [0.6.0] — 2021-04-07 - -### Added - -- New experimental **Baseline** interpreter has been added to the project. - It provides relatively straight-forward EVM implementation and - can be enabled with `O=0` option. - [#261](https://github.com/ethereum/evmone/pull/261) - [#280](https://github.com/ethereum/evmone/pull/280) -- A set of EVM synthetic benchmarks stressing individual - low-level EVM instructions. - [#278](https://github.com/ethereum/evmone/pull/278) -- [Silkworm]-driven integration and Ethereum consensus testing. - [#290](https://github.com/ethereum/evmone/pull/290) - -### Changed - -- [EVMC] upgraded to version [7.5.0][EVMC 7.5.0]. - [#294](https://github.com/ethereum/evmone/pull/294) -- `evmone-bench` tool under-the-hood improvements. - [#286](https://github.com/ethereum/evmone/pull/286) - [#287](https://github.com/ethereum/evmone/pull/287) - [#288](https://github.com/ethereum/evmone/pull/288) -- A lot of instructions implementation refactoring to allow code sharing - between Baseline and Advanced interpreters. - - -## [0.5.0] — 2020-06-24 - -### Changed - -- [intx] upgraded to version [0.5.0][intx 0.5.0], small performance increase for - `ADDMOD` and `MULMOD` instructions expected. - [#239](https://github.com/ethereum/evmone/pull/239) -- [EVMC] upgraded to version [7.4.0][EVMC 7.4.0]. - [#243](https://github.com/ethereum/evmone/pull/243) -- C++ exception handling and Run-Time Type Information (RTTI) have been disabled - for the evmone library (in GCC and Clang compilers). - [#244](https://github.com/ethereum/evmone/pull/244) - - -## [0.4.1] — 2020-04-01 - -### Fixed - -- The release binaries for Windows are now built without AVX instruction set - enabled. That was never intended and is consistent with binaries for other - operating systems. - [#230](https://github.com/ethereum/evmone/pull/230) - -## [0.4.0] — 2019-12-09 - -### Fixed - -- In previous versions evmone incorrectly assumed that code size cannot exceed - 24576 bytes (0x6000) — the limit introduced for the size of newly deployed - contracts by [EIP-170] in [Spurious Dragon]. The limit do not apply to - contract creating init code (i.e. in context of "create" transaction or CREATE - instruction). Therefore, the pre-processing phase in evmone has been reworked - to raise the technical limits or eliminated them entirely. From now on, only - blocks of instruction with total base gas cost exceeding 4294967295 (2³² - 1) - combined with execution gas limit also above this value can cause issues. - [#217](https://github.com/ethereum/evmone/pull/217) - [#218](https://github.com/ethereum/evmone/pull/218) - [#219](https://github.com/ethereum/evmone/pull/219) - [#221](https://github.com/ethereum/evmone/pull/221) - -### Changed - -- [EVMC] has been upgraded to version [7.1.0][EVMC 7.1.0]. - [#212](https://github.com/ethereum/evmone/pull/212) - -## [0.3.0] — 2019-11-14 - -This release of evmone adds changes for **[Istanbul]** EVM revision. - -### Added - -- **Istanbul** EVM revision support with new costs for some instructions ([EIP-1884]). - [#191](https://github.com/ethereum/evmone/pull/191) -- Implementation of CHAINID instruction from the **Istanbul** EVM revision ([EIP-1344]). - [#190](https://github.com/ethereum/evmone/pull/190) -- Implementation of SELFBALANCE instruction from the **Istanbul** EVM revision ([EIP-1884]). - [#24](https://github.com/ethereum/evmone/pull/24) -- Implementation of new cost model for SSTORE from the **Istanbul** EVM revision ([EIP-2200]). - [#142](https://github.com/ethereum/evmone/pull/142) - -### Changed - -- [EVMC] has been upgraded to version [7.0.0][EVMC 7.0.0]. - [#204](https://github.com/ethereum/evmone/pull/204) - - -## [0.2.0] — 2019-09-24 - -This release of evmone is binary compatible with 0.1 and delivers big performance improvements -– both code preprocessing and execution is **~66%** faster (needs ~40% less time). - -### Added - -- **evm-test** – the testing tool for [EVMC]-compatible EVM implementations. - [#85](https://github.com/ethereum/evmone/pull/85) -- **evmone-fuzzer** – the testing tool that fuzzes evmone execution against [aleth-interpreter][Aleth] execution. - Any other [EVMC]-compatible EVM implementation can be added easily. - [#162](https://github.com/ethereum/evmone/pull/162) - [#184](https://github.com/ethereum/evmone/pull/184) -- **evmone-standalone** – single static library that bundles evmone with all its static library dependencies - (available on Linux, but support can be extended to other platforms). - [#95](https://github.com/ethereum/evmone/pull/95) -- The **evmone-bench** tool has learned how to benchmark external [EVMC]-compatible EVMs. - [#111](https://github.com/ethereum/evmone/pull/111) -- The **evmone-bench** tool sorts test cases by file names and allows organizing them in subfolders. - [#150](https://github.com/ethereum/evmone/pull/150) -- The docker image [ethereum/evmone](https://hub.docker.com/r/ethereum/evmone) - with evmone and modified geth is available on Docker Hub. - [#127](https://github.com/ethereum/evmone/pull/127) - - -### Changed - -#### Optimizations - -- Instead of checking basic block preconditions (base gas cost, stack requirements) in the dispatch loop, - this is now done in the special "BEGINBLOCK" instruction — execution time reduction **-2–8%**. - [#74](https://github.com/ethereum/evmone/pull/74) -- New EVM stack implementation has replaced naïve usage of `std::vector` — **-8–16%**. - [#79](https://github.com/ethereum/evmone/pull/79) -- Improvements to interpreter's dispatch loop — **-4–9%**. - [#107](https://github.com/ethereum/evmone/pull/107) -- Optimization of the JUMPDEST map — up to **-34%**. - [#80](https://github.com/ethereum/evmone/pull/80) -- Optimizations to code preprocessing / analysis. - [#121](https://github.com/ethereum/evmone/pull/121) - [#125](https://github.com/ethereum/evmone/pull/125) - [#153](https://github.com/ethereum/evmone/pull/153) - [#168](https://github.com/ethereum/evmone/pull/168) - [#178](https://github.com/ethereum/evmone/pull/178) -- Push instructions with values up to 8 bytes (PUSH1–PUSH8) - are now handled much more efficiently — up to **-9%**. - [#122](https://github.com/ethereum/evmone/pull/122) -- Pointer to next instruction is now obtained in instruction implementations - (instead of the dispatch loop) and is kept in CPU registers only — **-3–7%**. - [#133](https://github.com/ethereum/evmone/pull/133) -- The run-time information about basic blocks has been compressed. - [#139](https://github.com/ethereum/evmone/pull/139) - [#144](https://github.com/ethereum/evmone/pull/144) - -#### Other changes - -- The DUP, SWAP, LOG and CALL instructions are now implemented by individual functions (template instances) - instead of a parametrized function handling each family of instructions. - [#126](https://github.com/ethereum/evmone/pull/126) - [#159](https://github.com/ethereum/evmone/pull/159) -- [EVMC] upgraded to version [6.3.1](https://github.com/ethereum/evmc/releases/tag/v6.3.1). - [#129](https://github.com/ethereum/evmone/pull/129) - [#77](https://github.com/ethereum/evmone/pull/77) - [#96](https://github.com/ethereum/evmone/pull/96) -- [intx] upgraded to version [0.4.0](https://github.com/chfast/intx/releases/tag/v0.4.0). - [#131](https://github.com/ethereum/evmone/pull/131) -- The ability to provide custom opcode table for code preprocessing has been dropped. - [#167](https://github.com/ethereum/evmone/pull/167) - - -### Fixed - -- The gas calculation for blocks containing an undefined instruction has been fixed. - This bug could not cause consensus issue because a block with an undefined instruction terminates - with an exception despite incorrect gas checking. - However, execution might have ended with a confusing error code. - [#93](https://github.com/ethereum/evmone/pull/93) -- Fix for LOG being emitted after _out-of-gas_ exception. - [#120](https://github.com/ethereum/evmone/pull/120) - - -## [0.1.1] — 2019-09-11 - -### Changed - -- [EVMC] upgraded to version 6.3.1 (still ABI-compatible with evmone 0.1.0). - [#171](https://github.com/ethereum/evmone/pull/171) -- Changes to the **evmone-bench** tool backported from 0.2. - This allows better performance comparison between 0.1 and 0.2 as both versions - can run the same set of benchmarks. - [#172](https://github.com/ethereum/evmone/pull/172) - - -## [0.1.0] — 2019-06-19 - -The first release of the evmone project. -It delivers fully-compatible and high-speed EVM implementation. - -### Added - -- Support for all current EVM revisions up to [Petersburg]. -- Exposes [EVMC] 6 ABI. -- The [intx 0.2.0](https://github.com/chfast/intx/releases/tag/v0.2.0) library is used for 256-bit precision arithmetic. - - -[0.10.0]: https://github.com/ethereum/evmone/releases/tag/v0.10.0 -[0.9.1]: https://github.com/ethereum/evmone/releases/tag/v0.9.1 -[0.9.0]: https://github.com/ethereum/evmone/releases/tag/v0.9.0 -[0.8.2]: https://github.com/ethereum/evmone/releases/tag/v0.8.2 -[0.8.1]: https://github.com/ethereum/evmone/releases/tag/v0.8.1 -[0.8.0]: https://github.com/ethereum/evmone/releases/tag/v0.8.0 -[0.7.0]: https://github.com/ethereum/evmone/releases/tag/v0.7.0 -[0.6.0]: https://github.com/ethereum/evmone/releases/tag/v0.6.0 -[0.5.0]: https://github.com/ethereum/evmone/releases/tag/v0.5.0 -[0.4.1]: https://github.com/ethereum/evmone/releases/tag/v0.4.1 -[0.4.0]: https://github.com/ethereum/evmone/releases/tag/v0.4.0 -[0.3.0]: https://github.com/ethereum/evmone/releases/tag/v0.3.0 -[0.2.0]: https://github.com/ethereum/evmone/releases/tag/v0.2.0 -[0.1.1]: https://github.com/ethereum/evmone/releases/tag/v0.1.1 -[0.1.0]: https://github.com/ethereum/evmone/releases/tag/v0.1.0 - -[Aleth]: https://github.com/ethereum/aleth -[EIP-170]: https://eips.ethereum.org/EIPS/eip-170 -[EIP-663]: https://eips.ethereum.org/EIPS/eip-663 -[EIP-1884]: https://eips.ethereum.org/EIPS/eip-1884 -[EIP-1344]: https://eips.ethereum.org/EIPS/eip-1344 -[EIP-2200]: https://eips.ethereum.org/EIPS/eip-2200 -[EIP-2929]: https://eips.ethereum.org/EIPS/eip-2929 -[EIP-3155]: https://eips.ethereum.org/EIPS/eip-3155 -[EIP-3198]: https://eips.ethereum.org/EIPS/eip-3198 -[EIP-3540]: https://eips.ethereum.org/EIPS/eip-3540 -[EIP-3651]: https://eips.ethereum.org/EIPS/eip-3651 -[EIP-3670]: https://eips.ethereum.org/EIPS/eip-3670 -[EIP-3855]: https://eips.ethereum.org/EIPS/eip-3855 -[EIP-3860]: https://eips.ethereum.org/EIPS/eip-3860 -[EIP-4200]: https://eips.ethereum.org/EIPS/eip-4200 -[EIP-4750]: https://eips.ethereum.org/EIPS/eip-4750 -[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 -[EIP-5450]: https://eips.ethereum.org/EIPS/eip-5450 -[Spurious Dragon]: https://eips.ethereum.org/EIPS/eip-607 -[Petersburg]: https://eips.ethereum.org/EIPS/eip-1716 -[Istanbul]: https://eips.ethereum.org/EIPS/eip-1679 -[Berlin]: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md -[London]: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md -[Shanghai]: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md -[Cancun]: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md -[EOF]: https://notes.ethereum.org/@ipsilon/evm-object-format-overview -[EVMC]: https://github.com/ethereum/evmc -[EVMC 10.1.0]: https://github.com/ethereum/evmc/releases/tag/v10.1.0 -[EVMC 10.0.0]: https://github.com/ethereum/evmc/releases/tag/v10.0.0 -[EVMC 9.0.0]: https://github.com/ethereum/evmc/releases/tag/v9.0.0 -[EVMC 8.0.0]: https://github.com/ethereum/evmc/releases/tag/v8.0.0 -[EVMC 7.5.0]: https://github.com/ethereum/evmc/releases/tag/v7.5.0 -[EVMC 7.4.0]: https://github.com/ethereum/evmc/releases/tag/v7.4.0 -[EVMC 7.1.0]: https://github.com/ethereum/evmc/releases/tag/v7.1.0 -[EVMC 7.0.0]: https://github.com/ethereum/evmc/releases/tag/v7.0.0 -[intx]: https://github.com/chfast/intx -[intx 0.10.0]: https://github.com/chfast/intx/releases/tag/v0.10.0 -[intx 0.8.0]: https://github.com/chfast/intx/releases/tag/v0.8.0 -[intx 0.6.0]: https://github.com/chfast/intx/releases/tag/v0.6.0 -[intx 0.5.0]: https://github.com/chfast/intx/releases/tag/v0.5.0 -[ethash]: https://github.com/chfast/ethash -[ethash 0.7.0]: https://github.com/chfast/ethash/releases/tag/v0.7.0 -[ethash 1.0.0]: https://github.com/chfast/ethash/releases/tag/v1.0.0 -[Ethereum Execution Tests]: https://github.com/ethereum/tests -[tests 12.2]: https://github.com/ethereum/tests/releases/tag/v12.2 -[tests 9.0.2]: https://github.com/ethereum/tests/releases/tag/9.0.2 -[tests 8.0.4]: https://github.com/ethereum/tests/releases/tag/8.0.4 -[evm-benchmarks]: https://github.com/ipsilon/evm-benchmarks -[execution-spec-tests]: https://github.com/ethereum/execution-spec-tests -[retesteth]: https://github.com/ethereum/retesteth -[Silkworm]: https://github.com/torquem-ch/silkworm -[t8n]: https://ethereum-tests.readthedocs.io/en/develop/t8ntool-ref.html -[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/ -[Semantic Versioning]: https://semver.org/spec/v2.0.0.html diff --git a/CMakeLists.txt b/CMakeLists.txt index b7055f83..63796a73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,6 @@ if(PROJECT_VERSION_MAJOR EQUAL 0) endif() find_package(ethash CONFIG REQUIRED) -find_package(evmc REQUIRED) cable_configure_compiler(NO_STACK_PROTECTION) if(CABLE_COMPILER_GNULIKE) diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 094ec48c..00000000 --- a/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM debian:testing as evmone - -RUN apt-get update -q && apt-get install -qy --no-install-recommends \ - ca-certificates g++ cmake ninja-build \ - && rm -rf /var/lib/apt/lists/* - -ADD . /src -RUN mkdir /build \ - && cmake -S /src -B /build -G Ninja -DEVMONE_TESTING=ON -DHUNTER_ROOT=/build \ - && cmake --build /build --target install \ - && ldconfig \ - && rm /build -rf \ - && adduser --disabled-password --no-create-home --gecos '' evmone -USER evmone diff --git a/LICENSE b/LICENSE index d6456956..de2951a0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,202 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2024 =nil; Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 576cdf50..72853350 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ Created by members of the [Ipsilon] (ex-[Ewasm]) team. ### Libraries -- [evmc](https://github.com/ethereum/evmc) - [intx](https://github.com/chfast/intx) - [ethash](https://github.com/chfast/ethash) - [blueprint](https://github.com/NilFoundation/zkllvm-blueprint) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 1616ecd8..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: "{build}" -image: Visual Studio 2019 - -branches: - only: - - master - - /release\/.*/ - - appveyor - - hunter - - /v\d+\..+/ -configuration: - - Release - - Debug -environment: - GITHUB_TOKEN: - secure: OE3TGKRyt/hvk5Gt3DLXvs3Y+F1NLDQAL/bHplDffR+hY2aFg6HrapThKjYo/XX2 - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - GENERATOR: "Ninja" - -cache: - - C:\.hunter\_Base\Cache -> cmake\Hunter\init.cmake - -install: - - cmake --version - - git submodule update --init --recursive - -before_build: - - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd" -arch=amd64 - - cmake -S . -B build -DEVMONE_TESTING=ON -Wno-dev -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DHUNTER_CONFIGURATION_TYPES=%CONFIGURATION% -DCMAKE_INSTALL_PREFIX=C:\install - -build_script: - - cmake --build build --target package - - mkdir package - - mv build/evmone-* package - -artifacts: - - path: package/* - name: package - -test_script: - - cd build && ctest -j4 --output-on-failure --schedule-random - -deploy_script: - - ps: >- - if ($env:appveyor_repo_tag_name -match 'v\d+\..+') { - - $env:GO111MODULE = "on" - go get github.com/tcnksm/ghr@v0.12.1 2>$null - $env:PATH += ";$env:USERPROFILE\go\bin" - - cd $env:appveyor_build_folder - $name = "evmone " + ($env:appveyor_repo_tag_name).Remove(0,1) - if (($env:appveyor_repo_tag_name).Contains("-")) { - $prerelease_flag = "-prerelease" - } - echo $name - echo $prerelease_flag - ghr -u ethereum -r evmone -n "$name" $prerelease_flag $env:appveyor_repo_tag_name package/ - } diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 6de5a197..00000000 --- a/circle.yml +++ /dev/null @@ -1,773 +0,0 @@ -version: 2.1 -orbs: - win: circleci/windows@5.0 - -executors: - lint: - docker: - - image: ethereum/cpp-build-env:20-lint - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - linux-gcc-latest: - docker: - - image: ethereum/cpp-build-env:20-gcc-13 - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 4 - linux-gcc-multilib: - docker: - - image: ethereum/cpp-build-env:20-gcc-13-multilib - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - blockchain-tests: - docker: - - image: ethereum/cpp-build-env:20-gcc-13 - resource_class: xlarge - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 8 - linux-clang-xlarge: - docker: - - image: ethereum/cpp-build-env:20-clang-16 - resource_class: xlarge - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 8 - linux-gcc-min: - docker: - - image: ethereum/cpp-build-env:17-gcc-11 - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - linux-clang-latest: - docker: - - image: ethereum/cpp-build-env:20-clang-16 - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 4 - linux-clang-min: - docker: - - image: ethereum/cpp-build-env:18-clang-13 - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - linux-base: - docker: - - image: cimg/base:edge-22.04 - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - macos: - resource_class: macos.x86.medium.gen2 - macos: - xcode: 15.0.0 - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 4 - macos-m1: - resource_class: macos.m1.large.gen1 - macos: - xcode: 15.0.0 - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 8 - macos-xcode-min: - resource_class: macos.x86.medium.gen2 - macos: - xcode: 14.3.1 - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 4 - -commands: - install_cmake: - parameters: - version: - type: string - steps: - - run: - name: "Install CMake <>" - working_directory: /usr/local - command: | - curl -L https://github.com/Kitware/CMake/releases/download/v<>/cmake-<>-linux-x86_64.tar.gz | sudo tar -xz --strip=1 - - install_riscv_toolchain: - steps: - - run: - name: "Install RISC-V Toolchain" - working_directory: /usr/local - command: | - curl -L https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.07.07/riscv32-glibc-ubuntu-22.04-llvm-nightly-2023.07.07-nightly.tar.gz | sudo tar -xz - - checkout_submodules: - steps: - - run: - name: "Update submodules" - command: git submodule update --init --recursive - - build_silkworm: - parameters: - branch: - type: string - default: master - commit: - type: string - steps: - - run: - # Fixes the cache restore step in case the silkworm dir does not exist - name: "Make Silkworm dir" - command: mkdir -p ~/silkworm - - restore_cache: - name: "Restore Silkworm cache (<>-<>)" - key: &silkworm-cache-key silkworm-v2-<>-<> - - run: - name: "Check Silkworm cache" - command: | - if [ -f ~/silkworm/ethereum ]; then - echo 'Cached Silkworm binary available - skip build.' - else - echo 'export SILKWORM_BUILD=true' >> $BASH_ENV - fi - - run: - name: "Checkout Silkworm" - working_directory: ~/silkworm/src - command: | - [ "$SILKWORM_BUILD" = true ] || exit 0 - git clone --no-checkout --single-branch https://github.com/torquem-ch/silkworm.git . --branch <> - git checkout <> - git submodule update --init --recursive --progress - - run: - name: "Install conan" - # Use conan version from the Silkworm documentation. - # https://github.com/erigontech/silkworm#building-on-linux--macos - command: sudo pip install --break-system-packages conan==1.60.2 - - run: - name: "Configure Silkworm" - working_directory: ~/silkworm - command: | - [ "$SILKWORM_BUILD" = true ] || exit 0 - cmake -S src -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=$(pwd) - - run: - name: "Build Silkworm cmd/test/ethereum" - working_directory: ~/silkworm - command: | - [ "$SILKWORM_BUILD" = true ] || exit 0 - cmake --build build --target ethereum - - save_cache: - name: "Save Silkworm cache" - key: *silkworm-cache-key - paths: - - ~/silkworm/ethereum - - download_execution_tests: - parameters: - repo: - type: string - default: "ethereum/tests" - rev: - type: string - default: develop - commit: - type: string - default: "" - legacy: - description: "Download also legacy tests" - type: boolean - default: true - steps: - - run: - name: "Download execution tests: <> <>" - working_directory: ~/tests - command: | - find . -delete - git clone --no-checkout --depth=100 --single-branch https://github.com/<> . --branch <> - <<#parameters.rev>>git checkout <><> - <<#parameters.commit>>git checkout <><> - - when: - condition: <> - steps: - - run: - name: "Download legacy execution tests (git submodule)" - working_directory: ~/tests - command: git submodule update --init --recursive --depth=1 --progress - - download_execution_spec_tests: - steps: - - run: - name: "Download execution-spec-tests" - working_directory: ~/spec-tests - command: | - curl -L https://github.com/ethereum/execution-spec-tests/releases/download/v1.0.6/fixtures_develop.tar.gz | tar -xz - ls -l - - build: - description: "Build" - steps: - - checkout - - checkout_submodules - - run: - name: "Environment" - command: | - CC=${CC:-cc} - CXX=${CXX:-cpp} - echo CC: $CC - echo CXX: $CXX - $CC --version - $CXX --version - cmake --version - echo CMAKE_BUILD_PARALLEL_LEVEL: $CMAKE_BUILD_PARALLEL_LEVEL - - # Create the build.info file for cache key. - echo $TOOLCHAIN >> build.info - echo $CMAKE_OPTIONS >> build.info - $CXX --version >> build.info - - printf '\n-----------\nbuild.info:\n' - cat build.info - - restore_cache: - name: "Restore Hunter cache" - key: &hunter-cache-key hunter-{{arch}}-{{checksum "build.info"}}-{{checksum "cmake/Hunter/init.cmake"}}-{{checksum "cmake/Hunter/config.cmake"}} - - run: - name: "Configure" - working_directory: ~/build - command: | - if [ "$TOOLCHAIN" ]; then - export toolchain_option="-DTOOLCHAIN=$TOOLCHAIN" - fi - cmake ../project $toolchain_option -DCMAKE_INSTALL_PREFIX=~/install -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DEVMONE_TESTING=ON $CMAKE_OPTIONS - - save_cache: - name: "Save Hunter cache" - key: *hunter-cache-key - paths: - - ~/.hunter/_Base/Cache - - run: - name: "Build" - command: cmake --build ~/build - - run: - name: "Install" - command: cmake --build ~/build --target install - - test: - description: "Test" - steps: - - run: - name: "Test" - shell: bash - working_directory: ~/build - command: ctest -R ${TESTS_FILTER:-'.*'} --schedule-random --output-on-failure --parallel $CMAKE_BUILD_PARALLEL_LEVEL --output-junit ~/test_results/evmone.xml - - store_test_results: - path: ~/test_results - - collect_coverage_gcc: - description: "Collect coverage data (GCC)" - steps: - - run: - name: "Collect coverage data (GCC)" - working_directory: ~/build - command: | - lcov --capture --directory . --output-file coverage.lcov --exclude='/usr/*' --exclude="$HOME/.hunter/*" --exclude="$PWD/_deps/*" - lcov --zerocounters --directory . - rm -rf ~/coverage - genhtml coverage.lcov --output-directory ~/coverage --title $CIRCLE_PROJECT_REPONAME - - store_artifacts: - path: ~/coverage - destination: coverage - - upload_coverage: - description: "Upload coverage data" - parameters: - flags: - type: string - steps: - - run: - name: "Install codecov" - command: | - export CODECOV_VERSION=v0.5.0 - curl -Os https://uploader.codecov.io/$CODECOV_VERSION/linux/codecov - curl -Os https://uploader.codecov.io/$CODECOV_VERSION/linux/codecov.SHA256SUM - curl -Os https://uploader.codecov.io/$CODECOV_VERSION/linux/codecov.SHA256SUM.sig - - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - shasum -c codecov.SHA256SUM - - chmod +x codecov - sudo mv codecov /usr/local/bin - - - run: - name: "Upload to Codecov" - command: | - # Convert to relative paths - sed -i 's|$(pwd)/||' ~/build/coverage.lcov - codecov --flags <> --required --file ~/build/coverage.lcov -X gcov - - package: - description: "Make package" - steps: - - run: - name: "Build Package" - shell: bash - working_directory: ~/package - command: cmake --build ~/build --target package && mv ~/build/evmone-*.* . - - store_artifacts: - path: ~/package - destination: package - - persist_to_workspace: - root: ~/package - paths: - - evmone-* - - unpack_package: - steps: - - attach_workspace: - at: ~/package - - run: - name: "Unpack evmone" - working_directory: ~/package - command: tar xz < evmone*.tar.gz - -jobs: - - lint: - executor: lint - steps: - - checkout - - run: - name: "Check code format" - command: | - clang-format --version - find include lib test -name '*.hpp' -o -name '*.cpp' -o -name '*.h' -o -name '*.c' | xargs clang-format -i - git diff --color --exit-code - - run: - name: "Check spelling" - command: | - codespell --quiet-level=4 --skip=.git - - release-linux: - executor: linux-gcc-latest - environment: - BUILD_TYPE: Release - steps: - - build - - test - - package - - release-windows: - executor: win/server-2022 - environment: - CMAKE_BUILD_TYPE: Release - CMAKE_BUILD_PARALLEL_LEVEL: 4 - steps: - - checkout - - checkout_submodules - - run: - name: "Setup environment (bash)" - shell: bash - command: | - echo 'export PATH=$PATH:"/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin"' >> $BASH_ENV - - run: - name: 'Configure' - shell: powershell - command: | - $ErrorActionPreference = "Stop" - & 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch amd64 - which cmake - cmake -S . -B ~/build -G Ninja -DCMAKE_INSTALL_PREFIX=C:\install -DEVMONE_TESTING=ON - - run: - name: 'Build' - shell: powershell - command: | - $ErrorActionPreference = "Stop" - & 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch amd64 - cmake --build ~/build - - test - - package - - release-windows-32bit: - executor: win/server-2022 - environment: - CMAKE_BUILD_TYPE: Release - CMAKE_BUILD_PARALLEL_LEVEL: 4 - steps: - - checkout - - checkout_submodules - - run: - name: "Setup environment (bash)" - shell: bash - command: | - echo 'export PATH=$PATH:"/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin"' >> $BASH_ENV - - run: - name: 'Configure' - shell: powershell - command: | - $ErrorActionPreference = "Stop" - & 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch x86 - which cmake - cmake -S . -B ~/build -G Ninja -DCMAKE_INSTALL_PREFIX=C:\install -DEVMONE_TESTING=ON - - run: - name: 'Build' - shell: powershell - command: | - $ErrorActionPreference = "Stop" - & 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch x86 - cmake --build ~/build - - test - - package - - release-macos: - executor: macos - environment: - BUILD_TYPE: Release - steps: - - run: - name: "Install System Dependencies" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake - - build - - test - - package - - release-macos-m1: - executor: macos-m1 - environment: - BUILD_TYPE: Release - steps: - - run: - name: "Install System Dependencies" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake - - build - - test - - package - - deploy: - docker: - - image: circleci/golang - steps: - - run: - name: "Install GHR" - command: | - GO111MODULE=on go get github.com/tcnksm/ghr@v0.12.1 - - attach_workspace: - at: ~/package - - run: - name: "Create GitHub release" - command: | - ls -l ~/package - prerelease_flag=$([[ $CIRCLE_TAG =~ ^v[0-9\.]+$ ]] || echo '-prerelease') - name="$CIRCLE_PROJECT_REPONAME ${CIRCLE_TAG:1}" - echo $name - ghr -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -n "$name" $prerelease_flag $CIRCLE_TAG ~/package - - blockchain-tests: - executor: blockchain-tests - environment: - BUILD_TYPE: Coverage - CMAKE_OPTIONS: -DEVMONE_TESTING=OFF -DCMAKE_CXX_FLAGS=-Og - steps: - - build - - build_silkworm: - branch: evmc-v11.0.0-alpha.1 - commit: evmc-v11.0.0-alpha.1 - - download_execution_tests: - rev: v13 - - run: - name: "Silkworm-driven blockchain tests (Advanced)" - working_directory: ~/build - no_output_timeout: 20m - command: ~/silkworm/ethereum --evm lib/libevmone.so,advanced --tests ~/tests --threads $CMAKE_BUILD_PARALLEL_LEVEL - - run: - name: "Silkworm-driven blockchain tests (Baseline)" - working_directory: ~/build - no_output_timeout: 20m - command: ~/silkworm/ethereum --evm lib/libevmone.so --tests ~/tests --threads $CMAKE_BUILD_PARALLEL_LEVEL - - collect_coverage_gcc - - upload_coverage: - flags: blockchaintests - - state-tests: - executor: blockchain-tests - environment: - BUILD_TYPE: Coverage - CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-Og - steps: - - download_execution_spec_tests - - build - - run: - name: "Execution spec tests" - working_directory: ~/build - command: > - EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json - bin/evmone-blockchaintest ~/spec-tests/fixtures - - - download_execution_tests: - rev: v13 - - run: - name: "State tests" - working_directory: ~/build - command: > - EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json - bin/evmone-statetest - ~/tests/GeneralStateTests - ~/tests/LegacyTests/Constantinople/GeneralStateTests - - run: - name: "Blockchain tests (GeneralStateTests)" - working_directory: ~/build - command: > - EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json - bin/evmone-blockchaintest - --gtest_filter='*:-VMTests/vmPerformance.*:*.*Call50000_sha256' - ~/tests/BlockchainTests/GeneralStateTests - - run: - name: "Blockchain tests (ValidBlocks)" - working_directory: ~/build - command: > - EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json - bin/evmone-blockchaintest - --gtest_filter='*:-bcMultiChainTest.*:bcTotalDifficultyTest.*:bcForkStressTest.ForkStressTest:bcGasPricerTest.RPC_API_Test:bcValidBlockTest.SimpleTx3LowS' - ~/tests/BlockchainTests/ValidBlocks - - run: - name: "Blockchain tests (EIPs)" - working_directory: ~/build - command: > - EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json - bin/evmone-blockchaintest - --gtest_filter='-*StateTests/stEOF/*.*' - ~/tests/EIPTests/BlockchainTests/ - - download_execution_tests: - repo: ipsilon/tests - rev: eof-nrf-20231128 - legacy: false - - run: - name: "State tests (EOF)" - working_directory: ~/build - command: | - bin/evmone-statetest ~/tests/EIPTests/StateTests/stEOF - - run: - name: "EOF validation tests" - working_directory: ~/build - command: | - bin/evmone-eoftest ~/tests/EOFTests - - collect_coverage_gcc - - upload_coverage: - flags: statetests - - precompiles-silkpre: - executor: blockchain-tests - environment: - BUILD_TYPE: Coverage - CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-Og -DEVMONE_PRECOMPILES_SILKPRE=1 - steps: - - run: - name: "Install GMP" - command: sudo apt-get -q update && sudo apt-get -qy install libgmp-dev - - build - - download_execution_tests: - rev: v12.4 - - run: - name: "State tests" - working_directory: ~/build - command: | - bin/evmone-statetest ~/tests/GeneralStateTests ~/tests/LegacyTests/Constantinople/GeneralStateTests - - collect_coverage_gcc - - upload_coverage: - flags: statetests-silkpre - - gcc-min: - executor: linux-gcc-min - steps: - - build - - test - - clang-min: - executor: linux-clang-min - steps: - - build - - test - - - gcc-latest-coverage: - executor: linux-gcc-latest - environment: - BUILD_TYPE: Coverage - TESTS_FILTER: unittests|integration - steps: - - build - - test - - collect_coverage_gcc - - upload_coverage: - flags: unittests - - gcc-latest-memcheck: - executor: linux-gcc-latest - environment: - BUILD_TYPE: Debug - CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-O1 - steps: - - build - - test - - run: - name: "memcheck" - working_directory: ~/build - command: valgrind --vgdb=no --error-exitcode=99 bin/evmone-unittests - - gcc-32bit: - executor: linux-gcc-multilib - environment: - TOOLCHAIN: cxx17-32bit - steps: - - build - - test - - clang-latest-sanitizers: - executor: linux-clang-xlarge - environment: - CMAKE_OPTIONS: -DBUILD_SHARED_LIBS=NO -DSANITIZE=address,undefined,shift-exponent,implicit-conversion,nullability -DCMAKE_CXX_CLANG_TIDY=clang-tidy - UBSAN_OPTIONS: halt_on_error=1 - steps: - - build - - test - - clang-latest-coverage: - executor: linux-clang-latest - resource_class: small - environment: - CMAKE_BUILD_PARALLEL_LEVEL: 2 - BUILD_TYPE: Coverage - TESTS_FILTER: unittests|integration - steps: - - build - - test - - run: - name: "Coverage report" - working_directory: ~/build - command: | - ARGS='lib/libevmone.so -Xdemangler llvm-cxxfilt -instr-profile=evmone.profdata -ignore-filename-regex=include/evmc' - SHOW_ARGS='-format=html -show-branches=count -show-regions -show-expansions' - - mkdir ~/coverage - llvm-profdata merge *.profraw -o evmone.profdata - llvm-cov show $ARGS $SHOW_ARGS > ~/coverage/full.html - llvm-cov show $ARGS $SHOW_ARGS -region-coverage-lt=100 > ~/coverage/missing.html - - llvm-cov report $ARGS > ~/coverage/report.txt - llvm-cov report $ARGS -use-color - - store_artifacts: - path: ~/coverage - destination: coverage - - fuzzing: - executor: linux-clang-xlarge - environment: - CMAKE_OPTIONS: -DEVMONE_FUZZING=ON - steps: - - build - - restore_cache: - name: "Restore fuzzing corpus" - key: fuzzing-corpus - - run: - name: "Run evmone-fuzzer" - working_directory: ~/build - command: | - bin/evmone-fuzzer -runs=5000000 -fork=$CMAKE_BUILD_PARALLEL_LEVEL -fork_corpus_groups=1 ~/corpus -create_missing_dirs=1 -max_len=100 -entropic_scale_per_exec_time=1 2>&1 | sed '/NEW_FUNC/d' - - save_cache: - name: "Save fuzzing corpus" - key: fuzzing-corpus-{{epoch}} - paths: - - ~/corpus - - macos-asan: - executor: macos-m1 - environment: - BUILD_TYPE: RelWithDebInfo - CMAKE_OPTIONS: -DSANITIZE=address,undefined - TESTS_FILTER: unittests - steps: - - run: - name: "Install System Dependencies" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake - - build - - test - - xcode-min: - executor: macos-xcode-min - steps: - - run: - name: "Install System Dependencies" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake - - build - - test - - cmake-min: - executor: linux-base - steps: - - install_cmake: - version: 3.16.9 - - build - - test - - x86-64-v1: - executor: linux-gcc-latest - environment: - BUILD_TYPE: Release - QEMU_CPU: core2duo # The lowest 64-bit CPU I could find, but qemu64 should be good too. - steps: - - build - - run: - name: "Check evmone.so" - working_directory: ~/build - command: (! qemu-x86_64-static bin/evmc run --vm ./lib/libevmone.so,trace 6000 2>&1) | grep "CPU does not support" - - run: - name: "Check unittests" - working_directory: ~/build - command: (! qemu-x86_64-static bin/evmone-unittests 2>&1) | grep "CPU does not support" - - riscv32: - executor: linux-gcc-latest - environment: - BUILD_TYPE: Release - CMAKE_OPTIONS: -DCMAKE_TOOLCHAIN_FILE=~/project/cmake/toolchains/riscv32.cmake - steps: - - install_riscv_toolchain - - build - - test - - - -workflows: - version: 2 - evmone: - jobs: - - lint - - release-linux: - filters: - tags: - only: /.*/ - - release-windows: - filters: - tags: - only: /.*/ - - release-windows-32bit - - release-macos: - filters: - tags: - only: /.*/ - - release-macos-m1 - - deploy: - requires: - - release-linux - - release-windows - - release-macos - filters: - branches: - ignore: /.*/ - tags: - only: /^v[0-9].*/ - - state-tests - - precompiles-silkpre - - blockchain-tests - - cmake-min - - gcc-min - - clang-min - - gcc-latest-coverage - - gcc-latest-memcheck - - clang-latest-sanitizers - - clang-latest-coverage - - macos-asan - - xcode-min - - gcc-32bit - - x86-64-v1 - - riscv32 - - fuzzing diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in index 305b3424..a119cd10 100644 --- a/cmake/Config.cmake.in +++ b/cmake/Config.cmake.in @@ -3,7 +3,6 @@ include(CMakeFindDependencyMacro) find_dependency(crypto3 REQUIRED) find_dependency(crypto3_blueprint REQUIRED) -find_dependency(evmc REQUIRED) find_dependency(intx REQUIRED) find_dependency(ethash REQUIRED) diff --git a/codealike.json b/codealike.json deleted file mode 100644 index abe11c00..00000000 --- a/codealike.json +++ /dev/null @@ -1 +0,0 @@ -{"projectId":"cb431fbb-c9ef-4e1a-a15c-47e63373c0df","projectName":"evmone"} \ No newline at end of file diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 0578a660..00000000 --- a/codecov.yml +++ /dev/null @@ -1,16 +0,0 @@ -codecov: - require_ci_to_pass: false - -comment: - layout: "diff, flags, files" - -flags: - statetests: - paths: - - lib/evmone - - test/state - - test/statetest - blockchaintests: - joined: false - paths: - - lib/evmone diff --git a/flake.lock b/flake.lock index 04b5029a..c78da9e1 100644 --- a/flake.lock +++ b/flake.lock @@ -18,45 +18,28 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "nil-crypto3": { "inputs": { - "nix-3rdparty": "nix-3rdparty", + "nix-3rdparty": [ + "nix-3rdparty" + ], "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1720036529, - "narHash": "sha256-Ub38Lwsy0PzQtJ+3cfqbVVAXrDuu0A4i1i3vPT9Nxa0=", - "ref": "refs/heads/master", - "rev": "c34662a28869af63afc67789435390a2a8f3c708", - "revCount": 9148, - "submodules": true, - "type": "git", - "url": "https://github.com/NilFoundation/crypto3" + "lastModified": 1720200505, + "narHash": "sha256-eKb9e/+E+jZKdoJrsvUhaKqElfio6PMl97W+bSvKq+Q=", + "owner": "NilFoundation", + "repo": "crypto3", + "rev": "3bd5b8df2091274abaa28fd86b9e3e89d661b95a", + "type": "github" }, "original": { - "submodules": true, - "type": "git", - "url": "https://github.com/NilFoundation/crypto3" + "owner": "NilFoundation", + "repo": "crypto3", + "rev": "3bd5b8df2091274abaa28fd86b9e3e89d661b95a", + "type": "github" } }, "nil-zkllvm-blueprint": { @@ -82,34 +65,13 @@ "url": "https://github.com/NilFoundation/zkllvm-blueprint" }, "original": { + "rev": "73d6a40e39b6b6fc7b1c84441e62337206dc0815", "submodules": true, "type": "git", "url": "https://github.com/NilFoundation/zkllvm-blueprint" } }, "nix-3rdparty": { - "inputs": { - "flake-utils": "flake-utils_2", - "nixpkgs": [ - "nil-crypto3", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1717519917, - "narHash": "sha256-GqzEqEW4Uz9Z7uDZwers0t9seWRNbRWPNE3OJnjE1Uw=", - "owner": "NilFoundation", - "repo": "nix-3rdparty", - "rev": "a2e45429aa25a4a6e8e362ef17df6f197312f224", - "type": "github" - }, - "original": { - "owner": "NilFoundation", - "repo": "nix-3rdparty", - "type": "github" - } - }, - "nix-3rdparty_2": { "inputs": { "flake-utils": [ "flake-utils" @@ -119,11 +81,11 @@ ] }, "locked": { - "lastModified": 1717421108, - "narHash": "sha256-TuMP6k7KFqAiauPajsWERrmj2Hw3UIcxXUTUUgc5uhw=", + "lastModified": 1717519917, + "narHash": "sha256-GqzEqEW4Uz9Z7uDZwers0t9seWRNbRWPNE3OJnjE1Uw=", "owner": "NilFoundation", "repo": "nix-3rdparty", - "rev": "39c6b74a759804dc581c8d15990e6a10ae9d2027", + "rev": "a2e45429aa25a4a6e8e362ef17df6f197312f224", "type": "github" }, "original": { @@ -134,16 +96,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1712741485, - "narHash": "sha256-bCs0+MSTra80oXAsnM6Oq62WsirOIaijQ/BbUY59tR4=", + "lastModified": 1721804089, + "narHash": "sha256-1a4FrLzn4I1xoASzWfhGEF3Gln33g4lrtRLDNybftak=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b2cf36f43f9ef2ded5711b30b1f393ac423d8f72", + "rev": "633ae2570ec145a008d7703886e78faa24b9c1bd", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.11", "repo": "nixpkgs", "type": "github" } @@ -153,7 +114,7 @@ "flake-utils": "flake-utils", "nil-crypto3": "nil-crypto3", "nil-zkllvm-blueprint": "nil-zkllvm-blueprint", - "nix-3rdparty": "nix-3rdparty_2", + "nix-3rdparty": "nix-3rdparty", "nixpkgs": "nixpkgs" } }, @@ -171,21 +132,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 1656346c..fd6e1309 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "Nix flake for EVM-assigner"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + nixpkgs.url = "github:NixOS/nixpkgs"; flake-utils.url = "github:numtide/flake-utils"; nix-3rdparty = { url = "github:NilFoundation/nix-3rdparty"; @@ -14,15 +14,17 @@ nil-crypto3 = { url = "https://github.com/NilFoundation/crypto3"; type = "git"; - submodules = true; + rev = "3bd5b8df2091274abaa28fd86b9e3e89d661b95a"; inputs = { nixpkgs.follows = "nixpkgs"; + nix-3rdparty.follows = "nix-3rdparty"; }; }; nil-zkllvm-blueprint = { url = "https://github.com/NilFoundation/zkllvm-blueprint"; type = "git"; submodules = true; + rev = "73d6a40e39b6b6fc7b1c84441e62337206dc0815"; inputs = { nixpkgs.follows = "nixpkgs"; flake-utils.follows = "flake-utils"; @@ -72,7 +74,6 @@ }: let deps = with pkgs; [ - (evmc.override { inherit enableDebug; }) (intx.override { inherit enableDebug; }) ethash ]; diff --git a/lib/assigner/CMakeLists.txt b/lib/assigner/CMakeLists.txt index 37a598c8..96d921a0 100644 --- a/lib/assigner/CMakeLists.txt +++ b/lib/assigner/CMakeLists.txt @@ -21,10 +21,11 @@ find_package(crypto3_blueprint REQUIRED) target_include_directories(${PROJECT_NAME} PUBLIC $ $ + $ $) target_link_libraries(${PROJECT_NAME} - PUBLIC evmc::evmc intx::intx crypto3::all crypto3::blueprint ethash::keccak) + PUBLIC intx::intx crypto3::all crypto3::blueprint ethash::keccak) set_target_properties( ${PROJECT_NAME} @@ -48,6 +49,12 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/evmone/execution_state.hpp ${CMAKE_CURRENT_SOURCE_DIR}/evmone/baseline.hpp ${CMAKE_CURRENT_SOURCE_DIR}/evmone/eof.hpp ${CMAKE_CURRENT_SOURCE_DIR}/evmone/instructions_opcodes.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/evmc.h + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/evmc.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/filter_iterator.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/helpers.h + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/hex.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/evmc/utils.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(BUILD_ASSIGNER_TESTS) add_subdirectory(test) diff --git a/lib/assigner/evmc/evmc.h b/lib/assigner/evmc/evmc.h new file mode 100644 index 00000000..f0578034 --- /dev/null +++ b/lib/assigner/evmc/evmc.h @@ -0,0 +1,1198 @@ +/** + * EVMC: Ethereum Client-VM Connector API + * + * @copyright + * Copyright 2016 The EVMC Authors. + * Licensed under the Apache License, Version 2.0. + * + * @defgroup EVMC EVMC + * @{ + */ +#ifndef EVM_ASSIGNER_EVMC_EVMC_H_ +#define EVM_ASSIGNER_EVMC_EVMC_H_ + +#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 6) +/** + * Portable declaration of "deprecated" attribute. + * + * Available for clang and GCC 6+ compilers. The older GCC compilers know + * this attribute, but it cannot be applied to enum elements. + */ +#define EVMC_DEPRECATED __attribute__((deprecated)) +#else +#define EVMC_DEPRECATED +#endif + + +#include /* Definition of bool, true and false. */ +#include /* Definition of size_t. */ +#include /* Definition of int64_t, uint64_t. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN Python CFFI declarations */ + +enum +{ + /** + * The EVMC ABI version number of the interface declared in this file. + * + * The EVMC ABI version always equals the major version number of the EVMC project. + * The Host SHOULD check if the ABI versions match when dynamically loading VMs. + * + * @see @ref versioning + */ + EVMC_ABI_VERSION = 11 +}; + + +/** + * The fixed size array of 32 bytes. + * + * 32 bytes of data capable of storing e.g. 256-bit hashes. + */ +typedef struct evmc_bytes32 +{ + /** The 32 bytes. */ + uint8_t bytes[32]; +} evmc_bytes32; + +/** + * The alias for evmc_bytes32 to represent a big-endian 256-bit integer. + */ +typedef struct evmc_bytes32 evmc_uint256be; + +/** Big-endian 160-bit hash suitable for keeping an Ethereum address. */ +typedef struct evmc_address +{ + /** The 20 bytes of the hash. */ + uint8_t bytes[20]; +} evmc_address; + +/** The kind of call-like instruction. */ +enum evmc_call_kind +{ + EVMC_CALL = 0, /**< Request CALL. */ + EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. Valid since Homestead. + The value param ignored. */ + EVMC_CALLCODE = 2, /**< Request CALLCODE. */ + EVMC_CREATE = 3, /**< Request CREATE. */ + EVMC_CREATE2 = 4 /**< Request CREATE2. Valid since Constantinople.*/ +}; + +/** The flags for ::evmc_message. */ +enum evmc_flags +{ + EVMC_STATIC = 1 /**< Static call mode. */ +}; + +/** + * The message describing an EVM call, including a zero-depth calls from a transaction origin. + * + * Most of the fields are modelled by the section 8. Message Call of the Ethereum Yellow Paper. + */ +struct evmc_message +{ + /** The kind of the call. For zero-depth calls ::EVMC_CALL SHOULD be used. */ + enum evmc_call_kind kind; + + /** + * Additional flags modifying the call execution behavior. + * In the current version the only valid values are ::EVMC_STATIC or 0. + */ + uint32_t flags; + + /** + * The present depth of the message call stack. + * + * Defined as `e` in the Yellow Paper. + */ + int32_t depth; + + /** + * The amount of gas available to the message execution. + * + * Defined as `g` in the Yellow Paper. + */ + int64_t gas; + + /** + * The recipient of the message. + * + * This is the address of the account which storage/balance/nonce is going to be modified + * by the message execution. In case of ::EVMC_CALL, this is also the account where the + * message value evmc_message::value is going to be transferred. + * For ::EVMC_CALLCODE or ::EVMC_DELEGATECALL, this may be different from + * the evmc_message::code_address. + * + * Defined as `r` in the Yellow Paper. + */ + evmc_address recipient; + + /** + * The sender of the message. + * + * The address of the sender of a message call defined as `s` in the Yellow Paper. + * This must be the message recipient of the message at the previous (lower) depth, + * except for the ::EVMC_DELEGATECALL where recipient is the 2 levels above the present depth. + * At the depth 0 this must be the transaction origin. + */ + evmc_address sender; + + /** + * The message input data. + * + * The arbitrary length byte array of the input data of the call, + * defined as `d` in the Yellow Paper. + * This MAY be NULL. + */ + const uint8_t* input_data; + + /** + * The size of the message input data. + * + * If input_data is NULL this MUST be 0. + */ + size_t input_size; + + /** + * The amount of Ether transferred with the message. + * + * This is transferred value for ::EVMC_CALL or apparent value for ::EVMC_DELEGATECALL. + * Defined as `v` or `v~` in the Yellow Paper. + */ + evmc_uint256be value; + + /** + * The optional value used in new contract address construction. + * + * Needed only for a Host to calculate created address when kind is ::EVMC_CREATE2. + * Ignored in evmc_execute_fn(). + */ + evmc_bytes32 create2_salt; + + /** + * The address of the code to be executed. + * + * For ::EVMC_CALLCODE or ::EVMC_DELEGATECALL this may be different from + * the evmc_message::recipient. + * Not required when invoking evmc_execute_fn(), only when invoking evmc_call_fn(). + * Ignored if kind is ::EVMC_CREATE or ::EVMC_CREATE2. + * + * In case of ::EVMC_CAPABILITY_PRECOMPILES implementation, this fields should be inspected + * to identify the requested precompile. + * + * Defined as `c` in the Yellow Paper. + */ + evmc_address code_address; +}; + + +/** The transaction and block data for execution. */ +struct evmc_tx_context +{ + evmc_uint256be tx_gas_price; /**< The transaction gas price. */ + evmc_address tx_origin; /**< The transaction origin account. */ + evmc_address block_coinbase; /**< The miner of the block. */ + int64_t block_number; /**< The block number. */ + int64_t block_timestamp; /**< The block timestamp. */ + int64_t block_gas_limit; /**< The block gas limit. */ + evmc_uint256be block_prev_randao; /**< The block previous RANDAO (EIP-4399). */ + evmc_uint256be chain_id; /**< The blockchain's ChainID. */ + evmc_uint256be block_base_fee; /**< The block base fee per gas (EIP-1559, EIP-3198). */ + evmc_uint256be blob_base_fee; /**< The blob base fee (EIP-7516). */ + const evmc_bytes32* blob_hashes; /**< The array of blob hashes (EIP-4844). */ + size_t blob_hashes_count; /**< The number of blob hashes (EIP-4844). */ +}; + +/** + * @struct evmc_host_context + * The opaque data type representing the Host execution context. + * @see evmc_execute_fn(). + */ +struct evmc_host_context; + +/** + * Get transaction context callback function. + * + * This callback function is used by an EVM to retrieve the transaction and + * block context. + * + * @param context The pointer to the Host execution context. + * @return The transaction context. + */ +typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_host_context* context); + +/** + * Get block hash callback function. + * + * This callback function is used by a VM to query the hash of the header of the given block. + * If the information about the requested block is not available, then this is signalled by + * returning null bytes. + * + * @param context The pointer to the Host execution context. + * @param number The block number. + * @return The block hash or null bytes + * if the information about the block is not available. + */ +typedef evmc_bytes32 (*evmc_get_block_hash_fn)(struct evmc_host_context* context, int64_t number); + +/** + * The execution status code. + * + * Successful execution is represented by ::EVMC_SUCCESS having value 0. + * + * Positive values represent failures defined by VM specifications with generic + * ::EVMC_FAILURE code of value 1. + * + * Status codes with negative values represent VM internal errors + * not provided by EVM specifications. These errors MUST not be passed back + * to the caller. They MAY be handled by the Client in predefined manner + * (see e.g. ::EVMC_REJECTED), otherwise internal errors are not recoverable. + * The generic representant of errors is ::EVMC_INTERNAL_ERROR but + * an EVM implementation MAY return negative status codes that are not defined + * in the EVMC documentation. + * + * @note + * In case new status codes are needed, please create an issue or pull request + * in the EVMC repository (https://github.com/ethereum/evmc). + */ +enum evmc_status_code +{ + /** Execution finished with success. */ + EVMC_SUCCESS = 0, + + /** Generic execution failure. */ + EVMC_FAILURE = 1, + + /** + * Execution terminated with REVERT opcode. + * + * In this case the amount of gas left MAY be non-zero and additional output + * data MAY be provided in ::evmc_result. + */ + EVMC_REVERT = 2, + + /** The execution has run out of gas. */ + EVMC_OUT_OF_GAS = 3, + + /** + * The designated INVALID instruction has been hit during execution. + * + * The EIP-141 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-141.md) + * defines the instruction 0xfe as INVALID instruction to indicate execution + * abortion coming from high-level languages. This status code is reported + * in case this INVALID instruction has been encountered. + */ + EVMC_INVALID_INSTRUCTION = 4, + + /** An undefined instruction has been encountered. */ + EVMC_UNDEFINED_INSTRUCTION = 5, + + /** + * The execution has attempted to put more items on the EVM stack + * than the specified limit. + */ + EVMC_STACK_OVERFLOW = 6, + + /** Execution of an opcode has required more items on the EVM stack. */ + EVMC_STACK_UNDERFLOW = 7, + + /** Execution has violated the jump destination restrictions. */ + EVMC_BAD_JUMP_DESTINATION = 8, + + /** + * Tried to read outside memory bounds. + * + * An example is RETURNDATACOPY reading past the available buffer. + */ + EVMC_INVALID_MEMORY_ACCESS = 9, + + /** Call depth has exceeded the limit (if any) */ + EVMC_CALL_DEPTH_EXCEEDED = 10, + + /** Tried to execute an operation which is restricted in static mode. */ + EVMC_STATIC_MODE_VIOLATION = 11, + + /** + * A call to a precompiled or system contract has ended with a failure. + * + * An example: elliptic curve functions handed invalid EC points. + */ + EVMC_PRECOMPILE_FAILURE = 12, + + /** + * Contract validation has failed (e.g. due to EVM 1.5 jump validity, + * Casper's purity checker or ewasm contract rules). + */ + EVMC_CONTRACT_VALIDATION_FAILURE = 13, + + /** + * An argument to a state accessing method has a value outside of the + * accepted range of values. + */ + EVMC_ARGUMENT_OUT_OF_RANGE = 14, + + /** + * A WebAssembly `unreachable` instruction has been hit during execution. + */ + EVMC_WASM_UNREACHABLE_INSTRUCTION = 15, + + /** + * A WebAssembly trap has been hit during execution. This can be for many + * reasons, including division by zero, validation errors, etc. + */ + EVMC_WASM_TRAP = 16, + + /** The caller does not have enough funds for value transfer. */ + EVMC_INSUFFICIENT_BALANCE = 17, + + /** EVM implementation generic internal error. */ + EVMC_INTERNAL_ERROR = -1, + + /** + * The execution of the given code and/or message has been rejected + * by the EVM implementation. + * + * This error SHOULD be used to signal that the EVM is not able to or + * willing to execute the given code type or message. + * If an EVM returns the ::EVMC_REJECTED status code, + * the Client MAY try to execute it in other EVM implementation. + * For example, the Client tries running a code in the EVM 1.5. If the + * code is not supported there, the execution falls back to the EVM 1.0. + */ + EVMC_REJECTED = -2, + + /** The VM failed to allocate the amount of memory needed for execution. */ + EVMC_OUT_OF_MEMORY = -3 +}; + +/* Forward declaration. */ +struct evmc_result; + +/** + * Releases resources assigned to an execution result. + * + * This function releases memory (and other resources, if any) assigned to the + * specified execution result making the result object invalid. + * + * @param result The execution result which resources are to be released. The + * result itself it not modified by this function, but becomes + * invalid and user MUST discard it as well. + * This MUST NOT be NULL. + * + * @note + * The result is passed by pointer to avoid (shallow) copy of the ::evmc_result + * struct. Think of this as the best possible C language approximation to + * passing objects by reference. + */ +typedef void (*evmc_release_result_fn)(const struct evmc_result* result); + +/** The EVM code execution result. */ +struct evmc_result +{ + /** The execution status code. */ + enum evmc_status_code status_code; + + /** + * The amount of gas left after the execution. + * + * If evmc_result::status_code is neither ::EVMC_SUCCESS nor ::EVMC_REVERT + * the value MUST be 0. + */ + int64_t gas_left; + + /** + * The refunded gas accumulated from this execution and its sub-calls. + * + * The transaction gas refund limit is not applied. + * If evmc_result::status_code is other than ::EVMC_SUCCESS the value MUST be 0. + */ + int64_t gas_refund; + + /** + * The reference to output data. + * + * The output contains data coming from RETURN opcode (iff evmc_result::code + * field is ::EVMC_SUCCESS) or from REVERT opcode. + * + * The memory containing the output data is owned by EVM and has to be + * freed with evmc_result::release(). + * + * This pointer MAY be NULL. + * If evmc_result::output_size is 0 this pointer MUST NOT be dereferenced. + */ + const uint8_t* output_data; + + /** + * The size of the output data. + * + * If evmc_result::output_data is NULL this MUST be 0. + */ + size_t output_size; + + /** + * The method releasing all resources associated with the result object. + * + * This method (function pointer) is optional (MAY be NULL) and MAY be set + * by the VM implementation. If set it MUST be called by the user once to + * release memory and other resources associated with the result object. + * Once the resources are released the result object MUST NOT be used again. + * + * The suggested code pattern for releasing execution results: + * @code + * struct evmc_result result = ...; + * if (result.release) + * result.release(&result); + * @endcode + * + * @note + * It works similarly to C++ virtual destructor. Attaching the release + * function to the result itself allows VM composition. + */ + evmc_release_result_fn release; + + /** + * The address of the possibly created contract. + * + * The create address may be provided even though the contract creation has failed + * (evmc_result::status_code is not ::EVMC_SUCCESS). This is useful in situations + * when the address is observable, e.g. access to it remains warm. + * In all other cases the address MUST be null bytes. + */ + evmc_address create_address; + + /** + * Reserved data that MAY be used by a evmc_result object creator. + * + * This reserved 4 bytes together with 20 bytes from create_address form + * 24 bytes of memory called "optional data" within evmc_result struct + * to be optionally used by the evmc_result object creator. + * + * @see evmc_result_optional_data, evmc_get_optional_data(). + * + * Also extends the size of the evmc_result to 64 bytes (full cache line). + */ + uint8_t padding[4]; +}; + + +/** + * Check account existence callback function. + * + * This callback function is used by the VM to check if + * there exists an account at given address. + * @param context The pointer to the Host execution context. + * @param address The address of the account the query is about. + * @return true if exists, false otherwise. + */ +typedef bool (*evmc_account_exists_fn)(struct evmc_host_context* context, + const evmc_address* address); + +/** + * Get storage callback function. + * + * This callback function is used by a VM to query the given account storage entry. + * + * @param context The Host execution context. + * @param address The address of the account. + * @param key The index of the account's storage entry. + * @return The storage value at the given storage key or null bytes + * if the account does not exist. + */ +typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key); + +/** + * Get transient storage callback function. + * + * This callback function is used by a VM to query + * the given account transient storage (EIP-1153) entry. + * + * @param context The Host execution context. + * @param address The address of the account. + * @param key The index of the account's transient storage entry. + * @return The transient storage value at the given storage key or null bytes + * if the account does not exist. + */ +typedef evmc_bytes32 (*evmc_get_transient_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key); + + +/** + * The effect of an attempt to modify a contract storage item. + * + * See @ref storagestatus for additional information about design of this enum + * and analysis of the specification. + * + * For the purpose of explaining the meaning of each element, the following + * notation is used: + * - 0 is zero value, + * - X != 0 (X is any value other than 0), + * - Y != 0, Y != X, (Y is any value other than X and 0), + * - Z != 0, Z != X, Z != X (Z is any value other than Y and X and 0), + * - the "o -> c -> v" triple describes the change status in the context of: + * - o: original value (cold value before a transaction started), + * - c: current storage value, + * - v: new storage value to be set. + * + * The order of elements follows EIPs introducing net storage gas costs: + * - EIP-2200: https://eips.ethereum.org/EIPS/eip-2200, + * - EIP-1283: https://eips.ethereum.org/EIPS/eip-1283. + */ +enum evmc_storage_status +{ + /** + * The new/same value is assigned to the storage item without affecting the cost structure. + * + * The storage value item is either: + * - left unchanged (c == v) or + * - the dirty value (o != c) is modified again (c != v). + * This is the group of cases related to minimal gas cost of only accessing warm storage. + * 0|X -> 0 -> 0 (current value unchanged) + * 0|X|Y -> Y -> Y (current value unchanged) + * 0|X -> Y -> Z (modified previously added/modified value) + * + * This is "catch all remaining" status. I.e. if all other statuses are correctly matched + * this status should be assigned to all remaining cases. + */ + EVMC_STORAGE_ASSIGNED = 0, + + /** + * A new storage item is added by changing + * the current clean zero to a nonzero value. + * 0 -> 0 -> Z + */ + EVMC_STORAGE_ADDED = 1, + + /** + * A storage item is deleted by changing + * the current clean nonzero to the zero value. + * X -> X -> 0 + */ + EVMC_STORAGE_DELETED = 2, + + /** + * A storage item is modified by changing + * the current clean nonzero to other nonzero value. + * X -> X -> Z + */ + EVMC_STORAGE_MODIFIED = 3, + + /** + * A storage item is added by changing + * the current dirty zero to a nonzero value other than the original value. + * X -> 0 -> Z + */ + EVMC_STORAGE_DELETED_ADDED = 4, + + /** + * A storage item is deleted by changing + * the current dirty nonzero to the zero value and the original value is not zero. + * X -> Y -> 0 + */ + EVMC_STORAGE_MODIFIED_DELETED = 5, + + /** + * A storage item is added by changing + * the current dirty zero to the original value. + * X -> 0 -> X + */ + EVMC_STORAGE_DELETED_RESTORED = 6, + + /** + * A storage item is deleted by changing + * the current dirty nonzero to the original zero value. + * 0 -> Y -> 0 + */ + EVMC_STORAGE_ADDED_DELETED = 7, + + /** + * A storage item is modified by changing + * the current dirty nonzero to the original nonzero value other than the current value. + * X -> Y -> X + */ + EVMC_STORAGE_MODIFIED_RESTORED = 8 +}; + + +/** + * Set storage callback function. + * + * This callback function is used by a VM to update the given account storage entry. + * The VM MUST make sure that the account exists. This requirement is only a formality because + * VM implementations only modify storage of the account of the current execution context + * (i.e. referenced by evmc_message::recipient). + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @param key The index of the storage entry. + * @param value The value to be stored. + * @return The effect on the storage item. + */ +typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key, + const evmc_bytes32* value); + +/** + * Set transient storage callback function. + * + * This callback function is used by a VM to update + * the given account's transient storage (EIP-1153) entry. + * The VM MUST make sure that the account exists. This requirement is only a formality because + * VM implementations only modify storage of the account of the current execution context + * (i.e. referenced by evmc_message::recipient). + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @param key The index of the transient storage entry. + * @param value The value to be stored. + */ +typedef void (*evmc_set_transient_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key, + const evmc_bytes32* value); + +/** + * Get balance callback function. + * + * This callback function is used by a VM to query the balance of the given account. + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @return The balance of the given account or 0 if the account does not exist. + */ +typedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_host_context* context, + const evmc_address* address); + +/** + * Get code size callback function. + * + * This callback function is used by a VM to get the size of the code stored + * in the account at the given address. + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @return The size of the code in the account or 0 if the account does not exist. + */ +typedef size_t (*evmc_get_code_size_fn)(struct evmc_host_context* context, + const evmc_address* address); + +/** + * Get code hash callback function. + * + * This callback function is used by a VM to get the keccak256 hash of the code stored + * in the account at the given address. For existing accounts not having a code, this + * function returns keccak256 hash of empty data. + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @return The hash of the code in the account or null bytes if the account does not exist. + */ +typedef evmc_bytes32 (*evmc_get_code_hash_fn)(struct evmc_host_context* context, + const evmc_address* address); + +/** + * Copy code callback function. + * + * This callback function is used by an EVM to request a copy of the code + * of the given account to the memory buffer provided by the EVM. + * The Client MUST copy the requested code, starting with the given offset, + * to the provided memory buffer up to the size of the buffer or the size of + * the code, whichever is smaller. + * + * @param context The pointer to the Host execution context. See ::evmc_host_context. + * @param address The address of the account. + * @param code_offset The offset of the code to copy. + * @param buffer_data The pointer to the memory buffer allocated by the EVM + * to store a copy of the requested code. + * @param buffer_size The size of the memory buffer. + * @return The number of bytes copied to the buffer by the Client. + */ +typedef size_t (*evmc_copy_code_fn)(struct evmc_host_context* context, + const evmc_address* address, + size_t code_offset, + uint8_t* buffer_data, + size_t buffer_size); + +/** + * Selfdestruct callback function. + * + * This callback function is used by an EVM to SELFDESTRUCT given contract. + * The execution of the contract will not be stopped, that is up to the EVM. + * + * @param context The pointer to the Host execution context. See ::evmc_host_context. + * @param address The address of the contract to be selfdestructed. + * @param beneficiary The address where the remaining ETH is going to be transferred. + * @return The information if the given address has not been registered as + * selfdestructed yet. True if registered for the first time, false otherwise. + */ +typedef bool (*evmc_selfdestruct_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_address* beneficiary); + +/** + * Log callback function. + * + * This callback function is used by an EVM to inform about a LOG that happened + * during an EVM bytecode execution. + * + * @param context The pointer to the Host execution context. See ::evmc_host_context. + * @param address The address of the contract that generated the log. + * @param data The pointer to unindexed data attached to the log. + * @param data_size The length of the data. + * @param topics The pointer to the array of topics attached to the log. + * @param topics_count The number of the topics. Valid values are between 0 and 4 inclusively. + */ +typedef void (*evmc_emit_log_fn)(struct evmc_host_context* context, + const evmc_address* address, + const uint8_t* data, + size_t data_size, + const evmc_bytes32 topics[], + size_t topics_count); + +/** + * Access status per EIP-2929: Gas cost increases for state access opcodes. + */ +enum evmc_access_status +{ + /** + * The entry hasn't been accessed before – it's the first access. + */ + EVMC_ACCESS_COLD = 0, + + /** + * The entry is already in accessed_addresses or accessed_storage_keys. + */ + EVMC_ACCESS_WARM = 1 +}; + +/** + * Access account callback function. + * + * This callback function is used by a VM to add the given address + * to accessed_addresses substate (EIP-2929). + * + * @param context The Host execution context. + * @param address The address of the account. + * @return EVMC_ACCESS_WARM if accessed_addresses already contained the address + * or EVMC_ACCESS_COLD otherwise. + */ +typedef enum evmc_access_status (*evmc_access_account_fn)(struct evmc_host_context* context, + const evmc_address* address); + +/** + * Access storage callback function. + * + * This callback function is used by a VM to add the given account storage entry + * to accessed_storage_keys substate (EIP-2929). + * + * @param context The Host execution context. + * @param address The address of the account. + * @param key The index of the account's storage entry. + * @return EVMC_ACCESS_WARM if accessed_storage_keys already contained the key + * or EVMC_ACCESS_COLD otherwise. + */ +typedef enum evmc_access_status (*evmc_access_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key); + +/** + * Pointer to the callback function supporting EVM calls. + * + * @param context The pointer to the Host execution context. + * @param msg The call parameters. + * @return The result of the call. + */ +typedef struct evmc_result (*evmc_call_fn)(struct evmc_host_context* context, + const struct evmc_message* msg); + +/** + * The Host interface. + * + * The set of all callback functions expected by VM instances. This is C + * realisation of vtable for OOP interface (only virtual methods, no data). + * Host implementations SHOULD create constant singletons of this (similarly + * to vtables) to lower the maintenance and memory management cost. + */ +struct evmc_host_interface +{ + /** Check account existence callback function. */ + evmc_account_exists_fn account_exists; + + /** Get storage callback function. */ + evmc_get_storage_fn get_storage; + + /** Set storage callback function. */ + evmc_set_storage_fn set_storage; + + /** Get balance callback function. */ + evmc_get_balance_fn get_balance; + + /** Get code size callback function. */ + evmc_get_code_size_fn get_code_size; + + /** Get code hash callback function. */ + evmc_get_code_hash_fn get_code_hash; + + /** Copy code callback function. */ + evmc_copy_code_fn copy_code; + + /** Selfdestruct callback function. */ + evmc_selfdestruct_fn selfdestruct; + + /** Call callback function. */ + evmc_call_fn call; + + /** Get transaction context callback function. */ + evmc_get_tx_context_fn get_tx_context; + + /** Get block hash callback function. */ + evmc_get_block_hash_fn get_block_hash; + + /** Emit log callback function. */ + evmc_emit_log_fn emit_log; + + /** Access account callback function. */ + evmc_access_account_fn access_account; + + /** Access storage callback function. */ + evmc_access_storage_fn access_storage; + + /** Get transient storage callback function. */ + evmc_get_transient_storage_fn get_transient_storage; + + /** Set transient storage callback function. */ + evmc_set_transient_storage_fn set_transient_storage; +}; + + +/* Forward declaration. */ +struct evmc_vm; + +/** + * Destroys the VM instance. + * + * @param vm The VM instance to be destroyed. + */ +typedef void (*evmc_destroy_fn)(struct evmc_vm* vm); + +/** + * Possible outcomes of evmc_set_option. + */ +enum evmc_set_option_result +{ + EVMC_SET_OPTION_SUCCESS = 0, + EVMC_SET_OPTION_INVALID_NAME = 1, + EVMC_SET_OPTION_INVALID_VALUE = 2 +}; + +/** + * Configures the VM instance. + * + * Allows modifying options of the VM instance. + * Options: + * - code cache behavior: on, off, read-only, ... + * - optimizations, + * + * @param vm The VM instance to be configured. + * @param name The option name. NULL-terminated string. Cannot be NULL. + * @param value The new option value. NULL-terminated string. Cannot be NULL. + * @return The outcome of the operation. + */ +typedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_vm* vm, + char const* name, + char const* value); + + +/** + * EVM revision. + * + * The revision of the EVM specification based on the Ethereum + * upgrade / hard fork codenames. + */ +enum evmc_revision +{ + /** + * The Frontier revision. + * + * The one Ethereum launched with. + */ + EVMC_FRONTIER = 0, + + /** + * The Homestead revision. + * + * https://eips.ethereum.org/EIPS/eip-606 + */ + EVMC_HOMESTEAD = 1, + + /** + * The Tangerine Whistle revision. + * + * https://eips.ethereum.org/EIPS/eip-608 + */ + EVMC_TANGERINE_WHISTLE = 2, + + /** + * The Spurious Dragon revision. + * + * https://eips.ethereum.org/EIPS/eip-607 + */ + EVMC_SPURIOUS_DRAGON = 3, + + /** + * The Byzantium revision. + * + * https://eips.ethereum.org/EIPS/eip-609 + */ + EVMC_BYZANTIUM = 4, + + /** + * The Constantinople revision. + * + * https://eips.ethereum.org/EIPS/eip-1013 + */ + EVMC_CONSTANTINOPLE = 5, + + /** + * The Petersburg revision. + * + * Other names: Constantinople2, ConstantinopleFix. + * + * https://eips.ethereum.org/EIPS/eip-1716 + */ + EVMC_PETERSBURG = 6, + + /** + * The Istanbul revision. + * + * https://eips.ethereum.org/EIPS/eip-1679 + */ + EVMC_ISTANBUL = 7, + + /** + * The Berlin revision. + * + * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md + */ + EVMC_BERLIN = 8, + + /** + * The London revision. + * + * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md + */ + EVMC_LONDON = 9, + + /** + * The Paris revision (aka The Merge). + * + * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md + */ + EVMC_PARIS = 10, + + /** + * The Shanghai revision. + * + * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md + */ + EVMC_SHANGHAI = 11, + + /** + * The Cancun revision. + * + * The future next revision after Shanghai. + * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md + */ + EVMC_CANCUN = 12, + + /** + * The Prague revision. + * + * The future next revision after Cancun. + */ + EVMC_PRAGUE = 13, + + /** The maximum EVM revision supported. */ + EVMC_MAX_REVISION = EVMC_PRAGUE, + + /** + * The latest known EVM revision with finalized specification. + * + * This is handy for EVM tools to always use the latest revision available. + */ + EVMC_LATEST_STABLE_REVISION = EVMC_SHANGHAI +}; + + +/** + * Executes the given code using the input from the message. + * + * This function MAY be invoked multiple times for a single VM instance. + * + * @param vm The VM instance. This argument MUST NOT be NULL. + * @param host The Host interface. This argument MUST NOT be NULL unless + * the @p vm has the ::EVMC_CAPABILITY_PRECOMPILES capability. + * @param context The opaque pointer to the Host execution context. + * This argument MAY be NULL. The VM MUST pass the same + * pointer to the methods of the @p host interface. + * The VM MUST NOT dereference the pointer. + * @param rev The requested EVM specification revision. + * @param msg The call parameters. See ::evmc_message. This argument MUST NOT be NULL. + * @param code The reference to the code to be executed. This argument MAY be NULL. + * @param code_size The length of the code. If @p code is NULL this argument MUST be 0. + * @return The execution result. + */ +typedef struct evmc_result (*evmc_execute_fn)(struct evmc_vm* vm, + const struct evmc_host_interface* host, + struct evmc_host_context* context, + enum evmc_revision rev, + const struct evmc_message* msg, + uint8_t const* code, + size_t code_size); + +/** + * Possible capabilities of a VM. + */ +enum evmc_capabilities +{ + /** + * The VM is capable of executing EVM1 bytecode. + */ + EVMC_CAPABILITY_EVM1 = (1u << 0), + + /** + * The VM is capable of executing ewasm bytecode. + */ + EVMC_CAPABILITY_EWASM = (1u << 1), + + /** + * The VM is capable of executing the precompiled contracts + * defined for the range of code addresses. + * + * The EIP-1352 (https://eips.ethereum.org/EIPS/eip-1352) specifies + * the range 0x000...0000 - 0x000...ffff of addresses + * reserved for precompiled and system contracts. + * + * This capability is **experimental** and MAY be removed without notice. + */ + EVMC_CAPABILITY_PRECOMPILES = (1u << 2) +}; + +/** + * Alias for unsigned integer representing a set of bit flags of EVMC capabilities. + * + * @see evmc_capabilities + */ +typedef uint32_t evmc_capabilities_flagset; + +/** + * Return the supported capabilities of the VM instance. + * + * This function MAY be invoked multiple times for a single VM instance, + * and its value MAY be influenced by calls to evmc_vm::set_option. + * + * @param vm The VM instance. + * @return The supported capabilities of the VM. @see evmc_capabilities. + */ +typedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_vm* vm); + + +/** + * The VM instance. + * + * Defines the base struct of the VM implementation. + */ +struct evmc_vm +{ + /** + * EVMC ABI version implemented by the VM instance. + * + * Can be used to detect ABI incompatibilities. + * The EVMC ABI version represented by this file is in ::EVMC_ABI_VERSION. + */ + const int abi_version; + + /** + * The name of the EVMC VM implementation. + * + * It MUST be a NULL-terminated not empty string. + * The content MUST be UTF-8 encoded (this implies ASCII encoding is also allowed). + */ + const char* name; + + /** + * The version of the EVMC VM implementation, e.g. "1.2.3b4". + * + * It MUST be a NULL-terminated not empty string. + * The content MUST be UTF-8 encoded (this implies ASCII encoding is also allowed). + */ + const char* version; + + /** + * Pointer to function destroying the VM instance. + * + * This is a mandatory method and MUST NOT be set to NULL. + */ + evmc_destroy_fn destroy; + + /** + * Pointer to function executing a code by the VM instance. + * + * This is a mandatory method and MUST NOT be set to NULL. + */ + evmc_execute_fn execute; + + /** + * A method returning capabilities supported by the VM instance. + * + * The value returned MAY change when different options are set via the set_option() method. + * + * A Client SHOULD only rely on the value returned if it has queried it after + * it has called the set_option(). + * + * This is a mandatory method and MUST NOT be set to NULL. + */ + evmc_get_capabilities_fn get_capabilities; + + /** + * Optional pointer to function modifying VM's options. + * + * If the VM does not support this feature the pointer can be NULL. + */ + evmc_set_option_fn set_option; +}; + +/* END Python CFFI declarations */ + +#ifdef EVMC_DOCUMENTATION +/** + * Example of a function creating an instance of an example EVM implementation. + * + * Each EVM implementation MUST provide a function returning an EVM instance. + * The function SHOULD be named `evmc_create_(void)`. If the VM name contains hyphens + * replaces them with underscores in the function names. + * + * @par Binaries naming convention + * For VMs distributed as shared libraries, the name of the library SHOULD match the VM name. + * The convetional library filename prefixes and extensions SHOULD be ignored by the Client. + * For example, the shared library with the "beta-interpreter" implementation may be named + * `libbeta-interpreter.so`. + * + * @return The VM instance or NULL indicating instance creation failure. + */ +struct evmc_vm* evmc_create_example_vm(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // EVM_ASSIGNER_EVMC_EVMC_H_ +/** @} */ diff --git a/lib/assigner/evmc/evmc.hpp b/lib/assigner/evmc/evmc.hpp new file mode 100644 index 00000000..f5e46871 --- /dev/null +++ b/lib/assigner/evmc/evmc.hpp @@ -0,0 +1,964 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2018 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. +#ifndef EVM_ASSIGNER_EVMC_EVMC_HPP_ +#define EVM_ASSIGNER_EVMC_EVMC_HPP_ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static_assert(EVMC_LATEST_STABLE_REVISION <= EVMC_MAX_REVISION, + "latest stable revision ill-defined"); + +/// EVMC C++ API - wrappers and bindings for C++ +/// @ingroup cpp +namespace evmc +{ +/// String view of uint8_t chars. +using bytes_view = std::basic_string_view; + +/// The big-endian 160-bit hash suitable for keeping an Ethereum address. +/// +/// This type wraps C ::evmc_address to make sure objects of this type are always initialized. +struct address : evmc_address +{ + /// Default and converting constructor. + /// + /// Initializes bytes to zeros if not other @p init value provided. + constexpr address(evmc_address init = {}) noexcept : evmc_address{init} {} + + /// Converting constructor from unsigned integer value. + /// + /// This constructor assigns the @p v value to the last 8 bytes [12:19] + /// in big-endian order. + constexpr explicit address(uint64_t v) noexcept + : evmc_address{{0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + static_cast(v >> 56), + static_cast(v >> 48), + static_cast(v >> 40), + static_cast(v >> 32), + static_cast(v >> 24), + static_cast(v >> 16), + static_cast(v >> 8), + static_cast(v >> 0)}} + {} + + /// Explicit operator converting to bool. + inline constexpr explicit operator bool() const noexcept; + + /// Implicit operator converting to bytes_view. + inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; } +}; + +/// The fixed size array of 32 bytes for storing 256-bit EVM values. +/// +/// This type wraps C ::evmc_bytes32 to make sure objects of this type are always initialized. +struct bytes32 : evmc_bytes32 +{ + /// Default and converting constructor. + /// + /// Initializes bytes to zeros if not other @p init value provided. + constexpr bytes32(evmc_bytes32 init = {}) noexcept : evmc_bytes32{init} {} + + /// Converting constructor from unsigned integer value. + /// + /// This constructor assigns the @p v value to the last 8 bytes [24:31] + /// in big-endian order. + constexpr explicit bytes32(uint64_t v) noexcept + : evmc_bytes32{{0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + static_cast(v >> 56), + static_cast(v >> 48), + static_cast(v >> 40), + static_cast(v >> 32), + static_cast(v >> 24), + static_cast(v >> 16), + static_cast(v >> 8), + static_cast(v >> 0)}} + {} + + /// Explicit operator converting to bool. + inline constexpr explicit operator bool() const noexcept; + + /// Implicit operator converting to bytes_view. + inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; } +}; + +/// The alias for evmc::bytes32 to represent a big-endian 256-bit integer. +using uint256be = bytes32; + + +/// Loads 64 bits / 8 bytes of data from the given @p data array in big-endian order. +inline constexpr uint64_t load64be(const uint8_t* data) noexcept +{ + return (uint64_t{data[0]} << 56) | (uint64_t{data[1]} << 48) | (uint64_t{data[2]} << 40) | + (uint64_t{data[3]} << 32) | (uint64_t{data[4]} << 24) | (uint64_t{data[5]} << 16) | + (uint64_t{data[6]} << 8) | uint64_t{data[7]}; +} + +/// Loads 64 bits / 8 bytes of data from the given @p data array in little-endian order. +inline constexpr uint64_t load64le(const uint8_t* data) noexcept +{ + return uint64_t{data[0]} | (uint64_t{data[1]} << 8) | (uint64_t{data[2]} << 16) | + (uint64_t{data[3]} << 24) | (uint64_t{data[4]} << 32) | (uint64_t{data[5]} << 40) | + (uint64_t{data[6]} << 48) | (uint64_t{data[7]} << 56); +} + +/// Loads 32 bits / 4 bytes of data from the given @p data array in big-endian order. +inline constexpr uint32_t load32be(const uint8_t* data) noexcept +{ + return (uint32_t{data[0]} << 24) | (uint32_t{data[1]} << 16) | (uint32_t{data[2]} << 8) | + uint32_t{data[3]}; +} + +/// Loads 32 bits / 4 bytes of data from the given @p data array in little-endian order. +inline constexpr uint32_t load32le(const uint8_t* data) noexcept +{ + return uint32_t{data[0]} | (uint32_t{data[1]} << 8) | (uint32_t{data[2]} << 16) | + (uint32_t{data[3]} << 24); +} + +namespace fnv +{ +constexpr auto prime = 0x100000001b3; ///< The 64-bit FNV prime number. +constexpr auto offset_basis = 0xcbf29ce484222325; ///< The 64-bit FNV offset basis. + +/// The hashing transformation for 64-bit inputs based on the FNV-1a formula. +inline constexpr uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept +{ + return (h ^ x) * prime; +} +} // namespace fnv + + +/// The "equal to" comparison operator for the evmc::address type. +inline constexpr bool operator==(const address& a, const address& b) noexcept +{ + return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) && + load64le(&a.bytes[8]) == load64le(&b.bytes[8]) && + load32le(&a.bytes[16]) == load32le(&b.bytes[16]); +} + +/// The "not equal to" comparison operator for the evmc::address type. +inline constexpr bool operator!=(const address& a, const address& b) noexcept +{ + return !(a == b); +} + +/// The "less than" comparison operator for the evmc::address type. +inline constexpr bool operator<(const address& a, const address& b) noexcept +{ + return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) || + (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) && + (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) || + (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) && + load32be(&a.bytes[16]) < load32be(&b.bytes[16])))); +} + +/// The "greater than" comparison operator for the evmc::address type. +inline constexpr bool operator>(const address& a, const address& b) noexcept +{ + return b < a; +} + +/// The "less than or equal to" comparison operator for the evmc::address type. +inline constexpr bool operator<=(const address& a, const address& b) noexcept +{ + return !(b < a); +} + +/// The "greater than or equal to" comparison operator for the evmc::address type. +inline constexpr bool operator>=(const address& a, const address& b) noexcept +{ + return !(a < b); +} + +/// The "equal to" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator==(const bytes32& a, const bytes32& b) noexcept +{ + return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) && + load64le(&a.bytes[8]) == load64le(&b.bytes[8]) && + load64le(&a.bytes[16]) == load64le(&b.bytes[16]) && + load64le(&a.bytes[24]) == load64le(&b.bytes[24]); +} + +/// The "not equal to" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator!=(const bytes32& a, const bytes32& b) noexcept +{ + return !(a == b); +} + +/// The "less than" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept +{ + return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) || + (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) && + (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) || + (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) && + (load64be(&a.bytes[16]) < load64be(&b.bytes[16]) || + (load64be(&a.bytes[16]) == load64be(&b.bytes[16]) && + load64be(&a.bytes[24]) < load64be(&b.bytes[24])))))); +} + +/// The "greater than" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator>(const bytes32& a, const bytes32& b) noexcept +{ + return b < a; +} + +/// The "less than or equal to" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator<=(const bytes32& a, const bytes32& b) noexcept +{ + return !(b < a); +} + +/// The "greater than or equal to" comparison operator for the evmc::bytes32 type. +inline constexpr bool operator>=(const bytes32& a, const bytes32& b) noexcept +{ + return !(a < b); +} + +/// Checks if the given address is the zero address. +inline constexpr bool is_zero(const address& a) noexcept +{ + return a == address{}; +} + +inline constexpr address::operator bool() const noexcept +{ + return !is_zero(*this); +} + +/// Checks if the given bytes32 object has all zero bytes. +inline constexpr bool is_zero(const bytes32& a) noexcept +{ + return a == bytes32{}; +} + +inline constexpr bytes32::operator bool() const noexcept +{ + return !is_zero(*this); +} + +namespace literals +{ +/// Converts a raw literal into value of type T. +/// +/// This function is expected to be used on literals in constexpr context only. +/// In case the input is invalid the std::terminate() is called. +/// TODO(c++20): Use consteval. +template +constexpr T parse(std::string_view s) noexcept +{ + return from_hex(s).value(); +} + +/// Literal for evmc::address. +constexpr address operator""_address(const char* s) noexcept +{ + return parse
(s); +} + +/// Literal for evmc::bytes32. +constexpr bytes32 operator""_bytes32(const char* s) noexcept +{ + return parse(s); +} +} // namespace literals + +using namespace literals; + + +/// @copydoc evmc_status_code_to_string +inline const char* to_string(evmc_status_code status_code) noexcept +{ + return evmc_status_code_to_string(status_code); +} + +/// @copydoc evmc_revision_to_string +inline const char* to_string(evmc_revision rev) noexcept +{ + return evmc_revision_to_string(rev); +} + + +/// Alias for evmc_make_result(). +constexpr auto make_result = evmc_make_result; + +/// @copydoc evmc_result +/// +/// This is a RAII wrapper for evmc_result and objects of this type +/// automatically release attached resources. +class Result : private evmc_result +{ +public: + using evmc_result::create_address; + using evmc_result::gas_left; + using evmc_result::gas_refund; + using evmc_result::output_data; + using evmc_result::output_size; + using evmc_result::status_code; + + /// Creates the result from the provided arguments. + /// + /// The provided output is copied to memory allocated with malloc() + /// and the evmc_result::release function is set to one invoking free(). + /// + /// @param _status_code The status code. + /// @param _gas_left The amount of gas left. + /// @param _gas_refund The amount of refunded gas. + /// @param _output_data The pointer to the output. + /// @param _output_size The output size. + explicit Result(evmc_status_code _status_code, + int64_t _gas_left, + int64_t _gas_refund, + const uint8_t* _output_data, + size_t _output_size) noexcept + : evmc_result{make_result(_status_code, _gas_left, _gas_refund, _output_data, _output_size)} + {} + + /// Creates the result without output. + /// + /// @param _status_code The status code. + /// @param _gas_left The amount of gas left. + /// @param _gas_refund The amount of refunded gas. + explicit Result(evmc_status_code _status_code = EVMC_INTERNAL_ERROR, + int64_t _gas_left = 0, + int64_t _gas_refund = 0) noexcept + : evmc_result{make_result(_status_code, _gas_left, _gas_refund, nullptr, 0)} + {} + + /// Creates the result of contract creation. + /// + /// @param _status_code The status code. + /// @param _gas_left The amount of gas left. + /// @param _gas_refund The amount of refunded gas. + /// @param _create_address The address of the possibly created account. + explicit Result(evmc_status_code _status_code, + int64_t _gas_left, + int64_t _gas_refund, + const evmc_address& _create_address) noexcept + : evmc_result{make_result(_status_code, _gas_left, _gas_refund, nullptr, 0)} + { + create_address = _create_address; + } + + /// Converting constructor from raw evmc_result. + /// + /// This object takes ownership of the resources of @p res. + explicit Result(const evmc_result& res) noexcept : evmc_result{res} {} + + /// Destructor responsible for automatically releasing attached resources. + ~Result() noexcept + { + if (release != nullptr) + release(this); + } + + /// Move constructor. + Result(Result&& other) noexcept : evmc_result{other} + { + other.release = nullptr; // Disable releasing of the rvalue object. + } + + /// Move assignment operator. + /// + /// The self-assignment MUST never happen. + /// + /// @param other The other result object. + /// @return The reference to the left-hand side object. + Result& operator=(Result&& other) noexcept + { + this->~Result(); // Release this object. + static_cast(*this) = other; // Copy data. + other.release = nullptr; // Disable releasing of the rvalue object. + return *this; + } + + /// Access the result object as a referenced to ::evmc_result. + evmc_result& raw() noexcept { return *this; } + + /// Access the result object as a const referenced to ::evmc_result. + const evmc_result& raw() const noexcept { return *this; } + + /// Releases the ownership and returns the raw copy of evmc_result. + /// + /// This method drops the ownership of the result + /// (result's resources are not going to be released when this object is destructed). + /// It is the caller's responsibility having the returned copy of the result to release it. + /// This object MUST NOT be used after this method is invoked. + /// + /// @return The copy of this object converted to raw evmc_result. + evmc_result release_raw() noexcept + { + const auto out = evmc_result{*this}; // Copy data. + this->release = nullptr; // Disable releasing of this object. + return out; + } +}; + + +/// The EVMC Host interface +class HostInterface +{ +public: + virtual ~HostInterface() noexcept = default; + + /// @copydoc evmc_host_interface::account_exists + virtual bool account_exists(const address& addr) const noexcept = 0; + + /// @copydoc evmc_host_interface::get_storage + virtual bytes32 get_storage(const address& addr, const bytes32& key) noexcept = 0; + + /// @copydoc evmc_host_interface::set_storage + virtual evmc_storage_status set_storage(const address& addr, + const bytes32& key, + const bytes32& value) noexcept = 0; + + /// @copydoc evmc_host_interface::get_balance + virtual uint256be get_balance(const address& addr) noexcept = 0; + + /// @copydoc evmc_host_interface::get_code_size + virtual size_t get_code_size(const address& addr) noexcept = 0; + + /// @copydoc evmc_host_interface::get_code_hash + virtual bytes32 get_code_hash(const address& addr) noexcept = 0; + + /// @copydoc evmc_host_interface::copy_code + virtual size_t copy_code(const address& addr, + size_t code_offset, + uint8_t* buffer_data, + size_t buffer_size) noexcept = 0; + + /// @copydoc evmc_host_interface::selfdestruct + virtual bool selfdestruct(const address& addr, const address& beneficiary) noexcept = 0; + + /// @copydoc evmc_host_interface::call + virtual Result call(const evmc_message& msg) noexcept = 0; + + /// @copydoc evmc_host_interface::get_tx_context + virtual evmc_tx_context get_tx_context() const noexcept = 0; + + /// @copydoc evmc_host_interface::get_block_hash + virtual bytes32 get_block_hash(int64_t block_number) const noexcept = 0; + + /// @copydoc evmc_host_interface::emit_log + virtual void emit_log(const address& addr, + const uint8_t* data, + size_t data_size, + const bytes32 topics[], + size_t num_topics) noexcept = 0; + + /// @copydoc evmc_host_interface::access_account + virtual evmc_access_status access_account(const address& addr) noexcept = 0; + + /// @copydoc evmc_host_interface::access_storage + virtual evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept = 0; + + /// @copydoc evmc_host_interface::get_transient_storage + virtual bytes32 get_transient_storage(const address& addr, + const bytes32& key) noexcept = 0; + + /// @copydoc evmc_host_interface::set_transient_storage + virtual void set_transient_storage(const address& addr, + const bytes32& key, + const bytes32& value) noexcept = 0; +}; + + +/// Wrapper around EVMC host context / host interface. +/// +/// To be used by VM implementations as better alternative to using ::evmc_host_context directly. +class HostContext : public HostInterface +{ + const evmc_host_interface* host = nullptr; + evmc_host_context* context = nullptr; + +public: + /// Default constructor for null Host context. + HostContext() = default; + + /// Constructor from the EVMC Host primitives. + /// @param interface The reference to the Host interface. + /// @param ctx The pointer to the Host context object. This parameter MAY be null. + HostContext(const evmc_host_interface& interface, evmc_host_context* ctx) noexcept + : host{&interface}, context{ctx} + {} + + bool account_exists(const address& address) const noexcept final + { + return host->account_exists(context, &address); + } + + bytes32 get_storage(const address& address, const bytes32& key) noexcept final + { + return host->get_storage(context, &address, &key); + } + + evmc_storage_status set_storage(const address& address, + const bytes32& key, + const bytes32& value) noexcept final + { + return host->set_storage(context, &address, &key, &value); + } + + uint256be get_balance(const address& address) noexcept final + { + return host->get_balance(context, &address); + } + + size_t get_code_size(const address& address) noexcept final + { + return host->get_code_size(context, &address); + } + + bytes32 get_code_hash(const address& address) noexcept final + { + return host->get_code_hash(context, &address); + } + + size_t copy_code(const address& address, + size_t code_offset, + uint8_t* buffer_data, + size_t buffer_size) noexcept final + { + return host->copy_code(context, &address, code_offset, buffer_data, buffer_size); + } + + bool selfdestruct(const address& addr, const address& beneficiary) noexcept final + { + return host->selfdestruct(context, &addr, &beneficiary); + } + + Result call(const evmc_message& message) noexcept final + { + return Result{host->call(context, &message)}; + } + + /// @copydoc HostInterface::get_tx_context() + evmc_tx_context get_tx_context() const noexcept final { return host->get_tx_context(context); } + + bytes32 get_block_hash(int64_t number) const noexcept final + { + return host->get_block_hash(context, number); + } + + void emit_log(const address& addr, + const uint8_t* data, + size_t data_size, + const bytes32 topics[], + size_t topics_count) noexcept final + { + host->emit_log(context, &addr, data, data_size, topics, topics_count); + } + + evmc_access_status access_account(const address& address) noexcept final + { + return host->access_account(context, &address); + } + + evmc_access_status access_storage(const address& address, const bytes32& key) noexcept final + { + return host->access_storage(context, &address, &key); + } + + bytes32 get_transient_storage(const address& address, const bytes32& key) noexcept final + { + return host->get_transient_storage(context, &address, &key); + } + + void set_transient_storage(const address& address, + const bytes32& key, + const bytes32& value) noexcept final + { + host->set_transient_storage(context, &address, &key, &value); + } +}; + + +/// Abstract class to be used by Host implementations. +/// +/// When implementing EVMC Host, you can directly inherit from the evmc::Host class. +/// This way your implementation will be simpler by avoiding manual handling +/// of the ::evmc_host_context and the ::evmc_host_interface. +class Host : public HostInterface +{ +public: + /// Provides access to the global host interface. + /// @returns Reference to the host interface object. + static const evmc_host_interface& get_interface() noexcept; + + /// Converts the Host object to the opaque host context pointer. + /// @returns Pointer to evmc_host_context. + evmc_host_context* to_context() noexcept { return reinterpret_cast(this); } + + /// Converts the opaque host context pointer back to the original Host object. + /// @tparam DerivedClass The class derived from the Host class. + /// @param context The opaque host context pointer. + /// @returns The pointer to DerivedClass. + template + static DerivedClass* from_context(evmc_host_context* context) noexcept + { + // Get pointer of the Host base class. + auto* h = reinterpret_cast(context); + + // Additional downcast, only possible if DerivedClass inherits from Host. + return static_cast(h); + } +}; + + +/// @copybrief evmc_vm +/// +/// This is a RAII wrapper for evmc_vm, and object of this type +/// automatically destroys the VM instance. +class VM +{ +public: + VM() noexcept = default; + + /// Converting constructor from evmc_vm. + explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {} + + /// Destructor responsible for automatically destroying the VM instance. + ~VM() noexcept + { + if (m_instance != nullptr) + m_instance->destroy(m_instance); + } + + VM(const VM&) = delete; + VM& operator=(const VM&) = delete; + + /// Move constructor. + VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; } + + /// Move assignment operator. + VM& operator=(VM&& other) noexcept + { + this->~VM(); + m_instance = other.m_instance; + other.m_instance = nullptr; + return *this; + } + + /// The constructor that captures a VM instance and configures the instance + /// with the provided list of options. + inline VM(evmc_vm* vm, + std::initializer_list> options) noexcept; + + /// Checks if contains a valid pointer to the VM instance. + explicit operator bool() const noexcept { return m_instance != nullptr; } + + /// Checks whenever the VM instance is ABI compatible with the current EVMC API. + bool is_abi_compatible() const noexcept { return m_instance->abi_version == EVMC_ABI_VERSION; } + + /// @copydoc evmc_vm::name + char const* name() const noexcept { return m_instance->name; } + + /// @copydoc evmc_vm::version + char const* version() const noexcept { return m_instance->version; } + + /// Checks if the VM has the given capability. + bool has_capability(evmc_capabilities capability) const noexcept + { + return (get_capabilities() & static_cast(capability)) != 0; + } + + /// @copydoc evmc_vm::get_capabilities + evmc_capabilities_flagset get_capabilities() const noexcept + { + return m_instance->get_capabilities(m_instance); + } + + /// @copydoc evmc_set_option() + evmc_set_option_result set_option(const char name[], const char value[]) noexcept + { + return evmc_set_option(m_instance, name, value); + } + + /// @copydoc evmc_execute() + Result execute(const evmc_host_interface& host, + evmc_host_context* ctx, + evmc_revision rev, + const evmc_message& msg, + const uint8_t* code, + size_t code_size) noexcept + { + return Result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)}; + } + + /// Convenient variant of the VM::execute() that takes reference to evmc::Host class. + Result execute(Host& host, + evmc_revision rev, + const evmc_message& msg, + const uint8_t* code, + size_t code_size) noexcept + { + return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size); + } + + /// Executes code without the Host context. + /// + /// The same as + /// execute(const evmc_host_interface&, evmc_host_context*, evmc_revision, + /// const evmc_message&, const uint8_t*, size_t), + /// but without providing the Host context and interface. + /// This method is for experimental precompiles support where execution is + /// guaranteed not to require any Host access. + Result execute(evmc_revision rev, + const evmc_message& msg, + const uint8_t* code, + size_t code_size) noexcept + { + return Result{ + m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)}; + } + + /// Returns the pointer to C EVMC struct representing the VM. + /// + /// Gives access to the C EVMC VM struct to allow advanced interaction with the VM not supported + /// by the C++ interface. Use as the last resort. + /// This object still owns the VM after returning the pointer. The returned pointer MAY be null. + evmc_vm* get_raw_pointer() const noexcept { return m_instance; } + +private: + evmc_vm* m_instance = nullptr; +}; + +inline VM::VM(evmc_vm* vm, + std::initializer_list> options) noexcept + : m_instance{vm} +{ + // This constructor is implemented outside of the class definition to workaround a doxygen bug. + for (const auto& option : options) + set_option(option.first, option.second); +} + + +namespace internal +{ +inline bool account_exists(evmc_host_context* h, const evmc_address* addr) noexcept +{ + return Host::from_context(h)->account_exists(*addr); +} + +inline evmc_bytes32 get_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key) noexcept +{ + return Host::from_context(h)->get_storage(*addr, *key); +} + +inline evmc_storage_status set_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key, + const evmc_bytes32* value) noexcept +{ + return Host::from_context(h)->set_storage(*addr, *key, *value); +} + +inline evmc_uint256be get_balance(evmc_host_context* h, const evmc_address* addr) noexcept +{ + return Host::from_context(h)->get_balance(*addr); +} + +inline size_t get_code_size(evmc_host_context* h, const evmc_address* addr) noexcept +{ + return Host::from_context(h)->get_code_size(*addr); +} + +inline evmc_bytes32 get_code_hash(evmc_host_context* h, const evmc_address* addr) noexcept +{ + return Host::from_context(h)->get_code_hash(*addr); +} + +inline size_t copy_code(evmc_host_context* h, + const evmc_address* addr, + size_t code_offset, + uint8_t* buffer_data, + size_t buffer_size) noexcept +{ + return Host::from_context(h)->copy_code(*addr, code_offset, buffer_data, buffer_size); +} + +inline bool selfdestruct(evmc_host_context* h, + const evmc_address* addr, + const evmc_address* beneficiary) noexcept +{ + return Host::from_context(h)->selfdestruct(*addr, *beneficiary); +} + +inline evmc_result call(evmc_host_context* h, const evmc_message* msg) noexcept +{ + return Host::from_context(h)->call(*msg).release_raw(); +} + +inline evmc_tx_context get_tx_context(evmc_host_context* h) noexcept +{ + return Host::from_context(h)->get_tx_context(); +} + +inline evmc_bytes32 get_block_hash(evmc_host_context* h, int64_t block_number) noexcept +{ + return Host::from_context(h)->get_block_hash(block_number); +} + +inline void emit_log(evmc_host_context* h, + const evmc_address* addr, + const uint8_t* data, + size_t data_size, + const evmc_bytes32 topics[], + size_t num_topics) noexcept +{ + Host::from_context(h)->emit_log(*addr, data, data_size, static_cast(topics), + num_topics); +} + +inline evmc_access_status access_account(evmc_host_context* h, const evmc_address* addr) noexcept +{ + return Host::from_context(h)->access_account(*addr); +} + +inline evmc_access_status access_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key) noexcept +{ + return Host::from_context(h)->access_storage(*addr, *key); +} + +inline evmc_bytes32 get_transient_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key) noexcept +{ + return Host::from_context(h)->get_transient_storage(*addr, *key); +} + +inline void set_transient_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key, + const evmc_bytes32* value) noexcept +{ + Host::from_context(h)->set_transient_storage(*addr, *key, *value); +} +} // namespace internal + +inline const evmc_host_interface& Host::get_interface() noexcept +{ + static constexpr evmc_host_interface interface = { + ::evmc::internal::account_exists, + ::evmc::internal::get_storage, + ::evmc::internal::set_storage, + ::evmc::internal::get_balance, + ::evmc::internal::get_code_size, + ::evmc::internal::get_code_hash, + ::evmc::internal::copy_code, + ::evmc::internal::selfdestruct, + ::evmc::internal::call, + ::evmc::internal::get_tx_context, + ::evmc::internal::get_block_hash, + ::evmc::internal::emit_log, + ::evmc::internal::access_account, + ::evmc::internal::access_storage, + ::evmc::internal::get_transient_storage, + ::evmc::internal::set_transient_storage, + }; + return interface; +} +} // namespace evmc + + +/// "Stream out" operator implementation for ::evmc_status_code. +/// +/// @note This is defined in global namespace to match ::evmc_status_code definition and allow +/// convenient operator overloading usage. +inline std::ostream& operator<<(std::ostream& os, evmc_status_code status_code) +{ + return os << evmc::to_string(status_code); +} + +/// "Stream out" operator implementation for ::evmc_revision. +/// +/// @note This is defined in global namespace to match ::evmc_revision definition and allow +/// convenient operator overloading usage. +inline std::ostream& operator<<(std::ostream& os, evmc_revision rev) +{ + return os << evmc::to_string(rev); +} + +namespace std +{ +/// Hash operator template specialization for evmc::address. Needed for unordered containers. +template <> +struct hash +{ + /// Hash operator using FNV1a-based folding. + constexpr size_t operator()(const evmc::address& s) const noexcept + { + using namespace evmc; + using namespace fnv; + return static_cast(fnv1a_by64( + fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])), load64le(&s.bytes[8])), + load32le(&s.bytes[16]))); + } +}; + +/// Hash operator template specialization for evmc::bytes32. Needed for unordered containers. +template <> +struct hash +{ + /// Hash operator using FNV1a-based folding. + constexpr size_t operator()(const evmc::bytes32& s) const noexcept + { + using namespace evmc; + using namespace fnv; + return static_cast( + fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])), + load64le(&s.bytes[8])), + load64le(&s.bytes[16])), + load64le(&s.bytes[24]))); + } +}; +} // namespace std + +#endif // EVM_ASSIGNER_EVMC_EVMC_HPP_ diff --git a/lib/assigner/evmc/filter_iterator.hpp b/lib/assigner/evmc/filter_iterator.hpp new file mode 100644 index 00000000..0a349fc9 --- /dev/null +++ b/lib/assigner/evmc/filter_iterator.hpp @@ -0,0 +1,105 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2022 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. +#pragma once + +#include + +namespace evmc +{ +/// The constexpr variant of std::isspace(). +inline constexpr bool isspace(char ch) noexcept +{ + // Implementation taken from LLVM's libc. + return ch == ' ' || (static_cast(ch) - '\t') < 5; +} + +/// Checks if a character is not a white space. +inline constexpr bool is_not_space(char ch) noexcept +{ + return !isspace(ch); +} + +/// The filter iterator adaptor creates a view of an iterator range in which some elements of the +/// range are skipped. A predicate function controls which elements are skipped. When the predicate +/// is applied to an element, if it returns true then the element is retained and if it returns +/// false then the element is skipped over. When skipping over elements, it is necessary for the +/// filter adaptor to know when to stop so as to avoid going past the end of the underlying range. +/// A filter iterator is therefore constructed with pair of iterators indicating the range of +/// elements in the unfiltered sequence to be traversed. +/// +/// Similar to boost::filter_iterator. +template ::value_type) noexcept> +struct filter_iterator +{ + /// The iterator difference type. + using difference_type = typename std::iterator_traits::difference_type; + + /// The iterator value type. + using value_type = typename std::iterator_traits::value_type; + + /// The iterator pointer type. + using pointer = typename std::iterator_traits::pointer; + + /// The iterator reference type. + using reference = typename std::iterator_traits::reference; + + /// The iterator category. + using iterator_category = std::input_iterator_tag; + +private: + BaseIterator base; + BaseIterator base_end; + value_type value; + + constexpr void forward_to_next_value() noexcept + { + for (; base != base_end; ++base) + { + value = *base; + if (predicate(value)) + break; + } + } + +public: + /// The constructor of the base iterator pair. + constexpr filter_iterator(BaseIterator it, BaseIterator end) noexcept : base{it}, base_end{end} + { + forward_to_next_value(); + } + + /// The dereference operator. + constexpr auto operator*() noexcept + { + // We should not read from an input base iterator twice. So the only read is in + // forward_to_next_value() and here we return the cached value. + return value; + } + + /// The increment operator. + constexpr void operator++() noexcept + { + ++base; + forward_to_next_value(); + } + + /// The equality operator. + constexpr bool operator==(const filter_iterator& o) const noexcept { return base == o.base; } + + /// The inequality operator. + constexpr bool operator!=(const filter_iterator& o) const noexcept { return base != o.base; } +}; + +/// The input filter iterator which skips whitespace characters from the base input iterator. +template +struct skip_space_iterator : filter_iterator +{ + using filter_iterator::filter_iterator; +}; + +/// Class template argument deduction guide. +template +skip_space_iterator(BaseIterator, BaseIterator) -> skip_space_iterator; +} // namespace evmc diff --git a/lib/assigner/evmc/helpers.h b/lib/assigner/evmc/helpers.h new file mode 100644 index 00000000..f00f5d89 --- /dev/null +++ b/lib/assigner/evmc/helpers.h @@ -0,0 +1,318 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2018 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. + +/** + * EVMC Helpers + * + * A collection of C helper functions for invoking a VM instance methods. + * These are convenient for languages where invoking function pointers + * is "ugly" or impossible (such as Go). + * + * @defgroup helpers EVMC Helpers + * @{ + */ +#ifndef EVM_ASSIGNER_EVMC_HELPERS_H_ +#define EVM_ASSIGNER_EVMC_HELPERS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#endif +#endif + +/** + * Returns true if the VM has a compatible ABI version. + */ +static inline bool evmc_is_abi_compatible(struct evmc_vm* vm) +{ + return vm->abi_version == EVMC_ABI_VERSION; +} + +/** + * Returns the name of the VM. + */ +static inline const char* evmc_vm_name(struct evmc_vm* vm) +{ + return vm->name; +} + +/** + * Returns the version of the VM. + */ +static inline const char* evmc_vm_version(struct evmc_vm* vm) +{ + return vm->version; +} + +/** + * Checks if the VM has the given capability. + * + * @see evmc_get_capabilities_fn + */ +static inline bool evmc_vm_has_capability(struct evmc_vm* vm, enum evmc_capabilities capability) +{ + return (vm->get_capabilities(vm) & (evmc_capabilities_flagset)capability) != 0; +} + +/** + * Destroys the VM instance. + * + * @see evmc_destroy_fn + */ +static inline void evmc_destroy(struct evmc_vm* vm) +{ + vm->destroy(vm); +} + +/** + * Sets the option for the VM, if the feature is supported by the VM. + * + * @see evmc_set_option_fn + */ +static inline enum evmc_set_option_result evmc_set_option(struct evmc_vm* vm, + char const* name, + char const* value) +{ + if (vm->set_option) + return vm->set_option(vm, name, value); + return EVMC_SET_OPTION_INVALID_NAME; +} + +/** + * Executes code in the VM instance. + * + * @see evmc_execute_fn. + */ +static inline struct evmc_result evmc_execute(struct evmc_vm* vm, + const struct evmc_host_interface* host, + struct evmc_host_context* context, + enum evmc_revision rev, + const struct evmc_message* msg, + uint8_t const* code, + size_t code_size) +{ + return vm->execute(vm, host, context, rev, msg, code, code_size); +} + +/// The evmc_result release function using free() for releasing the memory. +/// +/// This function is used in the evmc_make_result(), +/// but may be also used in other case if convenient. +/// +/// @param result The result object. +static void evmc_free_result_memory(const struct evmc_result* result) +{ + free((uint8_t*)result->output_data); +} + +/// Creates the result from the provided arguments. +/// +/// The provided output is copied to memory allocated with malloc() +/// and the evmc_result::release function is set to one invoking free(). +/// +/// In case of memory allocation failure, the result has all fields zeroed +/// and only evmc_result::status_code is set to ::EVMC_OUT_OF_MEMORY internal error. +/// +/// @param status_code The status code. +/// @param gas_left The amount of gas left. +/// @param gas_refund The amount of refunded gas. +/// @param output_data The pointer to the output. +/// @param output_size The output size. +static inline struct evmc_result evmc_make_result(enum evmc_status_code status_code, + int64_t gas_left, + int64_t gas_refund, + const uint8_t* output_data, + size_t output_size) +{ + struct evmc_result result; + memset(&result, 0, sizeof(result)); + + if (output_size != 0) + { + uint8_t* buffer = (uint8_t*)malloc(output_size); + + if (!buffer) + { + result.status_code = EVMC_OUT_OF_MEMORY; + return result; + } + + memcpy(buffer, output_data, output_size); + result.output_data = buffer; + result.output_size = output_size; + result.release = evmc_free_result_memory; + } + + result.status_code = status_code; + result.gas_left = gas_left; + result.gas_refund = gas_refund; + return result; +} + +/** + * Releases the resources allocated to the execution result. + * + * @param result The result object to be released. MUST NOT be NULL. + * + * @see evmc_result::release() evmc_release_result_fn + */ +static inline void evmc_release_result(struct evmc_result* result) +{ + if (result->release) + result->release(result); +} + + +/** + * Helpers for optional storage of evmc_result. + * + * In some contexts (i.e. evmc_result::create_address is unused) objects of + * type evmc_result contains a memory storage that MAY be used by the object + * owner. This group defines helper types and functions for accessing + * the optional storage. + * + * @defgroup result_optional_storage Result Optional Storage + * @{ + */ + +/** + * The union representing evmc_result "optional storage". + * + * The evmc_result struct contains 24 bytes of optional storage that can be + * reused by the object creator if the object does not contain + * evmc_result::create_address. + * + * A VM implementation MAY use this memory to keep additional data + * when returning result from evmc_execute_fn(). + * The host application MAY use this memory to keep additional data + * when returning result of performed calls from evmc_call_fn(). + * + * @see evmc_get_optional_storage(), evmc_get_const_optional_storage(). + */ +union evmc_result_optional_storage +{ + uint8_t bytes[24]; /**< 24 bytes of optional storage. */ + void* pointer; /**< Optional pointer. */ +}; + +/** Provides read-write access to evmc_result "optional storage". */ +static inline union evmc_result_optional_storage* evmc_get_optional_storage( + struct evmc_result* result) +{ + return (union evmc_result_optional_storage*)&result->create_address; +} + +/** Provides read-only access to evmc_result "optional storage". */ +static inline const union evmc_result_optional_storage* evmc_get_const_optional_storage( + const struct evmc_result* result) +{ + return (const union evmc_result_optional_storage*)&result->create_address; +} + +/** @} */ + +/** Returns text representation of the ::evmc_status_code. */ +static inline const char* evmc_status_code_to_string(enum evmc_status_code status_code) +{ + switch (status_code) + { + case EVMC_SUCCESS: + return "success"; + case EVMC_FAILURE: + return "failure"; + case EVMC_REVERT: + return "revert"; + case EVMC_OUT_OF_GAS: + return "out of gas"; + case EVMC_INVALID_INSTRUCTION: + return "invalid instruction"; + case EVMC_UNDEFINED_INSTRUCTION: + return "undefined instruction"; + case EVMC_STACK_OVERFLOW: + return "stack overflow"; + case EVMC_STACK_UNDERFLOW: + return "stack underflow"; + case EVMC_BAD_JUMP_DESTINATION: + return "bad jump destination"; + case EVMC_INVALID_MEMORY_ACCESS: + return "invalid memory access"; + case EVMC_CALL_DEPTH_EXCEEDED: + return "call depth exceeded"; + case EVMC_STATIC_MODE_VIOLATION: + return "static mode violation"; + case EVMC_PRECOMPILE_FAILURE: + return "precompile failure"; + case EVMC_CONTRACT_VALIDATION_FAILURE: + return "contract validation failure"; + case EVMC_ARGUMENT_OUT_OF_RANGE: + return "argument out of range"; + case EVMC_WASM_UNREACHABLE_INSTRUCTION: + return "wasm unreachable instruction"; + case EVMC_WASM_TRAP: + return "wasm trap"; + case EVMC_INSUFFICIENT_BALANCE: + return "insufficient balance"; + case EVMC_INTERNAL_ERROR: + return "internal error"; + case EVMC_REJECTED: + return "rejected"; + case EVMC_OUT_OF_MEMORY: + return "out of memory"; + } + return ""; +} + +/** Returns the name of the ::evmc_revision. */ +static inline const char* evmc_revision_to_string(enum evmc_revision rev) +{ + switch (rev) + { + case EVMC_FRONTIER: + return "Frontier"; + case EVMC_HOMESTEAD: + return "Homestead"; + case EVMC_TANGERINE_WHISTLE: + return "Tangerine Whistle"; + case EVMC_SPURIOUS_DRAGON: + return "Spurious Dragon"; + case EVMC_BYZANTIUM: + return "Byzantium"; + case EVMC_CONSTANTINOPLE: + return "Constantinople"; + case EVMC_PETERSBURG: + return "Petersburg"; + case EVMC_ISTANBUL: + return "Istanbul"; + case EVMC_BERLIN: + return "Berlin"; + case EVMC_LONDON: + return "London"; + case EVMC_PARIS: + return "Paris"; + case EVMC_SHANGHAI: + return "Shanghai"; + case EVMC_CANCUN: + return "Cancun"; + case EVMC_PRAGUE: + return "Prague"; + } + return ""; +} + +/** @} */ + +#ifdef __cplusplus +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +} // extern "C" +#endif + +#endif // EVM_ASSIGNER_EVMC_HELPERS_H_ diff --git a/lib/assigner/evmc/hex.hpp b/lib/assigner/evmc/hex.hpp new file mode 100644 index 00000000..9ad9a94c --- /dev/null +++ b/lib/assigner/evmc/hex.hpp @@ -0,0 +1,161 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2021 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. +#ifndef EVM_ASSIGNER_EVMC_HEX_HPP_ +#define EVM_ASSIGNER_EVMC_HEX_HPP_ + +#include +#include +#include +#include +#include + +namespace evmc +{ +/// String of uint8_t chars. +using bytes = std::basic_string; + +/// String view of uint8_t chars. +using bytes_view = std::basic_string_view; + + +/// Encode a byte to a hex string. +inline std::string hex(uint8_t b) noexcept +{ + static constexpr auto hex_digits = "0123456789abcdef"; + return {hex_digits[b >> 4], hex_digits[b & 0xf]}; +} + +/// Encodes bytes as hex string. +inline std::string hex(bytes_view bs) +{ + std::string str; + str.reserve(bs.size() * 2); + for (const auto b : bs) + str += hex(b); + return str; +} + +namespace internal +{ +/// Extracts the nibble value out of a hex digit. +/// Returns -1 in case of invalid hex digit. +inline constexpr int from_hex_digit(char h) noexcept +{ + if (h >= '0' && h <= '9') + return h - '0'; + else if (h >= 'a' && h <= 'f') + return h - 'a' + 10; + else if (h >= 'A' && h <= 'F') + return h - 'A' + 10; + else + return -1; +} +} // namespace internal + +/// Decodes hex-encoded sequence of characters. +/// +/// It is guaranteed that the output will not be longer than half of the input length. +/// +/// @param begin The input begin iterator. It only must satisfy input iterator concept. +/// @param end The input end iterator. It only must satisfy input iterator concept. +/// @param out The output iterator. It must satisfy output iterator concept. +/// @return True if successful, false if input is invalid hex. +template +inline constexpr bool from_hex(InputIt begin, InputIt end, OutputIt out) noexcept +{ + int hi_nibble = -1; // Init with invalid value, should never be used. + size_t i = 0; + for (auto it = begin; it != end; ++it, ++i) + { + const auto h = *it; + const int v = evmc::internal::from_hex_digit(h); + if (v < 0) + { + if (i == 1 && hi_nibble == 0 && h == 'x') // 0x prefix + continue; + return false; + } + + if (i % 2 == 0) + hi_nibble = v << 4; + else + *out++ = static_cast(hi_nibble | v); + } + + return i % 2 == 0; +} + +/// Validates hex encoded string. +/// +/// @return True if the input is valid hex. +inline bool validate_hex(std::string_view hex) noexcept +{ + struct noop_output_iterator + { + uint8_t sink = {}; + uint8_t& operator*() noexcept { return sink; } + noop_output_iterator operator++(int) noexcept { return *this; } // NOLINT(cert-dcl21-cpp) + }; + + return from_hex(hex.begin(), hex.end(), noop_output_iterator{}); +} + +/// Decodes hex encoded string to bytes. +/// +/// In case the input is invalid the returned value is std::nullopt. +/// This can happen if a non-hex digit or odd number of digits is encountered. +inline std::optional from_hex(std::string_view hex) +{ + bytes bs; + bs.reserve(hex.size() / 2); + if (!from_hex(hex.begin(), hex.end(), std::back_inserter(bs))) + return {}; + return bs; +} + +/// Decodes hex-encoded string into custom type T with .bytes array of uint8_t. +/// +/// When the input is smaller than the result type, the result is padded with zeros on the left +/// (the result bytes of lowest indices are filled with zeros). +/// TODO: Support optional left alignment. +template +constexpr std::optional from_hex(std::string_view s) noexcept +{ + // Omit the optional 0x prefix. + if (s.size() >= 2 && s[0] == '0' && s[1] == 'x') + s.remove_prefix(2); + + T r{}; // The T must have .bytes array. This may be lifted if std::bit_cast is available. + constexpr auto num_out_bytes = std::size(r.bytes); + const auto num_in_bytes = s.length() / 2; + if (num_in_bytes > num_out_bytes) + return {}; + if (!from_hex(s.begin(), s.end(), &r.bytes[num_out_bytes - num_in_bytes])) + return {}; + return r; +} + +/// Decodes hex encoded string to bytes. The whitespace in the input is ignored. +/// +/// In case the input is invalid the returned value is std::nullopt. +/// This can happen if a non-hex digit or odd number of digits is encountered. +/// The whitespace (as defined by std::isspace) in the input is ignored. +template +std::optional from_spaced_hex(InputIterator begin, InputIterator end) noexcept +{ + bytes bs; + if (!from_hex(skip_space_iterator{begin, end}, skip_space_iterator{end, end}, + std::back_inserter(bs))) + return {}; + return bs; +} + +/// @copydoc from_spaced_hex +inline std::optional from_spaced_hex(std::string_view hex) noexcept +{ + return from_spaced_hex(hex.begin(), hex.end()); +} +} // namespace evmc + +#endif // EVM_ASSIGNER_EVMC_HEX_HPP_ diff --git a/lib/assigner/evmc/utils.h b/lib/assigner/evmc/utils.h new file mode 100644 index 00000000..01c0cc0e --- /dev/null +++ b/lib/assigner/evmc/utils.h @@ -0,0 +1,37 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2018 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. + +#ifndef EVM_ASSIGNER_UTILS_HEX_H_ +#define EVM_ASSIGNER_UTILS_HEX_H_ + +/** + * @file + * A collection of helper macros to handle some non-portable features of C/C++ compilers. + * + * @addtogroup helpers + * @{ + */ + +/** + * @def EVMC_EXPORT + * Marks a function to be exported from a shared library. + */ +#if defined _MSC_VER || defined __MINGW32__ +#define EVMC_EXPORT __declspec(dllexport) +#else +#define EVMC_EXPORT __attribute__((visibility("default"))) +#endif + +/** + * @def EVMC_NOEXCEPT + * Safe way of marking a function with `noexcept` C++ specifier. + */ +#ifdef __cplusplus +#define EVMC_NOEXCEPT noexcept +#else +#define EVMC_NOEXCEPT +#endif + +#endif // EVM_ASSIGNER_UTILS_HEX_H_ +/** @} */ diff --git a/lib/assigner/evmone/baseline.hpp b/lib/assigner/evmone/baseline.hpp index 48458997..25f9760f 100644 --- a/lib/assigner/evmone/baseline.hpp +++ b/lib/assigner/evmone/baseline.hpp @@ -8,8 +8,8 @@ #include "execution_state.hpp" #include "instructions.hpp" -#include -#include +#include +#include #include #include #include diff --git a/lib/assigner/evmone/baseline_instruction_table.hpp b/lib/assigner/evmone/baseline_instruction_table.hpp index f163bd97..9154f620 100644 --- a/lib/assigner/evmone/baseline_instruction_table.hpp +++ b/lib/assigner/evmone/baseline_instruction_table.hpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once -#include +#include #include namespace evmone::baseline diff --git a/lib/assigner/evmone/eof.hpp b/lib/assigner/evmone/eof.hpp index 361cf76c..ca64e8ff 100644 --- a/lib/assigner/evmone/eof.hpp +++ b/lib/assigner/evmone/eof.hpp @@ -4,8 +4,8 @@ #pragma once #include -#include -#include +#include +#include "utils.h" #include #include #include diff --git a/lib/assigner/evmone/execution_state.hpp b/lib/assigner/evmone/execution_state.hpp index d612faec..4ba1f869 100644 --- a/lib/assigner/evmone/execution_state.hpp +++ b/lib/assigner/evmone/execution_state.hpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once -#include +#include #include #include diff --git a/lib/assigner/include/assigner.hpp b/lib/assigner/include/assigner.hpp index fb3a7f2a..d332894c 100644 --- a/lib/assigner/include/assigner.hpp +++ b/lib/assigner/include/assigner.hpp @@ -5,10 +5,10 @@ // LICENSE file in the root directory of this source tree. //---------------------------------------------------------------------------// -#ifndef EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ASSIGNER_HPP_ -#define EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ASSIGNER_HPP_ +#ifndef EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ASSIGNER_HPP_ +#define EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ASSIGNER_HPP_ -#include +#include #include #include @@ -112,4 +112,4 @@ namespace nil { } // namespace evm_assigner } // namespace nil -#endif // EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ASSIGNER_HPP_ +#endif // EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ASSIGNER_HPP_ diff --git a/lib/assigner/include/bytecode.hpp b/lib/assigner/include/bytecode.hpp index 500ce229..4f7477f6 100644 --- a/lib/assigner/include/bytecode.hpp +++ b/lib/assigner/include/bytecode.hpp @@ -5,8 +5,8 @@ // LICENSE file in the root directory of this source tree. //---------------------------------------------------------------------------// -#ifndef EVM1_ASSIGNER_INCLUDE_BYTECODE_HPP_ -#define EVM1_ASSIGNER_INCLUDE_BYTECODE_HPP_ +#ifndef EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_BYTECODE_HPP_ +#define EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_BYTECODE_HPP_ #include #include @@ -109,4 +109,4 @@ namespace nil { } // namespace evm_assigner } // namespace nil -#endif // EVM1_ASSIGNER_INCLUDE_BYTECODE_HPP_ +#endif // EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_BYTECODE_HPP_ diff --git a/lib/assigner/include/rw.hpp b/lib/assigner/include/rw.hpp index 09aa0d6f..04220c14 100644 --- a/lib/assigner/include/rw.hpp +++ b/lib/assigner/include/rw.hpp @@ -5,8 +5,8 @@ // LICENSE file in the root directory of this source tree. //---------------------------------------------------------------------------// -#ifndef EVM1_ASSIGNER_INCLUDE_RW_HPP_ -#define EVM1_ASSIGNER_INCLUDE_RW_HPP_ +#ifndef EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_RW_HPP_ +#define EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_RW_HPP_ #include #include @@ -287,4 +287,4 @@ namespace nil { } // namespace evm_assigner } // namespace nil -#endif // EVM1_ASSIGNER_INCLUDE_RW_HPP_ +#endif // EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_RW_HPP_ diff --git a/lib/assigner/include/vm_host.hpp b/lib/assigner/include/vm_host.hpp index ae17d301..2279eada 100644 --- a/lib/assigner/include/vm_host.hpp +++ b/lib/assigner/include/vm_host.hpp @@ -3,7 +3,7 @@ // Based on example host -#include +#include #include #include @@ -44,9 +44,6 @@ using accounts = std::map; template class VMHost : public evmc::Host { - evmc::accounts accounts; - evmc_tx_context tx_context{}; - public: VMHost() = default; explicit VMHost(evmc_tx_context& _tx_context, std::shared_ptr> _assigner, const std::string& _target_circuit = "") noexcept @@ -59,19 +56,21 @@ class VMHost : public evmc::Host bool account_exists(const evmc::address& addr) const noexcept final { - return accounts.find(addr) != accounts.end(); + auto account_iter = get_account(addr); + return account_iter != accounts.end(); } evmc::bytes32 get_storage(const evmc::address& addr, - const evmc::bytes32& key) const noexcept final + const evmc::bytes32& key) noexcept final { - const auto account_iter = accounts.find(addr); - if (account_iter == accounts.end()) + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { return {}; - + } const auto storage_iter = account_iter->second.storage.find(key); - if (storage_iter != account_iter->second.storage.end()) + if (storage_iter != account_iter->second.storage.end()) { return storage_iter->second; + } return {}; } @@ -79,47 +78,59 @@ class VMHost : public evmc::Host const evmc::bytes32& key, const evmc::bytes32& value) noexcept final { - auto& account = accounts[addr]; - auto prev_value = account.storage[key]; - account.storage[key] = value; + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { + return EVMC_STORAGE_DELETED; + } + + auto storage_iter = account_iter->second.storage.find(key); + if (storage_iter == account_iter->second.storage.end()) { + return EVMC_STORAGE_DELETED; + } + auto prev_value = storage_iter->second; + storage_iter->second = value; return (prev_value == value) ? EVMC_STORAGE_ASSIGNED : EVMC_STORAGE_MODIFIED; } - evmc::uint256be get_balance(const evmc::address& addr) const noexcept final + evmc::uint256be get_balance(const evmc::address& addr) noexcept final { - auto it = accounts.find(addr); - if (it != accounts.end()) - return it->second.balance; - return {}; + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { + return {}; + } + return account_iter->second.balance; } - size_t get_code_size(const evmc::address& addr) const noexcept final + size_t get_code_size(const evmc::address& addr) noexcept final { - auto it = accounts.find(addr); - if (it != accounts.end()) - return it->second.code.size(); - return 0; + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { + return 0; + } + return account_iter->second.code.size(); } - evmc::bytes32 get_code_hash(const evmc::address& addr) const noexcept final + evmc::bytes32 get_code_hash(const evmc::address& addr) noexcept final { - auto it = accounts.find(addr); - if (it != accounts.end()) - return it->second.code_hash(); - return {}; + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { + return {}; + } + return account_iter->second.code_hash(); } size_t copy_code(const evmc::address& addr, size_t code_offset, uint8_t* buffer_data, - size_t buffer_size) const noexcept final + size_t buffer_size) noexcept final { - const auto it = accounts.find(addr); - if (it == accounts.end()) + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { return 0; + } - const auto& code = it->second.code; + const auto& code = account_iter->second.code; if (code_offset >= code.size()) return 0; @@ -195,11 +206,12 @@ class VMHost : public evmc::Host } evmc::bytes32 get_transient_storage(const evmc::address& addr, - const evmc::bytes32& key) const noexcept override + const evmc::bytes32& key) noexcept override { - const auto account_iter = accounts.find(addr); - if (account_iter == accounts.end()) + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { return {}; + } const auto transient_storage_iter = account_iter->second.transient_storage.find(key); if (transient_storage_iter != account_iter->second.transient_storage.end()) @@ -211,22 +223,33 @@ class VMHost : public evmc::Host const evmc::bytes32& key, const evmc::bytes32& value) noexcept override { - accounts[addr].transient_storage[key] = value; + auto account_iter = get_account(addr); + if (account_iter == accounts.end()) { + return; + } + account_iter->second.transient_storage[key] = value; } +protected: + evmc::accounts accounts; + + virtual evmc::accounts::iterator get_account(const evmc::address& addr) noexcept { + return accounts.find(addr); + } private: + evmc_tx_context tx_context{}; std::shared_ptr> assigner; std::string target_circuit; evmc::Result handle_call(const evmc_message& msg) { - auto sender_iter = accounts.find(msg.sender); + auto sender_iter = get_account(msg.sender); if (sender_iter == accounts.end()) { // Sender account does not exist return evmc::Result{EVMC_INTERNAL_ERROR}; } auto &sender_acc = sender_iter->second; - auto account_iter = accounts.find(msg.code_address); + auto account_iter = get_account(msg.code_address); if (account_iter == accounts.end()) { // Create account @@ -252,7 +275,7 @@ class VMHost : public evmc::Host evmc::Result handle_create(const evmc_message& msg) { evmc::address new_contract_address = calculate_address(msg); - if (accounts.find(new_contract_address) != accounts.end()) + if (get_account(new_contract_address) != accounts.end()) { // Address collision return evmc::Result{EVMC_FAILURE}; diff --git a/lib/assigner/include/zkevm_word.hpp b/lib/assigner/include/zkevm_word.hpp index c8fc0d7a..5fd0884f 100644 --- a/lib/assigner/include/zkevm_word.hpp +++ b/lib/assigner/include/zkevm_word.hpp @@ -5,10 +5,10 @@ // LICENSE file in the root directory of this source tree. //---------------------------------------------------------------------------// -#ifndef EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ZKEVM_WORD_HPP_ -#define EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ZKEVM_WORD_HPP_ +#ifndef EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ZKEVM_WORD_HPP_ +#define EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ZKEVM_WORD_HPP_ -#include +#include #include #include @@ -277,4 +277,4 @@ namespace nil { } } // namespace evm_assigner } // namespace nil -#endif // EVM1_ASSIGNER_INCLUDE_NIL_BLUEPRINT_ZKEVM_WORD_HPP_ +#endif // EVM_ASSIGNER_LIB_ASSIGNER_INCLUDE_ZKEVM_WORD_HPP_ diff --git a/lib/assigner/test/CMakeLists.txt b/lib/assigner/test/CMakeLists.txt index f6bb7a4c..dcf5ac7e 100644 --- a/lib/assigner/test/CMakeLists.txt +++ b/lib/assigner/test/CMakeLists.txt @@ -5,6 +5,8 @@ find_package(GTest CONFIG REQUIRED) add_executable(assigner_tests assigner_test.cpp) +target_include_directories(assigner_tests PRIVATE + $) target_link_libraries( assigner_tests PRIVATE diff --git a/lib/assigner/test/assigner_test.cpp b/lib/assigner/test/assigner_test.cpp index d0d3e0e2..1ec14d49 100644 --- a/lib/assigner/test/assigner_test.cpp +++ b/lib/assigner/test/assigner_test.cpp @@ -3,8 +3,7 @@ #include #include -#include -#include +#include #include #include diff --git a/nix/evmc.nix b/nix/evmc.nix deleted file mode 100644 index 8e60439a..00000000 --- a/nix/evmc.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ repo, pkgs, stdenv, enable_debug, ... }: -stdenv.mkDerivation { - name = "evmc"; - - src = repo; - - nativeBuildInputs = [ pkgs.cmake ]; - - cmakeFlags = [ - "-DEVMC_TOOLS=FALSE" - ]; - - doCheck = false; - dontStrip = enable_debug; -}