From 4c0883e20d78b987dc95acd46498f326626aaee3 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 23 Oct 2018 16:28:18 +0200 Subject: core/vm: adds refund as part of the json standard trace (#17910) This adds the global accumulated refund counter to the standard json output as a numeric json value. Previously this was not very interesting since it was not used much, but with the new sstore gas changes the value is a lot more interesting from a consensus investigation perspective. --- eth/tracers/tracer.go | 16 +++++++++++----- eth/tracers/tracer_test.go | 11 +++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'eth/tracers') diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go index b519236f2..3533a831f 100644 --- a/eth/tracers/tracer.go +++ b/eth/tracers/tracer.go @@ -290,11 +290,12 @@ type Tracer struct { contractWrapper *contractWrapper // Wrapper around the contract object dbWrapper *dbWrapper // Wrapper around the VM environment - pcValue *uint // Swappable pc value wrapped by a log accessor - gasValue *uint // Swappable gas value wrapped by a log accessor - costValue *uint // Swappable cost value wrapped by a log accessor - depthValue *uint // Swappable depth value wrapped by a log accessor - errorValue *string // Swappable error value wrapped by a log accessor + pcValue *uint // Swappable pc value wrapped by a log accessor + gasValue *uint // Swappable gas value wrapped by a log accessor + costValue *uint // Swappable cost value wrapped by a log accessor + depthValue *uint // Swappable depth value wrapped by a log accessor + errorValue *string // Swappable error value wrapped by a log accessor + refundValue *uint // Swappable refund value wrapped by a log accessor ctx map[string]interface{} // Transaction context gathered throughout execution err error // Error, if one has occurred @@ -323,6 +324,7 @@ func New(code string) (*Tracer, error) { gasValue: new(uint), costValue: new(uint), depthValue: new(uint), + refundValue: new(uint), } // Set up builtins for this environment tracer.vm.PushGlobalGoFunction("toHex", func(ctx *duktape.Context) int { @@ -442,6 +444,9 @@ func New(code string) (*Tracer, error) { tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.depthValue); return 1 }) tracer.vm.PutPropString(logObject, "getDepth") + tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.refundValue); return 1 }) + tracer.vm.PutPropString(logObject, "getRefund") + tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { if tracer.errorValue != nil { ctx.PushString(*tracer.errorValue) @@ -527,6 +532,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost *jst.gasValue = uint(gas) *jst.costValue = uint(cost) *jst.depthValue = uint(depth) + *jst.refundValue = uint(env.StateDB.GetRefund()) jst.errorValue = nil if err != nil { diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 58b624724..52f29c83f 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" ) @@ -43,8 +44,14 @@ func (account) ReturnGas(*big.Int) {} func (account) SetCode(common.Hash, []byte) {} func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} +type dummyStatedb struct { + state.StateDB +} + +func (dummyStatedb) GetRefund() uint64 { return 1337 } + func runTrace(tracer *Tracer) (json.RawMessage, error) { - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} @@ -126,7 +133,7 @@ func TestHaltBetweenSteps(t *testing.T) { t.Fatal(err) } - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) -- cgit v1.2.3