cmd/evm, core/vm/runtime: add more support for prestate configs

This commit is contained in:
cdetrio 2017-08-24 12:31:38 -04:00
parent 68955ed2eb
commit 807044be87
3 changed files with 37 additions and 6 deletions

View file

@ -24,6 +24,7 @@ import (
"os"
"runtime/pprof"
"time"
"math/big"
goruntime "runtime"
@ -83,6 +84,10 @@ func runCmd(ctx *cli.Context) error {
debugLogger *vm.StructLogger
statedb *state.StateDB
chainConfig *params.ChainConfig
genCoinbase common.Address
genTimestamp uint64
genGasLimit uint64
genDifficulty *big.Int
sender = common.StringToAddress("sender")
receiver = common.StringToAddress("receiver")
)
@ -96,6 +101,10 @@ func runCmd(ctx *cli.Context) error {
}
if ctx.GlobalString(GenesisFlag.Name) != "" {
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
genCoinbase = gen.Coinbase
genDifficulty = gen.Difficulty
genGasLimit = gen.GasLimit
genTimestamp = gen.Timestamp
_, statedb = gen.ToBlock()
chainConfig = gen.Config
} else {
@ -105,7 +114,8 @@ func runCmd(ctx *cli.Context) error {
if 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) != "" {
receiver = common.HexToAddress(ctx.GlobalString(ReceiverFlag.Name))
@ -154,9 +164,13 @@ func runCmd(ctx *cli.Context) error {
initialGas := ctx.GlobalUint64(GasFlag.Name)
runtimeConfig := runtime.Config{
Origin: sender,
Time: new(big.Int).SetUint64(genTimestamp),
Coinbase: genCoinbase,
Difficulty: genDifficulty,
State: statedb,
GasLimit: initialGas,
GasLimit: genGasLimit,
GasPrice: utils.GlobalBig(ctx, PriceFlag.Name),
TxGasLimit: initialGas,
Value: utils.GlobalBig(ctx, ValueFlag.Name),
EVMConfig: vm.Config{
Tracer: tracer,
@ -183,15 +197,30 @@ func runCmd(ctx *cli.Context) error {
}
tstart := time.Now()
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) {
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)
} else {
if len(code) > 0 {
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)
}
// 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)
if ctx.GlobalBool(DumpFlag.Name) {

View file

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

View file

@ -40,6 +40,7 @@ type Config struct {
Time *big.Int
GasLimit uint64
GasPrice *big.Int
TxGasLimit uint64
Value *big.Int
DisableJit bool // "disable" so it's enabled by default
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
// to it's original state afterwards.
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
// TODO: remove Execute()?
// only used in runtime_example_test.go
if cfg == nil {
cfg = new(Config)
}
@ -144,7 +147,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
code, address, leftOverGas, err := vmenv.Create(
sender,
input,
cfg.GasLimit,
cfg.TxGasLimit,
cfg.Value,
)
return code, address, leftOverGas, err
@ -166,7 +169,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
sender,
address,
input,
cfg.GasLimit,
cfg.TxGasLimit,
cfg.Value,
)