core/vm, cmd/evm: Add ability for 'evm' binary to report gas used

This commit is contained in:
Martin Holst Swende 2017-06-04 20:46:29 +02:00
parent 567f69539e
commit 21ac4dd109
3 changed files with 15 additions and 13 deletions

View file

@ -137,11 +137,11 @@ func runCmd(ctx *cli.Context) error {
}
code = common.Hex2Bytes(string(bytes.TrimRight(hexcode, "\n")))
}
initialGas := ctx.GlobalUint64(GasFlag.Name)
runtimeConfig := runtime.Config{
Origin: sender,
State: statedb,
GasLimit: ctx.GlobalUint64(GasFlag.Name),
GasLimit: initialGas,
GasPrice: utils.GlobalBig(ctx, PriceFlag.Name),
Value: utils.GlobalBig(ctx, ValueFlag.Name),
EVMConfig: vm.Config{
@ -168,14 +168,15 @@ func runCmd(ctx *cli.Context) error {
runtimeConfig.ChainConfig = chainConfig
}
tstart := time.Now()
var leftOverGas uint64
if ctx.GlobalBool(CreateFlag.Name) {
input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...)
ret, _, err = runtime.Create(input, &runtimeConfig)
ret, _, leftOverGas, err = runtime.Create(input, &runtimeConfig)
} else {
receiver := common.StringToAddress("receiver")
statedb.SetCode(receiver, code)
ret, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig)
ret, leftOverGas, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig)
}
execTime := time.Since(tstart)
@ -214,11 +215,12 @@ heap objects: %d
allocations: %d
total allocations: %d
GC calls: %d
Gas used: %d
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC)
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas)
}
if tracer != nil {
tracer.CaptureEnd(ret, 0, execTime)
tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime)
} else {
fmt.Printf("0x%x\n", ret)
}

View file

@ -125,7 +125,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
}
// Create executes the code using the EVM create method
func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
if cfg == nil {
cfg = new(Config)
}
@ -141,13 +141,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
)
// Call the code with the given configuration.
code, address, _, err := vmenv.Create(
code, address, leftOverGas, err := vmenv.Create(
sender,
input,
cfg.GasLimit,
cfg.Value,
)
return code, address, err
return code, address, leftOverGas, err
}
// Call executes the code given by the contract's address. It will return the
@ -155,14 +155,14 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
//
// Call, unlike Execute, requires a config and also requires the State field to
// be set.
func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) {
func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) {
setDefaults(cfg)
vmenv := NewEnv(cfg, cfg.State)
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
// Call the code with the given configuration.
ret, _, err := vmenv.Call(
ret, leftOverGas, err := vmenv.Call(
sender,
address,
input,
@ -170,5 +170,5 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) {
cfg.Value,
)
return ret, err
return ret, leftOverGas, err
}

View file

@ -106,7 +106,7 @@ func TestCall(t *testing.T) {
byte(vm.RETURN),
})
ret, err := Call(address, nil, &Config{State: state})
ret, _, err := Call(address, nil, &Config{State: state})
if err != nil {
t.Fatal("didn't expect error", err)
}