Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go: Remove dependencies on go-ethereum #513

Merged
merged 1 commit into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog],
and this project adheres to [Semantic Versioning].


## [7.3.0] — unreleased

### Changed

- Removed dependency on go-ethereum in Go bindings by introducing own `Address` and `Hash` types.
[#513](https://github.com/ethereum/evmc/pull/513)


## [7.2.0] — 2020-05-13

### Added
Expand Down
1 change: 0 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ build_script:
mkdir $env:GOPATH
gcc --version
go env
go get github.com/ethereum/go-ethereum/common

copy include/evmc/evmc.h bindings/go/evmc
copy include/evmc/helpers.h bindings/go/evmc
Expand Down
31 changes: 20 additions & 11 deletions bindings/go/evmc/evmc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2018-2019 The EVMC Authors.
// Copyright 2018-2020 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

package evmc
Expand Down Expand Up @@ -55,16 +55,25 @@ import (
"fmt"
"sync"
"unsafe"

"github.com/ethereum/go-ethereum/common"
)

// Hash represents the 32 bytes of arbitrary data (e.g. the result of Keccak256
// hash). It occasionally is used to represent 256-bit unsigned integer values
// stored in big-endian byte order.
type Hash [32]byte

// Address represents the 160-bit (20 bytes) address of an Ethereum account.
type Address [20]byte

// Static asserts.
const (
_ = uint(common.HashLength - C.sizeof_evmc_bytes32) // The size of evmc_bytes32 equals the size of Hash.
_ = uint(C.sizeof_evmc_bytes32 - common.HashLength)
_ = uint(common.AddressLength - C.sizeof_evmc_address) // The size of evmc_address equals the size of Address.
_ = uint(C.sizeof_evmc_address - common.AddressLength)
// The size of evmc_bytes32 equals the size of Hash.
_ = uint(len(Hash{}) - C.sizeof_evmc_bytes32)
_ = uint(C.sizeof_evmc_bytes32 - len(Hash{}))

// The size of evmc_address equals the size of Address.
_ = uint(len(Address{}) - C.sizeof_evmc_address)
_ = uint(C.sizeof_evmc_address - len(Address{}))
)

type Error int32
Expand Down Expand Up @@ -222,8 +231,8 @@ func (vm *VM) SetOption(name string, value string) (err error) {

func (vm *VM) Execute(ctx HostContext, rev Revision,
kind CallKind, static bool, depth int, gas int64,
destination common.Address, sender common.Address, input []byte, value common.Hash,
code []byte, create2Salt common.Hash) (output []byte, gasLeft int64, err error) {
destination Address, sender Address, input []byte, value Hash,
code []byte, create2Salt Hash) (output []byte, gasLeft int64, err error) {

flags := C.uint32_t(0)
if static {
Expand Down Expand Up @@ -283,15 +292,15 @@ func getHostContext(idx uintptr) HostContext {
return ctx
}

func evmcBytes32(in common.Hash) C.evmc_bytes32 {
func evmcBytes32(in Hash) C.evmc_bytes32 {
out := C.evmc_bytes32{}
for i := 0; i < len(in); i++ {
out.bytes[i] = C.uint8_t(in[i])
}
return out
}

func evmcAddress(address common.Address) C.evmc_address {
func evmcAddress(address Address) C.evmc_address {
r := C.evmc_address{}
for i := 0; i < len(address); i++ {
r.bytes[i] = C.uint8_t(address[i])
Expand Down
8 changes: 3 additions & 5 deletions bindings/go/evmc/evmc_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2018-2019 The EVMC Authors.
// 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
Expand All @@ -9,8 +9,6 @@ package evmc
import (
"bytes"
"testing"

"github.com/ethereum/go-ethereum/common"
)

var modulePath = "./example_vm.so"
Expand Down Expand Up @@ -47,8 +45,8 @@ func TestExecute(t *testing.T) {
vm, _ := Load(modulePath)
defer vm.Destroy()

addr := common.Address{}
h := common.Hash{}
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 {
Expand Down
53 changes: 25 additions & 28 deletions bindings/go/evmc/host.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2018-2019 The EVMC Authors.
// Copyright 2018-2020 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

package evmc
Expand All @@ -13,10 +13,7 @@ package evmc
*/
import "C"
import (
"math/big"
"unsafe"

"github.com/ethereum/go-ethereum/common"
)

type CallKind int
Expand All @@ -39,16 +36,16 @@ const (
StorageDeleted StorageStatus = C.EVMC_STORAGE_DELETED
)

func goAddress(in C.evmc_address) common.Address {
out := common.Address{}
func goAddress(in C.evmc_address) Address {
out := Address{}
for i := 0; i < len(out); i++ {
out[i] = byte(in.bytes[i])
}
return out
}

func goHash(in C.evmc_bytes32) common.Hash {
out := common.Hash{}
func goHash(in C.evmc_bytes32) Hash {
out := Hash{}
for i := 0; i < len(out); i++ {
out[i] = byte(in.bytes[i])
}
Expand All @@ -64,31 +61,31 @@ func goByteSlice(data *C.uint8_t, size C.size_t) []byte {

// TxContext contains information about current transaction and block.
type TxContext struct {
GasPrice common.Hash
Origin common.Address
Coinbase common.Address
GasPrice Hash
Origin Address
Coinbase Address
Number int64
Timestamp int64
GasLimit int64
Difficulty common.Hash
ChainID common.Hash
Difficulty Hash
ChainID Hash
}

type HostContext interface {
AccountExists(addr common.Address) bool
GetStorage(addr common.Address, key common.Hash) common.Hash
SetStorage(addr common.Address, key common.Hash, value common.Hash) StorageStatus
GetBalance(addr common.Address) common.Hash
GetCodeSize(addr common.Address) int
GetCodeHash(addr common.Address) common.Hash
GetCode(addr common.Address) []byte
Selfdestruct(addr common.Address, beneficiary common.Address)
AccountExists(addr Address) bool
GetStorage(addr Address, key Hash) Hash
SetStorage(addr Address, key Hash, value Hash) StorageStatus
GetBalance(addr Address) Hash
GetCodeSize(addr Address) int
GetCodeHash(addr Address) Hash
GetCode(addr Address) []byte
Selfdestruct(addr Address, beneficiary Address)
GetTxContext() TxContext
GetBlockHash(number int64) common.Hash
EmitLog(addr common.Address, topics []common.Hash, data []byte)
GetBlockHash(number int64) Hash
EmitLog(addr Address, topics []Hash, data []byte)
Call(kind CallKind,
destination common.Address, sender common.Address, value *big.Int, input []byte, gas int64, depth int,
static bool, salt *big.Int) (output []byte, gasLeft int64, createAddr common.Address, err error)
destination Address, sender Address, value Hash, input []byte, gas int64, depth int,
static bool, salt Hash) (output []byte, gasLeft int64, createAddr Address, err error)
}

//export accountExists
Expand Down Expand Up @@ -186,7 +183,7 @@ func emitLog(pCtx unsafe.Pointer, pAddr *C.evmc_address, pData unsafe.Pointer, d
tData := C.GoBytes(pTopics, C.int(topicsCount*32))

nTopics := int(topicsCount)
topics := make([]common.Hash, nTopics)
topics := make([]Hash, nTopics)
for i := 0; i < nTopics; i++ {
copy(topics[i][:], tData[i*32:(i+1)*32])
}
Expand All @@ -199,8 +196,8 @@ func call(pCtx unsafe.Pointer, msg *C.struct_evmc_message) C.struct_evmc_result
ctx := getHostContext(uintptr(pCtx))

kind := CallKind(msg.kind)
output, gasLeft, createAddr, err := ctx.Call(kind, goAddress(msg.destination), goAddress(msg.sender), goHash(msg.value).Big(),
goByteSlice(msg.input_data, msg.input_size), int64(msg.gas), int(msg.depth), msg.flags != 0, goHash(msg.create2_salt).Big())
output, gasLeft, createAddr, err := ctx.Call(kind, goAddress(msg.destination), goAddress(msg.sender), goHash(msg.value),
goByteSlice(msg.input_data, msg.input_size), int64(msg.gas), int(msg.depth), msg.flags != 0, goHash(msg.create2_salt))

statusCode := C.enum_evmc_status_code(0)
if err != nil {
Expand Down
47 changes: 22 additions & 25 deletions bindings/go/evmc/host_test.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,45 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2018-2019 The EVMC Authors.
// Copyright 2018-2020 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

package evmc

import (
"bytes"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
)

type testHostContext struct{}

func (host *testHostContext) AccountExists(addr common.Address) bool {
func (host *testHostContext) AccountExists(addr Address) bool {
return false
}

func (host *testHostContext) GetStorage(addr common.Address, key common.Hash) common.Hash {
return common.Hash{}
func (host *testHostContext) GetStorage(addr Address, key Hash) Hash {
return Hash{}
}

func (host *testHostContext) SetStorage(addr common.Address, key common.Hash, value common.Hash) (status StorageStatus) {
func (host *testHostContext) SetStorage(addr Address, key Hash, value Hash) (status StorageStatus) {
return StorageUnchanged
}

func (host *testHostContext) GetBalance(addr common.Address) common.Hash {
return common.Hash{}
func (host *testHostContext) GetBalance(addr Address) Hash {
return Hash{}
}

func (host *testHostContext) GetCodeSize(addr common.Address) int {
func (host *testHostContext) GetCodeSize(addr Address) int {
return 0
}

func (host *testHostContext) GetCodeHash(addr common.Address) common.Hash {
return common.Hash{}
func (host *testHostContext) GetCodeHash(addr Address) Hash {
return Hash{}
}

func (host *testHostContext) GetCode(addr common.Address) []byte {
func (host *testHostContext) GetCode(addr Address) []byte {
return nil
}

func (host *testHostContext) Selfdestruct(addr common.Address, beneficiary common.Address) {
func (host *testHostContext) Selfdestruct(addr Address, beneficiary Address) {
}

func (host *testHostContext) GetTxContext() TxContext {
Expand All @@ -51,18 +48,18 @@ func (host *testHostContext) GetTxContext() TxContext {
return txContext
}

func (host *testHostContext) GetBlockHash(number int64) common.Hash {
return common.Hash{}
func (host *testHostContext) GetBlockHash(number int64) Hash {
return Hash{}
}

func (host *testHostContext) EmitLog(addr common.Address, topics []common.Hash, data []byte) {
func (host *testHostContext) EmitLog(addr Address, topics []Hash, data []byte) {
}

func (host *testHostContext) Call(kind CallKind,
destination common.Address, sender common.Address, value *big.Int, input []byte, gas int64, depth int,
static bool, salt *big.Int) (output []byte, gasLeft int64, createAddr common.Address, err error) {
destination Address, sender Address, value Hash, input []byte, gas int64, depth int,
static bool, salt Hash) (output []byte, gasLeft int64, createAddr Address, err error) {
output = []byte("output from testHostContext.Call()")
return output, gas, common.Address{}, nil
return output, gas, Address{}, nil
}

func TestGetTxContext(t *testing.T) {
Expand All @@ -72,8 +69,8 @@ func TestGetTxContext(t *testing.T) {
host := &testHostContext{}
code := []byte("\x43\x60\x00\x52\x59\x60\x00\xf3")

addr := common.Address{}
h := common.Hash{}
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 {
Expand All @@ -97,8 +94,8 @@ func TestCall(t *testing.T) {
host := &testHostContext{}
code := []byte("\x60\x00\x80\x80\x80\x80\x80\x80\xf1")

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

if bytes.Compare(output, []byte("output from testHostContext.Call()")) != 0 {
Expand Down
1 change: 0 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ jobs:
- run:
name: "Go Build"
command: |
go get -v github.com/ethereum/go-ethereum/common
go build -v ./bindings/go/evmc
go vet -v ./bindings/go/evmc
go generate -v ./bindings/go/evmc
Expand Down