mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/vm: renamed variables
This commit is contained in:
parent
87bbc432ab
commit
22ca13fa85
3 changed files with 50 additions and 35 deletions
|
|
@ -91,6 +91,8 @@ type EVM struct {
|
||||||
|
|
||||||
// chainConfig contains information about the current chain
|
// chainConfig contains information about the current chain
|
||||||
chainConfig *params.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
|
// chain rules contains the chain rules for the current epoch
|
||||||
|
chainRules params.Rules
|
||||||
// virtual machine configuration options used to initialise the
|
// virtual machine configuration options used to initialise the
|
||||||
// evm.
|
// evm.
|
||||||
vmConfig Config
|
vmConfig Config
|
||||||
|
|
@ -110,6 +112,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
|
chainRules: chainConfig.Rules(ctx.BlockNumber),
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.interpreter = NewInterpreter(evm, vmConfig)
|
evm.interpreter = NewInterpreter(evm, vmConfig)
|
||||||
|
|
|
||||||
|
|
@ -46,18 +46,18 @@ type Config struct {
|
||||||
DisableGasMetering bool
|
DisableGasMetering bool
|
||||||
// Enable recording of SHA3/keccak preimages
|
// Enable recording of SHA3/keccak preimages
|
||||||
EnablePreimageRecording bool
|
EnablePreimageRecording bool
|
||||||
// JumpTable contains the EVM instruction table. This
|
// JumpTable contains the in instruction table. This
|
||||||
// may me left uninitialised and will be set the default
|
// may me left uninitialised and will be set the default
|
||||||
// table.
|
// table.
|
||||||
JumpTable [256]operation
|
JumpTable [256]operation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpreter is used to run Ethereum based contracts and will utilise the
|
// Interpreter is used to run Ethereum based contracts and will utilise the
|
||||||
// passed environment to query external sources for state information.
|
// passed evmironment to query external sources for state information.
|
||||||
// The Interpreter will run the byte code VM or JIT VM based on the passed
|
// The Interpreter will run the byte code VM or JIT VM based on the passed
|
||||||
// configuration.
|
// configuration.
|
||||||
type Interpreter struct {
|
type Interpreter struct {
|
||||||
env *EVM
|
evm *EVM
|
||||||
cfg Config
|
cfg Config
|
||||||
gasTable params.GasTable
|
gasTable params.GasTable
|
||||||
intPool *intPool
|
intPool *intPool
|
||||||
|
|
@ -66,15 +66,15 @@ type Interpreter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInterpreter returns a new instance of the Interpreter.
|
// NewInterpreter returns a new instance of the Interpreter.
|
||||||
func NewInterpreter(env *EVM, cfg Config) *Interpreter {
|
func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
|
||||||
// We use the STOP instruction whether to see
|
// We use the STOP instruction whether to see
|
||||||
// the jump table was initialised. If it was not
|
// the jump table was initialised. If it was not
|
||||||
// we'll set the default jump table.
|
// we'll set the default jump table.
|
||||||
if !cfg.JumpTable[STOP].valid {
|
if !cfg.JumpTable[STOP].valid {
|
||||||
switch {
|
switch {
|
||||||
case env.ChainConfig().IsMetropolis(env.BlockNumber):
|
case evm.ChainConfig().IsMetropolis(evm.BlockNumber):
|
||||||
cfg.JumpTable = metropolisInstructionSet
|
cfg.JumpTable = metropolisInstructionSet
|
||||||
case env.ChainConfig().IsHomestead(env.BlockNumber):
|
case evm.ChainConfig().IsHomestead(evm.BlockNumber):
|
||||||
cfg.JumpTable = homesteadInstructionSet
|
cfg.JumpTable = homesteadInstructionSet
|
||||||
default:
|
default:
|
||||||
cfg.JumpTable = baseInstructionSet
|
cfg.JumpTable = baseInstructionSet
|
||||||
|
|
@ -82,22 +82,36 @@ func NewInterpreter(env *EVM, cfg Config) *Interpreter {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Interpreter{
|
return &Interpreter{
|
||||||
env: env,
|
evm: evm,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
gasTable: env.ChainConfig().GasTable(env.BlockNumber),
|
gasTable: evm.ChainConfig().GasTable(evm.BlockNumber),
|
||||||
intPool: newIntPool(),
|
intPool: newIntPool(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error {
|
||||||
|
if in.evm.chainRules.IsMetropolis {
|
||||||
|
if in.readonly {
|
||||||
|
// if the interpreter is operating in readonly mode, make sure no
|
||||||
|
// state-modifying operation is performed.
|
||||||
|
if operation.writes ||
|
||||||
|
((op == CALL || op == CALLCODE) && stack.Back(3).BitLen() > 0) {
|
||||||
|
return errWriteProtection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Run loops and evaluates the contract's code with the given input data and returns
|
// Run loops and evaluates the contract's code with the given input data and returns
|
||||||
// the return byte-slice and an error if one occured.
|
// the return byte-slice and an error if one occured.
|
||||||
//
|
//
|
||||||
// It's important to note that any errors returned by the interpreter should be
|
// It's important to note that any errors returned by the interpreter should be
|
||||||
// considered a revert-and-consume-all-gas operation. No error specific checks
|
// considered a revert-and-consume-all-gas operation. No error specific checks
|
||||||
// should be handled to reduce complexity and errors further down the EVM.
|
// should be handled to reduce complexity and errors further down the in.
|
||||||
func (evm *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret []byte, err error) {
|
func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret []byte, err error) {
|
||||||
evm.env.depth++
|
in.evm.depth++
|
||||||
defer func() { evm.env.depth-- }()
|
defer func() { in.evm.depth-- }()
|
||||||
|
|
||||||
// Don't bother with the execution if there's no code.
|
// Don't bother with the execution if there's no code.
|
||||||
if len(contract.Code) == 0 {
|
if len(contract.Code) == 0 {
|
||||||
|
|
@ -123,37 +137,31 @@ func (evm *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
|
||||||
|
|
||||||
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
|
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && evm.cfg.Debug {
|
if err != nil && in.cfg.Debug {
|
||||||
// XXX For debugging
|
// XXX For debugging
|
||||||
//fmt.Printf("%04d: %8v cost = %-8d stack = %-8d ERR = %v\n", pc, op, cost, stack.len(), err)
|
//fmt.Printf("%04d: %8v cost = %-8d stack = %-8d ERR = %v\n", pc, op, cost, stack.len(), err)
|
||||||
// TODO update the tracer to accept uint64 instead of *big.Int
|
// TODO update the tracer to accept uint64 instead of *big.Int
|
||||||
g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
|
g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
|
||||||
evm.cfg.Tracer.CaptureState(evm.env, pc, op, contract.Gas, cost, mem, stack, contract, evm.env.depth, err)
|
in.cfg.Tracer.CaptureState(in.evm, pc, op, g, c, mem, stack, contract, in.evm.depth, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Debug("EVM running contract", "hash", codehash[:])
|
log.Debug("in running contract", "hash", codehash[:])
|
||||||
tstart := time.Now()
|
tstart := time.Now()
|
||||||
defer log.Debug("EVM finished running contract", "hash", codehash[:], "elapsed", time.Since(tstart))
|
defer log.Debug("in finished running contract", "hash", codehash[:], "elapsed", time.Since(tstart))
|
||||||
|
|
||||||
// The Interpreter main run loop (contextual). This loop runs until either an
|
// The Interpreter main run loop (contextual). This loop runs until either an
|
||||||
// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
|
// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
|
||||||
// the execution of one of the operations or until the evm.done is set by
|
// the execution of one of the operations or until the in.done is set by
|
||||||
// the parent context.Context.
|
// the parent context.Context.
|
||||||
for atomic.LoadInt32(&evm.env.abort) == 0 {
|
for atomic.LoadInt32(&in.evm.abort) == 0 {
|
||||||
// Get the memory location of pc
|
// Get the memory location of pc
|
||||||
op = contract.GetOp(pc)
|
op = contract.GetOp(pc)
|
||||||
|
|
||||||
// get the operation from the jump table matching the opcode
|
// get the operation from the jump table matching the opcode
|
||||||
operation := evm.cfg.JumpTable[op]
|
operation := in.cfg.JumpTable[op]
|
||||||
// if the interpreter is operating in readonly mode, make sure no
|
if err := in.enforceRestrictions(op, operation, stack); err != nil {
|
||||||
// state-modifying operation is performed.
|
return nil, err
|
||||||
if evm.readonly && evm.env.chainConfig.IsMetropolis(evm.env.BlockNumber) {
|
|
||||||
if operation.writes ||
|
|
||||||
((op == CALL || op == CALLCODE) && stack.Back(3).BitLen() > 0) {
|
|
||||||
return nil, errWriteProtection
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the op is invalid abort the process and return an error
|
// if the op is invalid abort the process and return an error
|
||||||
|
|
@ -182,10 +190,10 @@ func (evm *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !evm.cfg.DisableGasMetering {
|
if !in.cfg.DisableGasMetering {
|
||||||
// consume the gas and return an error if not enough gas is available.
|
// consume the gas and return an error if not enough gas is available.
|
||||||
// cost is explicitly set so that the capture state defer method cas get the proper cost
|
// cost is explicitly set so that the capture state defer method cas get the proper cost
|
||||||
cost, err = operation.gasCost(evm.gasTable, evm.env, contract, stack, mem, memorySize)
|
cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize)
|
||||||
if err != nil || !contract.UseGas(cost) {
|
if err != nil || !contract.UseGas(cost) {
|
||||||
return nil, ErrOutOfGas
|
return nil, ErrOutOfGas
|
||||||
}
|
}
|
||||||
|
|
@ -194,25 +202,25 @@ func (evm *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
|
||||||
mem.Resize(memorySize)
|
mem.Resize(memorySize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if evm.cfg.Debug {
|
if in.cfg.Debug {
|
||||||
// TODO update the tracer to accept uint64 instead of *big.Int
|
// TODO update the tracer to accept uint64 instead of *big.Int
|
||||||
g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
|
g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
|
||||||
evm.cfg.Tracer.CaptureState(evm.env, pc, op, g, c, mem, stack, contract, evm.env.depth, err)
|
in.cfg.Tracer.CaptureState(in.evm, pc, op, g, c, mem, stack, contract, in.evm.depth, err)
|
||||||
}
|
}
|
||||||
// XXX For debugging
|
// XXX For debugging
|
||||||
//fmt.Printf("%04d: %8v cost = %-8d stack = %-8d\n", pc, op, cost, stack.len())
|
//fmt.Printf("%04d: %8v cost = %-8d stack = %-8d\n", pc, op, cost, stack.len())
|
||||||
|
|
||||||
// execute the operation
|
// execute the operation
|
||||||
res, err := operation.execute(&pc, evm.env, contract, mem, stack)
|
res, err := operation.execute(&pc, in.evm, contract, mem, stack)
|
||||||
// verifyPool is a build flag. Pool verification makes sure the integrity
|
// verifyPool is a build flag. Pool verification makes sure the integrity
|
||||||
// of the integer pool by comparing values to a default value.
|
// of the integer pool by comparing values to a default value.
|
||||||
if verifyPool {
|
if verifyPool {
|
||||||
verifyIntegerPool(evm.intPool)
|
verifyIntegerPool(in.intPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks whether the operation should revert state.
|
// checks whether the operation should revert state.
|
||||||
if operation.reverts {
|
if operation.reverts {
|
||||||
evm.env.StateDB.RevertToSnapshot(snapshot)
|
in.evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|
|
||||||
|
|
@ -255,5 +255,9 @@ type Rules struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChainConfig) Rules(num *big.Int) Rules {
|
func (c *ChainConfig) Rules(num *big.Int) Rules {
|
||||||
return Rules{ChainId: new(big.Int).Set(c.ChainId), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsMetropolis: c.IsMetropolis(num)}
|
chainId := c.ChainId
|
||||||
|
if chainId == nil {
|
||||||
|
chainId = new(big.Int)
|
||||||
|
}
|
||||||
|
return Rules{ChainId: new(big.Int).Set(chainId), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsMetropolis: c.IsMetropolis(num)}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue