mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/vm: remove function call for stack validation from evm runloop
This commit is contained in:
parent
f9aa1cd21f
commit
4caa9dec46
3 changed files with 778 additions and 641 deletions
|
|
@ -118,22 +118,6 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in *EVMInterpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error {
|
|
||||||
if in.evm.chainRules.IsByzantium {
|
|
||||||
if in.readOnly {
|
|
||||||
// If the interpreter is operating in readonly mode, make sure no
|
|
||||||
// state-modifying operation is performed. The 3rd stack item
|
|
||||||
// for a call operation is the value. Transferring value from one
|
|
||||||
// account to the others means the state is modified and should also
|
|
||||||
// return with an error.
|
|
||||||
if operation.writes || (op == CALL && stack.Back(2).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 occurred.
|
// the return byte-slice and an error if one occurred.
|
||||||
//
|
//
|
||||||
|
|
@ -217,12 +201,24 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||||
if !operation.valid {
|
if !operation.valid {
|
||||||
return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
|
return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
|
||||||
}
|
}
|
||||||
if err = operation.validateStack(stack); err != nil {
|
// Validate stack
|
||||||
return nil, err
|
if sLen := stack.len(); sLen < operation.minStack{
|
||||||
|
return nil, fmt.Errorf("stack underflow (%d <=> %d)", sLen, operation.minStack)
|
||||||
|
}else{
|
||||||
|
if sLen > operation.maxStack{
|
||||||
|
return nil, fmt.Errorf("stack limit reached %d (%d)", sLen, operation.maxStack)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If the operation is valid, enforce and write restrictions
|
// If the operation is valid, enforce and write restrictions
|
||||||
if err = in.enforceRestrictions(op, operation, stack); err != nil {
|
if in.readOnly && in.evm.chainRules.IsByzantium {
|
||||||
return nil, err
|
// If the interpreter is operating in readonly mode, make sure no
|
||||||
|
// state-modifying operation is performed. The 3rd stack item
|
||||||
|
// for a call operation is the value. Transferring value from one
|
||||||
|
// account to the others means the state is modified and should also
|
||||||
|
// return with an error.
|
||||||
|
if operation.writes || (op == CALL && stack.Back(2).BitLen() > 0) {
|
||||||
|
return nil, errWriteProtection
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var memorySize uint64
|
var memorySize uint64
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -17,28 +17,26 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeStackFunc(pop, push int) stackValidationFunc {
|
func minSwapStack(n int) int {
|
||||||
return func(stack *Stack) error {
|
return minStack(n, n)
|
||||||
if err := stack.require(pop); err != nil {
|
}
|
||||||
return err
|
func maxSwapStack(n int) int {
|
||||||
}
|
return maxStack(n, n)
|
||||||
|
|
||||||
if stack.len()+push-pop > int(params.StackLimit) {
|
|
||||||
return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeDupStackFunc(n int) stackValidationFunc {
|
func minDupStack(n int) int {
|
||||||
return makeStackFunc(n, n+1)
|
return minStack(n, n+1)
|
||||||
|
}
|
||||||
|
func maxDupStack(n int) int {
|
||||||
|
return maxStack(n, n+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSwapStackFunc(n int) stackValidationFunc {
|
func maxStack(pop, push int) int {
|
||||||
return makeStackFunc(n, n)
|
return int(params.StackLimit) + pop - push
|
||||||
|
}
|
||||||
|
func minStack(pops, push int) int {
|
||||||
|
return pops
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue