This commit is contained in:
cdetrio 2017-12-04 22:20:51 +00:00 committed by GitHub
commit ba4e20545d
3 changed files with 40 additions and 6 deletions

View file

@ -24,6 +24,7 @@ import (
"os" "os"
"runtime/pprof" "runtime/pprof"
"time" "time"
"math/big"
goruntime "runtime" goruntime "runtime"
@ -83,6 +84,11 @@ func runCmd(ctx *cli.Context) error {
debugLogger *vm.StructLogger debugLogger *vm.StructLogger
statedb *state.StateDB statedb *state.StateDB
chainConfig *params.ChainConfig chainConfig *params.ChainConfig
genCoinbase common.Address
genTimestamp uint64
genGasLimit uint64
genDifficulty *big.Int
genNumber uint64
sender = common.StringToAddress("sender") sender = common.StringToAddress("sender")
receiver = common.StringToAddress("receiver") receiver = common.StringToAddress("receiver")
) )
@ -96,6 +102,11 @@ func runCmd(ctx *cli.Context) error {
} }
if ctx.GlobalString(GenesisFlag.Name) != "" { if ctx.GlobalString(GenesisFlag.Name) != "" {
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name)) gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
genCoinbase = gen.Coinbase
genDifficulty = gen.Difficulty
genGasLimit = gen.GasLimit
genTimestamp = gen.Timestamp
genNumber = gen.Number
_, statedb = gen.ToBlock() _, statedb = gen.ToBlock()
chainConfig = gen.Config chainConfig = gen.Config
} else { } else {
@ -105,7 +116,8 @@ func runCmd(ctx *cli.Context) error {
if ctx.GlobalString(SenderFlag.Name) != "" { if ctx.GlobalString(SenderFlag.Name) != "" {
sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name)) sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name))
} }
statedb.CreateAccount(sender) // TODO: createAccount overwrites the nonce in the prestate. should only be used if no prestate provided
// statedb.CreateAccount(sender)
if ctx.GlobalString(ReceiverFlag.Name) != "" { if ctx.GlobalString(ReceiverFlag.Name) != "" {
receiver = common.HexToAddress(ctx.GlobalString(ReceiverFlag.Name)) receiver = common.HexToAddress(ctx.GlobalString(ReceiverFlag.Name))
@ -154,9 +166,14 @@ func runCmd(ctx *cli.Context) error {
initialGas := ctx.GlobalUint64(GasFlag.Name) initialGas := ctx.GlobalUint64(GasFlag.Name)
runtimeConfig := runtime.Config{ runtimeConfig := runtime.Config{
Origin: sender, Origin: sender,
Time: new(big.Int).SetUint64(genTimestamp),
Coinbase: genCoinbase,
Difficulty: genDifficulty,
BlockNumber: new(big.Int).SetUint64(genNumber),
State: statedb, State: statedb,
GasLimit: initialGas, GasLimit: genGasLimit,
GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), GasPrice: utils.GlobalBig(ctx, PriceFlag.Name),
TxGasLimit: initialGas,
Value: utils.GlobalBig(ctx, ValueFlag.Name), Value: utils.GlobalBig(ctx, ValueFlag.Name),
EVMConfig: vm.Config{ EVMConfig: vm.Config{
Tracer: tracer, Tracer: tracer,
@ -183,15 +200,30 @@ func runCmd(ctx *cli.Context) error {
} }
tstart := time.Now() tstart := time.Now()
var leftOverGas uint64 var leftOverGas uint64
// sender account pre-pays gas
mgval := new(big.Int).Mul(new(big.Int).SetUint64(initialGas), runtimeConfig.GasPrice)
statedb.SubBalance(sender, mgval)
if ctx.GlobalBool(CreateFlag.Name) { if ctx.GlobalBool(CreateFlag.Name) {
input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...) input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...)
intrinsicGas := core.IntrinsicGas(input, ctx.GlobalBool(CreateFlag.Name), true)
initialGas -= intrinsicGas.Uint64()
runtimeConfig.TxGasLimit = initialGas
ret, _, leftOverGas, err = runtime.Create(input, &runtimeConfig) ret, _, leftOverGas, err = runtime.Create(input, &runtimeConfig)
} else { } else {
if len(code) > 0 { if len(code) > 0 {
statedb.SetCode(receiver, code) statedb.SetCode(receiver, code)
} }
intrinsicGas := core.IntrinsicGas(common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), false, true)
initialGas -= intrinsicGas.Uint64()
runtimeConfig.TxGasLimit = initialGas
ret, leftOverGas, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig) ret, leftOverGas, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig)
} }
// refund sender unused prepaid gas
remainingEther := new(big.Int).Mul(new(big.Int).SetUint64(leftOverGas), runtimeConfig.GasPrice)
statedb.AddBalance(sender, remainingEther)
execTime := time.Since(tstart) execTime := time.Since(tstart)
if ctx.GlobalBool(DumpFlag.Name) { if ctx.GlobalBool(DumpFlag.Name) {

View file

@ -19,7 +19,6 @@ package runtime
import ( import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
) )
@ -28,7 +27,7 @@ func NewEnv(cfg *Config) *vm.EVM {
context := vm.Context{ context := vm.Context{
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,
Transfer: core.Transfer, Transfer: core.Transfer,
GetHash: func(uint64) common.Hash { return common.Hash{} }, GetHash: cfg.GetHashFn,
Origin: cfg.Origin, Origin: cfg.Origin,
Coinbase: cfg.Coinbase, Coinbase: cfg.Coinbase,

View file

@ -40,6 +40,7 @@ type Config struct {
Time *big.Int Time *big.Int
GasLimit uint64 GasLimit uint64
GasPrice *big.Int GasPrice *big.Int
TxGasLimit uint64
Value *big.Int Value *big.Int
DisableJit bool // "disable" so it's enabled by default DisableJit bool // "disable" so it's enabled by default
Debug bool Debug bool
@ -95,6 +96,8 @@ func setDefaults(cfg *Config) {
// the given code. It enabled the JIT by default and make sure that it's restored // the given code. It enabled the JIT by default and make sure that it's restored
// to it's original state afterwards. // to it's original state afterwards.
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
// TODO: remove Execute()?
// only used in runtime_example_test.go
if cfg == nil { if cfg == nil {
cfg = new(Config) cfg = new(Config)
} }
@ -144,7 +147,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
code, address, leftOverGas, err := vmenv.Create( code, address, leftOverGas, err := vmenv.Create(
sender, sender,
input, input,
cfg.GasLimit, cfg.TxGasLimit,
cfg.Value, cfg.Value,
) )
return code, address, leftOverGas, err return code, address, leftOverGas, err
@ -166,7 +169,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
sender, sender,
address, address,
input, input,
cfg.GasLimit, cfg.TxGasLimit,
cfg.Value, cfg.Value,
) )