From 796905bd23d041e1ceb85bfca1fed86d8e347375 Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Mon, 4 May 2020 12:42:30 +0300 Subject: [PATCH] go: Remove dependencies on go-ethereum This introduces evmc.Address and evmc.Hash types as a replacement of using ones from go-ethereum/common. --- CHANGELOG.md | 8 ++++++ appveyor.yml | 1 - bindings/go/evmc/evmc.go | 31 ++++++++++++-------- bindings/go/evmc/evmc_test.go | 8 ++---- bindings/go/evmc/host.go | 53 +++++++++++++++++------------------ bindings/go/evmc/host_test.go | 47 +++++++++++++++---------------- circle.yml | 1 - 7 files changed, 78 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 706e5e662..1f425992f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/appveyor.yml b/appveyor.yml index 81cf7e0b0..8400e8cbc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 diff --git a/bindings/go/evmc/evmc.go b/bindings/go/evmc/evmc.go index db72bf37d..1f3609033 100644 --- a/bindings/go/evmc/evmc.go +++ b/bindings/go/evmc/evmc.go @@ -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 @@ -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 @@ -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 { @@ -283,7 +292,7 @@ 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]) @@ -291,7 +300,7 @@ func evmcBytes32(in common.Hash) C.evmc_bytes32 { 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]) diff --git a/bindings/go/evmc/evmc_test.go b/bindings/go/evmc/evmc_test.go index cd881e8ab..e089058f6 100644 --- a/bindings/go/evmc/evmc_test.go +++ b/bindings/go/evmc/evmc_test.go @@ -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 @@ -9,8 +9,6 @@ package evmc import ( "bytes" "testing" - - "github.com/ethereum/go-ethereum/common" ) var modulePath = "./example_vm.so" @@ -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 { diff --git a/bindings/go/evmc/host.go b/bindings/go/evmc/host.go index 478ac5cf8..88460e638 100644 --- a/bindings/go/evmc/host.go +++ b/bindings/go/evmc/host.go @@ -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 @@ -13,10 +13,7 @@ package evmc */ import "C" import ( - "math/big" "unsafe" - - "github.com/ethereum/go-ethereum/common" ) type CallKind int @@ -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]) } @@ -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 @@ -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]) } @@ -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 { diff --git a/bindings/go/evmc/host_test.go b/bindings/go/evmc/host_test.go index 214e292a3..fe4e107c3 100644 --- a/bindings/go/evmc/host_test.go +++ b/bindings/go/evmc/host_test.go @@ -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 { @@ -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) { @@ -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 { @@ -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 { diff --git a/circle.yml b/circle.yml index 7f5aa3608..569c3bef6 100644 --- a/circle.yml +++ b/circle.yml @@ -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