Skip to content

Commit

Permalink
Merge branch 'mempool-feed-stage' into merge/v1.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ayazabbas authored Jul 6, 2023
2 parents 3f93ed3 + 778a80c commit 76ed697
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 257 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v2
- name: Build geth
run: |
cd cmd/geth && /opt/go/1.18.1/bin/go build
cd cmd/geth && /opt/go/1.19.5/bin/go build
tar -czvf geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz geth
echo $(md5sum geth | awk '{print $1}') > geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz.md5
- name: Upload geth to release page
Expand Down
242 changes: 1 addition & 241 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
package core

import (
"fmt"
"encoding/json"
"fmt"
"math/big"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
Expand All @@ -34,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
)

// StateProcessor is a basic Processor, which takes care of transitioning
Expand Down Expand Up @@ -224,7 +221,6 @@ func ApplyTransactionWithResult(config *params.ChainConfig, bc ChainContext, aut
}

func ApplyUnsignedTransactionWithResult(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, msg *Message, usedGas *uint64, cfg vm.Config) (*types.Receipt, *ExecutionResult, interface{}, error) {
// Create call tracer to get JSON stack traces
tracer, err := blocknative.NewTxnOpCodeTracer(nil)
if err != nil {
return nil, nil, nil, err
Expand All @@ -236,242 +232,6 @@ func ApplyUnsignedTransactionWithResult(config *params.ChainConfig, bc ChainCont
return applyTransactionWithResult(msg, config, bc, author, gp, statedb, header, msg, usedGas, vmenv, tracer)
}

// StructLogRes stores a structured log emitted by the EVM while replaying a
// transaction in debug mode
type StructLogRes struct {
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Depth int `json:"depth"`
Error string `json:"error,omitempty"`
Stack *[]string `json:"stack,omitempty"`
Memory *[]string `json:"memory,omitempty"`
Storage *map[string]string `json:"storage,omitempty"`
}

// FormatLogs formats EVM returned structured logs for json output
func FormatLogs(logs []logger.StructLog) []StructLogRes {
formatted := make([]StructLogRes, len(logs))
for index, trace := range logs {
formatted[index] = StructLogRes{
Pc: trace.Pc,
Op: trace.Op.String(),
Gas: trace.Gas,
GasCost: trace.GasCost,
Depth: trace.Depth,
Error: trace.ErrorString(),
}
if trace.Stack != nil {
stack := make([]string, len(trace.Stack))
for i, stackValue := range trace.Stack {
stack[i] = stackValue.Hex()
}
formatted[index].Stack = &stack
}
if trace.Memory != nil {
memory := make([]string, 0, (len(trace.Memory)+31)/32)
for i := 0; i+32 <= len(trace.Memory); i += 32 {
memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32]))
}
formatted[index].Memory = &memory
}
if trace.Storage != nil {
storage := make(map[string]string)
for i, storageValue := range trace.Storage {
storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue)
}
formatted[index].Storage = &storage
}
}
return formatted
}

type call struct {
Type string `json:"type"`
From common.Address `json:"from"`
To common.Address `json:"to"`
Value *hexutil.Big `json:"value,omitempty"`
Gas hexutil.Uint64 `json:"gas"`
GasUsed hexutil.Uint64 `json:"gasUsed"`
Input hexutil.Bytes `json:"input"`
Output hexutil.Bytes `json:"output"`
Time string `json:"time,omitempty"`
Calls []*call `json:"calls,omitempty"`
Error string `json:"error,omitempty"`
startTime time.Time
outOff uint64
outLen uint64
gasIn uint64
gasCost uint64
}

type TracerResult interface {
vm.EVMLogger
GetResult() (json.RawMessage, error)
}

type CallTracer struct {
callStack []*call
descended bool
statedb *state.StateDB
}

func NewCallTracer(statedb *state.StateDB) TracerResult {
return &CallTracer{
callStack: []*call{},
descended: false,
statedb: statedb,
}
}

func (tracer *CallTracer) i() int {
return len(tracer.callStack) - 1
}

func (tracer *CallTracer) GetResult() (json.RawMessage, error) {
res, err := json.Marshal(tracer.callStack[0])
return json.RawMessage(res), err
}

