GithubHelp home page GithubHelp logo

ethereum / evmc Goto Github PK

View Code? Open in Web Editor NEW
318.0 34.0 288.0 2.8 MB

EVMC – Ethereum Client-VM Connector API

Home Page: https://evmc.ethereum.org

License: Apache License 2.0

C 46.87% CMake 8.97% C++ 30.11% Go 3.64% Rust 10.40%
ethereum evm ewasm wasm rust golang evmc c cpp java

evmc's Introduction

EVMC

chat: on gitter readme style: standard

Ethereum Client-VM Connector API

The EVMC is the low-level ABI between Ethereum Virtual Machines (EVMs) and Ethereum Clients. On the EVM side it supports classic EVM1 and ewasm. On the Client-side it defines the interface for EVM implementations to access Ethereum environment and state.

Usage

Documentation

Please visit the documentation.

Languages support

Language Supported Versions Supported Compilers Feature Support
C C99, C11 GCC 8+, clang 9+, MSVC 2017+ Host- and VM-side
C++ C++17 GCC 8+, clang 9+, MSVC 2017+ Host- and VM-side
Go (bindings) 1.11+ (with modules) Host-side only
Rust (bindings)¹ 2018 edition 1.47.0 and newer VM-side only
Java (bindings)² 11 Host-side only
  1. Rust support is limited and not complete yet, but it is mostly functional already. Breaking changes are possible at this stage.
  2. Java support is in progress and the interface remains in flux. Breaking changes are possible at this stage.

Testing tools

  • evmc run (tools/evmc) — executes bytecode in any EVMC-compatible VM implementation.
  • evmc-vmtester (tools/vmtester) — can test any EVM implementation for compatibility with EVMC.
  • evm-test (evmone → test/unittests) — allows running the collection of evmone's unit tests on any EVMC-compatible EVM implementation.
  • evmone-fuzzer (evmone → test/fuzzer) — differential fuzzer for EVMC-compatible EVM implementations.

Related projects

EVMs

Clients

Maintainers

See also the list of EVMC Authors.

Contributing

chat: on gitter

Talk with us on the EVMC Gitter chat.

License

license badge

Licensed under the Apache License, Version 2.0.

Internal

Making new release

  1. Update CHANGELOG.md, put the release date, update release link.
  2. git add CHANGELOG.md.
  3. Tag new release: bumpversion --allow-dirty prerel.
  4. Prepare CHANGELOG for next release: add unreleased section and link.
  5. git add CHANGELOG.md.
  6. Start new release series: bumpversion --allow-dirty --no-tag minor.

evmc's People

Contributors

atoulme avatar axic avatar chfast avatar gumb0 avatar herbertjordan avatar iamyulong avatar jakelang avatar jrhea avatar kjx98 avatar mandrigin avatar pirapira avatar rex4539 avatar vorot93 avatar vvviiimmm avatar yperbasis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

evmc's Issues

Reorder status codes

I would go with:

SUCCESS = 0

REVERT = 1
FAILURE = 2  // Generic failure

(specific failure codes)

INTERNAL_ERROR = -1  // Generic non-recoverable error
REJECTED = -2

EVMC_EXPORT for GNUC<4 and Mingw?

utils.h defines EVMC_EXPORT as:

#ifdef _MSC_VER
#define EVMC_EXPORT __declspec(dllexport)
#else
#define EVMC_EXPORT __attribute__((visibility("default")))
#endif

but Hera does the following:

#if defined _MSC_VER || defined __MINGW32__
# define HERA_EXPORT __declspec(dllexport)
# define HERA_IMPORT __declspec(dllimport)
#elif __GNU__ >= 4
# define HERA_EXPORT __attribute__((visibility("default")))
# define HERA_IMPORT __attribute__((visibility("default")))
#else
# define HERA_EXPORT
# define HERA_IMPORT
#endif

Two differences:

  • supporting MINGW32
  • checking for GNUC>=4

Do we want these here?

Entry point naming convention

