Merge tag 'v1.10.13' into HEAD

This commit is contained in:
Austin Roberts
2021-11-29 10:16:31 -06:00
137 changed files with 3214 additions and 1774 deletions
+2 -2
View File
@@ -141,7 +141,7 @@ func (a *AccessListTracer) CaptureStart(env *EVM, from common.Address, to common
}
// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist.
func (a *AccessListTracer) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
func (a *AccessListTracer) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
stack := scope.Stack
if (op == SLOAD || op == SSTORE) && stack.len() >= 1 {
slot := common.Hash(stack.data[stack.len()-1].Bytes32())
@@ -161,7 +161,7 @@ func (a *AccessListTracer) CaptureState(env *EVM, pc uint64, op OpCode, gas, cos
}
}
func (*AccessListTracer) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
func (*AccessListTracer) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
}
func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}
+1
View File
@@ -35,6 +35,7 @@ var (
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
ErrGasUintOverflow = errors.New("gas uint64 overflow")
ErrInvalidCode = errors.New("invalid code: must not begin with 0xef")
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
)
// ErrStackUnderflow wraps an evm error when the items on the stack less
+3
View File
@@ -424,6 +424,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
return nil, common.Address{}, gas, ErrInsufficientBalance
}
nonce := evm.StateDB.GetNonce(caller.Address())
if nonce+1 < nonce {
return nil, common.Address{}, gas, ErrNonceUintOverflow
}
evm.StateDB.SetNonce(caller.Address(), nonce+1)
// We add this to the access list _before_ taking a snapshot. Even if the creation fails,
// the access-list change should not be rolled back
+3 -3
View File
@@ -169,9 +169,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
defer func() {
if err != nil {
if !logged {
in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
in.cfg.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
} else {
in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err)
in.cfg.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err)
}
}
}()
@@ -253,7 +253,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
if in.cfg.Debug {
in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
in.cfg.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
logged = true
}
+14 -10
View File
@@ -105,10 +105,10 @@ func (s *StructLog) ErrorString() string {
// if you need to retain them beyond the current call.
type EVMLogger interface {
CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int)
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
CaptureExit(output []byte, gasUsed uint64, err error)
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error)
CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error)
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error)
}
@@ -119,6 +119,7 @@ type EVMLogger interface {
// contract their storage.
type StructLogger struct {
cfg LogConfig
env *EVM
storage map[common.Address]Storage
logs []StructLog
@@ -147,12 +148,13 @@ func (l *StructLogger) Reset() {
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
l.env = env
}
// CaptureState logs a new structured log message and pushes it out to the environment
//
// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
memory := scope.Memory
stack := scope.Stack
contract := scope.Contract
@@ -186,7 +188,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
if op == SLOAD && stack.len() >= 1 {
var (
address = common.Hash(stack.data[stack.len()-1].Bytes32())
value = env.StateDB.GetState(contract.Address(), address)
value = l.env.StateDB.GetState(contract.Address(), address)
)
l.storage[contract.Address()][address] = value
storage = l.storage[contract.Address()].Copy()
@@ -206,13 +208,13 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
copy(rdata, rData)
}
// create a new snapshot of the EVM.
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, env.StateDB.GetRefund(), err}
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
l.logs = append(l.logs, log)
}
// CaptureFault implements the EVMLogger interface to trace an execution fault
// while running an opcode.
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
func (l *StructLogger) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
}
// CaptureEnd is called after the call finishes to finalize the tracing.
@@ -291,12 +293,13 @@ func WriteLogs(writer io.Writer, logs []*types.Log) {
type mdLogger struct {
out io.Writer
cfg *LogConfig
env *EVM
}
// NewMarkdownLogger creates a logger which outputs information in a format adapted
// for human readability, and is also a valid markdown table
func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
l := &mdLogger{writer, cfg}
l := &mdLogger{out: writer, cfg: cfg}
if l.cfg == nil {
l.cfg = &LogConfig{}
}
@@ -304,6 +307,7 @@ func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
}
func (t *mdLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
t.env = env
if !create {
fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `0x%x`\nGas: `%d`\nValue `%v` wei\n",
from.String(), to.String(),
@@ -321,7 +325,7 @@ func (t *mdLogger) CaptureStart(env *EVM, from common.Address, to common.Address
}
// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
func (t *mdLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
stack := scope.Stack
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)
@@ -334,14 +338,14 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
fmt.Fprintf(t.out, "%10v |", b)
}
fmt.Fprintf(t.out, "%10v |", env.StateDB.GetRefund())
fmt.Fprintf(t.out, "%10v |", t.env.StateDB.GetRefund())
fmt.Fprintln(t.out, "")
if err != nil {
fmt.Fprintf(t.out, "Error: %v\n", err)
}
}
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
func (t *mdLogger) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) {
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
}
+6 -4
View File
@@ -29,12 +29,13 @@ import (
type JSONLogger struct {
encoder *json.Encoder
cfg *LogConfig
env *EVM
}
// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects
// into the provided stream.
func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger {
l := &JSONLogger{json.NewEncoder(writer), cfg}
l := &JSONLogger{encoder: json.NewEncoder(writer), cfg: cfg}
if l.cfg == nil {
l.cfg = &LogConfig{}
}
@@ -42,12 +43,13 @@ func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger {
}
func (l *JSONLogger) CaptureStart(env *EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
l.env = env
}
func (l *JSONLogger) CaptureFault(*EVM, uint64, OpCode, uint64, uint64, *ScopeContext, int, error) {}
func (l *JSONLogger) CaptureFault(uint64, OpCode, uint64, uint64, *ScopeContext, int, error) {}
// CaptureState outputs state information on the logger.
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
func (l *JSONLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
memory := scope.Memory
stack := scope.Stack
@@ -58,7 +60,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
GasCost: cost,
MemorySize: memory.Len(),
Depth: depth,
RefundCounter: env.StateDB.GetRefund(),
RefundCounter: l.env.StateDB.GetRefund(),
Err: err,
}
if l.cfg.EnableMemory {
+2 -1
View File
@@ -62,7 +62,8 @@ func TestStoreCapture(t *testing.T) {
scope.Stack.push(uint256.NewInt(1))
scope.Stack.push(new(uint256.Int))
var index common.Hash
logger.CaptureState(env, 0, SSTORE, 0, 0, scope, nil, 0, nil)
logger.CaptureStart(env, common.Address{}, contract.Address(), false, nil, 0, nil)
logger.CaptureState(0, SSTORE, 0, 0, scope, nil, 0, nil)
if len(logger.storage[contract.Address()]) == 0 {
t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(),
len(logger.storage[contract.Address()]))
+66 -57
View File
@@ -39,68 +39,68 @@ func (op OpCode) IsStaticJump() bool {
// 0x0 range - arithmetic ops.
const (
STOP OpCode = iota
ADD
MUL
SUB
DIV
SDIV
MOD
SMOD
ADDMOD
MULMOD
EXP
SIGNEXTEND
STOP OpCode = 0x0
ADD OpCode = 0x1
MUL OpCode = 0x2
SUB OpCode = 0x3
DIV OpCode = 0x4
SDIV OpCode = 0x5
MOD OpCode = 0x6
SMOD OpCode = 0x7
ADDMOD OpCode = 0x8
MULMOD OpCode = 0x9
EXP OpCode = 0xa
SIGNEXTEND OpCode = 0xb
)
// 0x10 range - comparison ops.
const (
LT OpCode = iota + 0x10
GT
SLT
SGT
EQ
ISZERO
AND
OR
XOR
NOT
BYTE
SHL
SHR
SAR
LT OpCode = 0x10
GT OpCode = 0x11
SLT OpCode = 0x12
SGT OpCode = 0x13
EQ OpCode = 0x14
ISZERO OpCode = 0x15
AND OpCode = 0x16
OR OpCode = 0x17
XOR OpCode = 0x18
NOT OpCode = 0x19
BYTE OpCode = 0x1a
SHL OpCode = 0x1b
SHR OpCode = 0x1c
SAR OpCode = 0x1d
SHA3 OpCode = 0x20
)
// 0x30 range - closure state.
const (
ADDRESS OpCode = 0x30 + iota
BALANCE
ORIGIN
CALLER
CALLVALUE
CALLDATALOAD
CALLDATASIZE
CALLDATACOPY
CODESIZE
CODECOPY
GASPRICE
EXTCODESIZE
EXTCODECOPY
RETURNDATASIZE
RETURNDATACOPY
EXTCODEHASH
ADDRESS OpCode = 0x30
BALANCE OpCode = 0x31
ORIGIN OpCode = 0x32
CALLER OpCode = 0x33
CALLVALUE OpCode = 0x34
CALLDATALOAD OpCode = 0x35
CALLDATASIZE OpCode = 0x36
CALLDATACOPY OpCode = 0x37
CODESIZE OpCode = 0x38
CODECOPY OpCode = 0x39
GASPRICE OpCode = 0x3a
EXTCODESIZE OpCode = 0x3b
EXTCODECOPY OpCode = 0x3c
RETURNDATASIZE OpCode = 0x3d
RETURNDATACOPY OpCode = 0x3e
EXTCODEHASH OpCode = 0x3f
)
// 0x40 range - block operations.
const (
BLOCKHASH OpCode = 0x40 + iota
COINBASE
TIMESTAMP
NUMBER
DIFFICULTY
GASLIMIT
BLOCKHASH OpCode = 0x40
COINBASE OpCode = 0x41
TIMESTAMP OpCode = 0x42
NUMBER OpCode = 0x43
DIFFICULTY OpCode = 0x44
GASLIMIT OpCode = 0x45
CHAINID OpCode = 0x46
SELFBALANCE OpCode = 0x47
BASEFEE OpCode = 0x48
@@ -122,7 +122,7 @@ const (
JUMPDEST OpCode = 0x5b
)
// 0x60 range.
// 0x60 range - pushes.
const (
PUSH1 OpCode = 0x60 + iota
PUSH2
@@ -156,7 +156,11 @@ const (
PUSH30
PUSH31
PUSH32
DUP1
)
// 0x80 range - dups.
const (
DUP1 = 0x80 + iota
DUP2
DUP3
DUP4
@@ -172,7 +176,11 @@ const (
DUP14
DUP15
DUP16
SWAP1
)
// 0x90 range - swaps.
const (
SWAP1 = 0x90 + iota
SWAP2
SWAP3
SWAP4
@@ -208,12 +216,13 @@ const (
// 0xf0 range - closures.
const (
CREATE OpCode = 0xf0 + iota
CALL
CALLCODE
RETURN
DELEGATECALL
CREATE2
CREATE OpCode = 0xf0
CALL OpCode = 0xf1
CALLCODE OpCode = 0xf2
RETURN OpCode = 0xf3
DELEGATECALL OpCode = 0xf4
CREATE2 OpCode = 0xf5
STATICCALL OpCode = 0xfa
REVERT OpCode = 0xfd
SELFDESTRUCT OpCode = 0xff
+6 -3
View File
@@ -35,6 +35,9 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/params"
// force-load js tracers to trigger registration
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
)
func TestDefaults(t *testing.T) {
@@ -330,12 +333,12 @@ type stepCounter struct {
func (s *stepCounter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
}
func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (s *stepCounter) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
}
func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}
func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (s *stepCounter) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
s.steps++
// Enable this for more output
//s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err)
@@ -511,7 +514,7 @@ func BenchmarkSimpleLoop(b *testing.B) {
// TestEip2929Cases contains various testcases that are used for
// EIP-2929 about gas repricings
func TestEip2929Cases(t *testing.T) {
t.Skip("Test only useful for generating documentation")
id := 1
prettyPrint := func(comment string, code []byte) {