Skip to content

Commit

Permalink
Add refund to execution result in Go binding (#690)
Browse files Browse the repository at this point in the history
This PR modifies the `Execute()` function from the Go bindings to return a `Result` struct instead of a list of result values to support the retrieval of the amount of refunded gas. This information is available in [evmc.h](https://github.com/ethereum/evmc/blob/v10.1.0/include/evmc/evmc.h)'s [evmc_result](https://github.com/ethereum/evmc/blob/v10.1.0/include/evmc/evmc.h#L404-L410), but was not exposed in the Go binding so far.
  • Loading branch information
HerbertJordan authored Nov 29, 2023
1 parent c3feb59 commit bf7f382
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
15 changes: 11 additions & 4 deletions bindings/go/evmc/evmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,16 @@ func (vm *VM) SetOption(name string, value string) (err error) {
return err
}

type Result struct {
Output []byte
GasLeft int64
GasRefund int64
}

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

flags := C.uint32_t(0)
if static {
Expand All @@ -216,8 +222,9 @@ func (vm *VM) Execute(ctx HostContext, rev Revision,
bytesPtr(code), C.size_t(len(code)))
removeHostContext(ctxId)

output = C.GoBytes(unsafe.Pointer(result.output_data), C.int(result.output_size))
gasLeft = int64(result.gas_left)
res.Output = C.GoBytes(unsafe.Pointer(result.output_data), C.int(result.output_size))
res.GasLeft = int64(result.gas_left)
res.GasRefund = int64(result.gas_refund)
if result.status_code != C.EVMC_SUCCESS {
err = Error(result.status_code)
}
Expand All @@ -226,7 +233,7 @@ func (vm *VM) Execute(ctx HostContext, rev Revision,
C.evmc_release_result(&result)
}

return output, gasLeft, err
return res, err
}

var (
Expand Down
13 changes: 8 additions & 5 deletions bindings/go/evmc/evmc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ func TestExecuteEmptyCode(t *testing.T) {

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

if bytes.Compare(output, []byte("")) != 0 {
t.Errorf("execution unexpected output: %x", output)
if !bytes.Equal(result.Output, []byte("")) {
t.Errorf("execution unexpected output: %x", result.Output)
}
if gasLeft != 999 {
t.Errorf("execution gas left is incorrect: %d", gasLeft)
if result.GasLeft != 999 {
t.Errorf("execution gas left is incorrect: %d", result.GasLeft)
}
if result.GasRefund != 0 {
t.Errorf("execution gas refund is incorrect: %d", result.GasRefund)
}
if err != nil {
t.Errorf("execution returned unexpected error: %v", err)
Expand Down
12 changes: 8 additions & 4 deletions bindings/go/evmc/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,17 @@ func TestGetBlockNumberFromTxContext(t *testing.T) {
host := &testHostContext{}
addr := Address{}
h := Hash{}
output, gasLeft, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code)
result, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code)
output := result.Output
gasLeft := result.GasLeft

if len(output) != 32 {
t.Errorf("unexpected output size: %d", len(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 {
if !bytes.Equal(output, expectedOutput) {
t.Errorf("execution unexpected output: %x", output)
}
if gasLeft != 94 {
Expand All @@ -111,12 +113,14 @@ func TestCall(t *testing.T) {
host := &testHostContext{}
addr := Address{}
h := Hash{}
output, gasLeft, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code)
result, err := vm.Execute(host, Byzantium, Call, false, 1, 100, addr, addr, nil, h, code)
output := result.Output
gasLeft := result.GasLeft

if len(output) != 34 {
t.Errorf("execution unexpected output length: %d", len(output))
}
if bytes.Compare(output, []byte("output from testHostContext.Call()")) != 0 {
if !bytes.Equal(output, []byte("output from testHostContext.Call()")) {
t.Errorf("execution unexpected output: %s", output)
}
if gasLeft != 89 {
Expand Down

0 comments on commit bf7f382

Please sign in to comment.