It is required that VM implementations have different names for "create" function.
At the moment we recommend naming them as <vm-name>_create.
I'd like to change the convention to evmc_create_<vm-name>.

This name would be more distinctive and will contain evmc_ prefix to easier recognize that it is for.
Also, when loading dynamic library I'm considering iterating over all exported symbols searching for evmc_create_ prefix.

Implement caching proxy

This could be used as for caching both code translation (evmjit) and host access.

It should be implemented as an EVMC VM while also loading another VM and proxying between the two.

Add support for EIP-1087: Net storage gas metering for the EVM

I propose to extend the function evmc_set_storage() by returning additional information to

enum evmc_storage_status evmc_set_storage(
    struct evmc_context* context,
    const struct evmc_address* address,
    const struct evmc_uint256be* key,
    const struct evmc_uint256be* value
);

The enum evmc_storage_status would contain the information what happened with the storage, like

  • unmodified,
  • modified,
  • added,
  • deleted,
  • modified_dirty.

The gas cost is going to be applied after the evmc_set_storage() is executed (is this a problem?).

This also avoids calling evmc_get_storage() first.

Add feature so that VM can request inserting code into the state

For example Hera could request to insert precompiles at certain addresses.

I would imagine this could work as adding a function create_account(address, code, balance) which can be called within execute. We trust the VM to do anything already, so this shouldn't raise any permission questions.

Go binding crashes on empty output

The line at https://github.com/ethereum/evmc/blob/master/bindings/go/evmc/evmc.go#L215:

	output = C.GoBytes(unsafe.Pointer(result.output_data), C.int(result.output_size))

Seems to be crashing if output_data is NULL.

The "spec" however says that output_data can be NULL:

    /**
     * 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 MAY be NULL.
     */
    const uint8_t* output_data;

    /**
     * The size of the output data.
     *
     *  If output_data is NULL this MUST be 0.
     */
    size_t output_size;

