Skip to content

Commit

Permalink
Merge pull request #539 from ethereum/example_vm_cpp
Browse files Browse the repository at this point in the history
examples: Convert example VM implementation to C++
  • Loading branch information
chfast authored Nov 3, 2020
2 parents 0aeb25b + 8867609 commit 8a04005
Show file tree
Hide file tree
Showing 17 changed files with 633 additions and 289 deletions.
25 changes: 15 additions & 10 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ AccessModifierOffset: -4
AlignAfterOpenBracket: Align
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
SplitEmptyFunction: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
# AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
# BeforeLambdaBody: true
# BeforeWhile: true
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
ColumnLimit: 100
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ WARN_LOGFILE =
INPUT = \
include/evmc/ \
docs/ \
examples/example_vm/example_vm.c
examples/example_vm/example_vm.cpp
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
Expand Down
16 changes: 8 additions & 8 deletions bindings/go/evmc/evmc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright 2018-2020 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

//go:generate gcc -shared ../../../examples/example_vm/example_vm.c -I../../../include -o example_vm.so
//go:generate g++ -shared ../../../examples/example_vm/example_vm.cpp -I../../../include -o example_vm.so

package evmc

Expand Down Expand Up @@ -41,21 +41,21 @@ func TestLoadConfigure(t *testing.T) {
}
}

func TestExecute(t *testing.T) {
func TestExecuteEmptyCode(t *testing.T) {
vm, _ := Load(modulePath)
defer vm.Destroy()

addr := Address{}
h := Hash{}
output, gasLeft, err := vm.Execute(nil, Byzantium, Call, false, 1, 999, addr, addr, nil, h, nil, h)

if bytes.Compare(output, []byte("Welcome to Byzantium!")) != 0 {
t.Errorf("execution unexpected output: %s", output)
if bytes.Compare(output, []byte("")) != 0 {
t.Errorf("execution unexpected output: %x", output)
}
if gasLeft != 99 {
t.Error("execution gas left is incorrect")
if gasLeft != 999 {
t.Errorf("execution gas left is incorrect: %d", gasLeft)
}
if err != Failure {
t.Error("execution returned unexpected error")
if err != nil {
t.Errorf("execution returned unexpected error: %v", err)
}
}
32 changes: 20 additions & 12 deletions bindings/go/evmc/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,49 +62,57 @@ func (host *testHostContext) Call(kind CallKind,
return output, gas, Address{}, nil
}

func TestGetTxContext(t *testing.T) {
func TestGetBlockNumberFromTxContext(t *testing.T) {
// Yul: mstore(0, number()) return(0, msize())
code := []byte("\x43\x60\x00\x52\x59\x60\x00\xf3")

vm, _ := Load(modulePath)
defer vm.Destroy()

host := &testHostContext{}
code := []byte("\x43\x60\x00\x52\x59\x60\x00\xf3")

addr := Address{}
h := Hash{}
output, gasLeft, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code, h)

if len(output) != 20 {
if len(output) != 32 {
t.Errorf("unexpected output size: %d", len(output))
}
if bytes.Compare(output[0:3], []byte("42\x00")) != 0 {
t.Errorf("execution unexpected output: %s", output)

// Should return value 42 (0x2a) as defined in GetTxContext().
expectedOutput := []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a")
if bytes.Compare(output, expectedOutput) != 0 {
t.Errorf("execution unexpected output: %x", output)
}
if gasLeft != 50 {
if gasLeft != 94 {
t.Errorf("execution gas left is incorrect: %d", gasLeft)
}
if err != nil {
t.Error("execution returned unexpected error")
t.Errorf("execution returned unexpected error: %v", err)
}
}

func TestCall(t *testing.T) {
// pseudo-Yul: call(0, 0, 0, 0, 0, 0, 34) return(0, msize())
code := []byte("\x60\x22\x60\x00\x80\x80\x80\x80\x80\xf1\x59\x60\x00\xf3")

vm, _ := Load(modulePath)
defer vm.Destroy()

host := &testHostContext{}
code := []byte("\x60\x00\x80\x80\x80\x80\x80\x80\xf1")

addr := Address{}
h := Hash{}
output, gasLeft, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code, h)

if len(output) != 34 {
t.Errorf("execution unexpected output length: %d", len(output))
}
if bytes.Compare(output, []byte("output from testHostContext.Call()")) != 0 {
t.Errorf("execution unexpected output: %s", output)
}
if gasLeft != 99 {
if gasLeft != 89 {
t.Errorf("execution gas left is incorrect: %d", gasLeft)
}
if err != nil {
t.Error("execution returned unexpected error")
t.Errorf("execution returned unexpected error: %v", err)
}
}
12 changes: 6 additions & 6 deletions bindings/java/java/src/test/java/org/ethereum/evmc/EvmcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void testExecute_returnAddress() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == 0);
assert (gasLeft == 199994);
}
}

Expand Down Expand Up @@ -100,7 +100,7 @@ void testExecute_counter() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == 0);
assert (gasLeft == 199994);
}
}

Expand Down Expand Up @@ -130,7 +130,7 @@ void testExecute_returnBlockNumber() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == gas / 2);
assert (gasLeft == 199994);
}
}

Expand Down Expand Up @@ -162,7 +162,7 @@ void testExecute_saveReturnBlockNumber() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == gas / 2);
assert (gasLeft == 199991);
}
}

Expand Down Expand Up @@ -201,7 +201,7 @@ void testExecute_makeCall() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == 0); // gas - gas / 64);
assert (gasLeft == 199992);
}
}

Expand Down Expand Up @@ -229,7 +229,7 @@ void testExecute_EVMC_CREATE() throws Exception {
result.getInt(); // padding
long gasLeft = result.getLong();
assert (statusCode == 0);
assert (gasLeft == gas / 10);
assert (gasLeft == 199999);
}
}

Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ jobs:
go get -v $(grep -o 'github.com/ethereum/evmc/v.*' ../../go.mod)@$V
go mod tidy -v
go mod graph
gcc -shared -I../../include ../../examples/example_vm/example_vm.c -o example-vm.so
g++ -shared -I../../include ../../examples/example_vm/example_vm.cpp -o example-vm.so
go test -v
go mod graph
Expand Down
2 changes: 1 addition & 1 deletion docs/VM_Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## An example

You can start with [the example implementation of EVMC VM interface in C](@ref example_vm.c).
You can start with [the example implementation of EVMC VM interface in C++](@ref example_vm.cpp).

## VM instance

Expand Down
8 changes: 5 additions & 3 deletions examples/example_vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
# Copyright 2019-2020 The EVMC Authors.
# Licensed under the Apache License, Version 2.0.

add_library(example-vm SHARED example_vm.c example_vm.h)
add_library(example-vm SHARED example_vm.cpp example_vm.h)
add_library(evmc::example-vm ALIAS example-vm)
target_compile_features(example-vm PRIVATE cxx_std_11)
target_link_libraries(example-vm PRIVATE evmc::evmc)

add_library(example-vm-static STATIC example_vm.c example_vm.h)
add_library(example-vm-static STATIC example_vm.cpp example_vm.h)
add_library(evmc::example-vm-static ALIAS example-vm-static)
target_compile_features(example-vm-static PRIVATE cxx_std_11)
target_link_libraries(example-vm-static PRIVATE evmc::evmc)

set_source_files_properties(example_vm.c PROPERTIES
set_source_files_properties(example_vm.cpp PROPERTIES
COMPILE_DEFINITIONS PROJECT_VERSION="${PROJECT_VERSION}")

if(EVMC_INSTALL)
Expand Down
Loading

0 comments on commit 8a04005

Please sign in to comment.