func (tracer *CallTracer) CaptureStart(evm *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
hvalue := hexutil.Big(*value)
tracer.callStack = []*call{&call{
From: from,
To: to,
Value: &hvalue,
Gas: hexutil.Uint64(gas),
Input: hexutil.Bytes(input),
Calls: []*call{},
}}
}
func (tracer *CallTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
tracer.callStack[tracer.i()].GasUsed = hexutil.Uint64(gasUsed)
// tracer.callStack[tracer.i()].Time = fmt.Sprintf("%v", t)
tracer.callStack[tracer.i()].Output = hexutil.Bytes(output)
}

func (tracer *CallTracer) descend(newCall *call) {
tracer.callStack[tracer.i()].Calls = append(tracer.callStack[tracer.i()].Calls, newCall)
tracer.callStack = append(tracer.callStack, newCall)
tracer.descended = true
}

func toAddress(value *uint256.Int) common.Address {
return common.BytesToAddress(value.Bytes())
}

func (tracer *CallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
// for depth < len(tracer.callStack) {
// c := tracer.callStack[tracer.i()]
// c.GasUsed = c.Gas - gas
// tracer.callStack = tracer.callStack[:tracer.i()]
// }
defer func() {
if r := recover(); r != nil {
tracer.callStack[tracer.i()].Error = "internal failure"
log.Warn("Panic during trace. Recovered.", "err", r)
}
}()
if op == vm.CREATE || op == vm.CREATE2 {
inOff := scope.Stack.Back(1).Uint64()
inLen := scope.Stack.Back(2).Uint64()
hvalue := hexutil.Big(*scope.Contract.Value())
tracer.descend(&call{
Type: op.String(),
From: scope.Contract.Caller(),
Input: scope.Memory.GetCopy(int64(inOff), int64(inLen)),
gasIn: gas,
gasCost: cost,
Value: &hvalue,
startTime: time.Now(),
})
return
}
if op == vm.SELFDESTRUCT {
hvalue := hexutil.Big(*tracer.statedb.GetBalance(scope.Contract.Caller()))
tracer.descend(&call{
Type: op.String(),
From: scope.Contract.Caller(),
To: toAddress(scope.Stack.Back(0)),
// TODO: Is this input correct?
Input: scope.Contract.Input,
Value: &hvalue,
gasIn: gas,
gasCost: cost,
startTime: time.Now(),
})
return
}
if op == vm.CALL || op == vm.CALLCODE || op == vm.DELEGATECALL || op == vm.STATICCALL {
toAddress := toAddress(scope.Stack.Back(1))
if _, isPrecompile := vm.PrecompiledContractsIstanbul[toAddress]; isPrecompile {
return
}
off := 1
if op == vm.DELEGATECALL || op == vm.STATICCALL {
off = 0
}
inOff := scope.Stack.Back(2 + off).Uint64()
inLength := scope.Stack.Back(3 + off).Uint64()
newCall := &call{
Type: op.String(),
From: scope.Contract.Address(),
To: toAddress,
Input: scope.Memory.GetCopy(int64(inOff), int64(inLength)),
gasIn: gas,
gasCost: cost,
outOff: scope.Stack.Back(4 + off).Uint64(),
outLen: scope.Stack.Back(5 + off).Uint64(),
startTime: time.Now(),
}
if off == 1 {
value := hexutil.Big(*new(big.Int).SetBytes(scope.Stack.Back(2).Bytes()))
newCall.Value = &value
}
tracer.descend(newCall)
return
}
if tracer.descended {
if depth >= len(tracer.callStack) {
tracer.callStack[tracer.i()].Gas = hexutil.Uint64(gas)
}
tracer.descended = false
}
if op == vm.REVERT {
tracer.callStack[tracer.i()].Error = "execution reverted"
return
}
if depth == len(tracer.callStack)-1 {
c := tracer.callStack[tracer.i()]
// c.Time = fmt.Sprintf("%v", time.Since(c.startTime))
tracer.callStack = tracer.callStack[:len(tracer.callStack)-1]
if vm.StringToOp(c.Type) == vm.CREATE || vm.StringToOp(c.Type) == vm.CREATE2 {
c.GasUsed = hexutil.Uint64(c.gasIn - c.gasCost - gas)
ret := scope.Stack.Back(0)
if ret.Uint64() != 0 {
c.To = common.BytesToAddress(ret.Bytes())
c.Output = tracer.statedb.GetCode(c.To)
} else if c.Error == "" {
c.Error = "internal failure"
}
} else {
c.GasUsed = hexutil.Uint64(c.gasIn - c.gasCost + uint64(c.Gas) - gas)
ret := scope.Stack.Back(0)
if ret.Uint64() != 0 {
c.Output = hexutil.Bytes(scope.Memory.GetCopy(int64(c.outOff), int64(c.outLen)))
} else if c.Error == "" {
c.Error = "internal failure"
}
}
}
return
}
func (tracer *CallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.ScopeContext, depth int, err error) {
}
func (tracer *CallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
}
func (tracer *CallTracer) CaptureExit(output []byte, gasUsed uint64, err error) {}
func (tracer *CallTracer) CaptureTxEnd(restGas uint64) {}
func (tracer *CallTracer) CaptureTxStart(gasLimit uint64) {}
func (tracer *CallTracer) Stop(err error) {}
4 changes: 1 addition & 3 deletions eth/tracers/blocknative/blocknative.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package blocknative
import (
"encoding/json"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
Expand All @@ -21,8 +20,7 @@ type Tracer interface {
Stop(err error)
}

// TracerOpts configure the tracer to save or ignore various aspects of a
// transaction execution.
// TracerOpts configure the tracer to save or ignore various aspects of a transaction execution.
type TracerOpts struct {
Logs bool `json:"logs"`
}
Expand Down
6 changes: 5 additions & 1 deletion eth/tracers/blocknative/txnOpCodeTracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type txnOpCodeTracer struct {
interrupt uint32 // Atomic flag to signal execution interruption
reason error // Textual reason for the interruption (not always specific for us)
opts TracerOpts
beginTime time.Time // Time object for start of trace for stats
}

// NewTxnOpCodeTracer returns a new txnOpCodeTracer tracer with the given
Expand Down Expand Up @@ -77,11 +78,14 @@ func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to comm
// Populate the block context from the vm environment.
t.trace.BlockContext.Number = env.Context.BlockNumber.Uint64()
t.trace.BlockContext.BaseFee = env.Context.BaseFee.Uint64()
t.trace.BlockContext.Time = env.Context.Time // todo alex: check this removal -> .Uint64()
t.trace.BlockContext.Time = env.Context.Time
t.trace.BlockContext.Coinbase = addrToHex(env.Context.Coinbase)
t.trace.BlockContext.GasLimit = env.Context.GasLimit
t.trace.BlockContext.Random = random

// Start tracing timer
t.beginTime = time.Now()

// This is the initial call
t.callStack[0] = CallFrame{
Type: "CALL",
Expand Down
26 changes: 15 additions & 11 deletions eth/tracers/internal/tracetest/txnOpCodeTracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ package tracetest

import (
"encoding/json"
"fmt"
"math/big"
"os"
"path/filepath"
"reflect"
"strings"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
Expand All @@ -12,12 +18,6 @@ import (
"github.com/ethereum/go-ethereum/eth/tracers/blocknative"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/tests"
"math/big"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
)

type txnOpCodeTracerTest struct {
Expand Down Expand Up @@ -108,11 +108,15 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) {
}

if !tracesEqual(ret, test.Result) {
x, _ := json.MarshalIndent(test.Result, "", "")
//y, _ := json.MarshalIndent(test.Result, "", "")
fmt.Println(string(x))
// Below are prints to show differences if we fail, can always just check against the specific test json files too!
// x, _ := json.MarshalIndent(ret, "", "")
// y, _ := json.MarshalIndent(test.Result, "", "")
// fmt.Println("ret")
// fmt.Println(string(x))
// fmt.Println("test.Result")
// fmt.Println(string(y))
t.Fatal("traces mismatch")
//t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result)
// t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result)
}
})
}
Expand Down

0 comments on commit 76ed697

Please sign in to comment.