Review Host callbacks return types

  • get_balance(), get_code_size(), get_code_hash().
    This should not return int to inform if an account exists. It would make it unnecessary complicated and a VM usually does not care (a contract might, but usually don't).

Two-phase initialization

We should split the evmc_context (host-side execution context) from evmc_context_fn_table. The evmc_context_fn_table should be renamed to evmc_host_interface and passed to the VM instance constructor. That would require splitting the ABI check from the VM instance creation.

Merge methods accessing accounts

Instead of

get_balance()
get_code_hash()
get_code_size()

have

struct account
{
  balance
  code_size
  code_hash
}
get_account() -> account

Replaces #117.

Tests do not compile on MacOS

[ 70%] Building CXX object test/unittests/CMakeFiles/evmc-test.dir/test_instructions.cpp.o
In file included from /Users/alex/Projects/evmc/test/unittests/test_instructions.cpp:5:
In file included from /Users/alex/Projects/evmc/include/evmc/instructions.h:16:
/Users/alex/Projects/evmc/include/evmc/evmc.h:450:29: error: commas at the end of enumerator lists are a C++11 extension [-Werror,-Wc++11-extensions]
    EVMC_STORAGE_DELETED = 3,
                            ^

Examples: bring back usage example

int main()
{
    struct evmc_instance* vm = evmc_create_examplevm();
    if (!evmc_is_abi_compatible(vm))
        return 1;
    // EVM bytecode goes here. This is one of the examples examplevm.c
    const uint8_t code[] = "\x30\x60\x00\x52\x59\x60\x00\xf3";
    const size_t code_size = sizeof(code);
    const struct evmc_uint256be code_hash = {.bytes = {1, 2, 3}};
    const uint8_t input[] = "Hello World!";
    const struct evmc_uint256be value = {{1, 0}};
    const struct evmc_address addr = {{0, 1, 2}};
    const int64_t gas = 200000;
    struct evmc_context ctx = {&ctx_fn_table};
    struct evmc_message msg;
    msg.sender = addr;
    msg.destination = addr;
    msg.value = value;
    msg.input_data = input;
    msg.input_size = sizeof(input);
    msg.code_hash = code_hash;
    msg.gas = gas;
    msg.depth = 0;
    struct evmc_result result = evmc_execute(vm, &ctx, EVMC_HOMESTEAD, &msg, code, code_size);
    printf("Execution result:\n");
    if (result.status_code != EVMC_SUCCESS)
    {
        printf("  EVM execution failure: %d\n", result.status_code);
    }
    else
    {
        printf("  Gas used: %" PRId64 "\n", gas - result.gas_left);
        printf("  Gas left: %" PRId64 "\n", result.gas_left);
        printf("  Output size: %zd\n", result.output_size);
        printf("  Output: ");
        size_t i = 0;
        for (i = 0; i < result.output_size; i++)
            printf("%02x ", result.output_data[i]);
        printf("\n");
    }
    evmc_release_result(&result);
    evmc_destroy(vm);
    return 0;
}

New status code `EVM_EC_ERROR`

This test: https://github.com/ethereum/tests/blob/develop/BlockchainTests/GeneralStateTests/stZeroKnowledge2/ecadd_0-0_1-3_21000_128_d0g0v0.json

throws exceptions in KEVM during some elliptic curve math. Currently, I am reporting elliptic curve errors as EVM_INTERNAL_ERROR, which does not count as an "exceptional" error but a VM failure. However, the test indicates that it should be treated as an "exceptional" error. See here (search for EVM_INTERNAL_ERROR): https://github.com/kframework/evm-semantics/blob/typed-exceptions/evm.md#precompiled-contracts

When running this using ./kevm run tests/ethereum-tests/BlockchainTests/GeneralStateTests/stZeroKnowledge2/ecadd_0-0_1-3_21000_128_d0g0v0.json, it indicates that it reaches:

<statusCode> EVM_INTERNAL_ERROR </statusCode>
<k> #exception ~> #return ... </k>

which basically means "if it's an exceptional error, handle it correctly", but because it's being reported as an EVM_INTERNAL_ERROR, execution halts and the test now fails.

I propose adding EVM_EC_ERROR, which indicates errors in the elliptic curve crypto functions.

Add support for Go 1.11

At least Windows builds are broken:

oader.c:19:41: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'struct evmc_instance * (*)(void)' [-Wcast-function-type]
 #define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn) GetProcAddress(handle, name)
                                         ^
loader.c:103:17: note: in expansion of macro 'DLL_GET_CREATE_FN'
     create_fn = DLL_GET_CREATE_FN(handle, name);
                 ^~~~~~~~~~~~~~~~~
loader.c:19:41: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'struct evmc_instance * (*)(void)' [-Wcast-function-type]
 #define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn) GetProcAddress(handle, name)
                                         ^
loader.c:112:25: note: in expansion of macro 'DLL_GET_CREATE_FN'
             create_fn = DLL_GET_CREATE_FN(handle, name);
                         ^~~~~~~~~~~~~~~~~
loader.c:19:41: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'struct evmc_instance * (*)(void)' [-Wcast-function-type]
 #define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn) GetProcAddress(handle, name)
                                         ^
loader.c:117:21: note: in expansion of macro 'DLL_GET_CREATE_FN'
         create_fn = DLL_GET_CREATE_FN(handle, "evmc_create");
                     ^~~~~~~~~~~~~~~~~

Consistent handling of evmc_result

  1. evmc_execute_fn returns it as value
  2. evmc_call_fn expects a user specified pointer refering to it, to be filled
  3. evmc_release_result_fn expects a pointer to it, yet it

I assume 3. because you wanted it to behave like a C++ destructor.

It would be nice to:

  • evmc_call_fn to return the result struct as a value
  • evmc_release_result_fn not take a pointer, but a struct

Both these make it even more clear that evmc_result struct cannot be extended by the VM.

evmc_execute should take evmc_tx_context as an parameter

I think all those execution details should be available to the client prior to execution. Do you think any client can be savings by assuming the code will not need those and only lazily populate evmc_tx_context on the first call to to get_tx_context?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.