Merge branch 'firehose-fh3.0-backport-1.13.5' into firehose-fh3.0

# Conflicts:
#	accounts/abi/bind/backends/simulated.go
#	cmd/evm/internal/t8ntool/execution.go
#	cmd/evm/internal/t8ntool/flags.go
#	cmd/evm/internal/t8ntool/transition.go
#	cmd/geth/snapshot.go
#	consensus/beacon/consensus.go
#	consensus/ethash/consensus.go
#	consensus/misc/dao.go
#	core/blockchain.go
#	core/chain_makers.go
#	core/evm.go
#	core/genesis.go
#	core/genesis_test.go
#	core/state/dump.go
#	core/state/state_object.go
#	core/state/state_test.go
#	core/state/statedb.go
#	core/state/statedb_fuzz_test.go
#	core/state/statedb_test.go
#	core/state/sync_test.go
#	core/state/trie_prefetcher_test.go
#	core/state_transition.go
#	core/tracing/hooks.go
#	core/txpool/blobpool/blobpool_test.go
#	core/txpool/legacypool/legacypool2_test.go
#	core/txpool/legacypool/legacypool_test.go
#	core/types/account.go
#	core/vm/errors.go
#	core/vm/evm.go
#	core/vm/instructions.go
#	core/vm/interface.go
#	core/vm/interpreter.go
#	eth/api_debug_test.go
#	eth/tracers/api.go
#	eth/tracers/directory/util_test.go
#	eth/tracers/firehose.go
#	eth/tracers/internal/tracetest/calltrace_test.go
#	eth/tracers/internal/tracetest/flat_calltrace_test.go
#	eth/tracers/internal/tracetest/prestate_test.go
#	eth/tracers/js/goja.go
#	eth/tracers/js/tracer_test.go
#	eth/tracers/logger/logger.go
#	eth/tracers/logger/logger_test.go
#	eth/tracers/native/call_flat.go
#	eth/tracers/native/prestate.go
#	eth/tracers/tracers_test.go
#	go.mod
#	internal/ethapi/api.go
#	light/odr_test.go
#	miner/worker.go
#	params/version.go
#	tests/block_test_util.go
#	tests/state_test_util.go
This commit is contained in:
Matthieu Vachon 2024-03-15 12:48:29 -04:00
commit b1d1d36dc4

View file

@ -35,7 +35,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)
var firehoseTracerLogLevel = strings.ToLower(os.Getenv("GETH_FIREHOSE_TRACER_LOG_LEVEL"))
var firehoseTracerLogLevel = strings.ToLower(os.Getenv("FIREHOSE_ETHEREUM_TRACER_LOG_LEVEL"))
var isFirehoseDebugEnabled = firehoseTracerLogLevel == "debug" || firehoseTracerLogLevel == "trace"
var isFirehoseTracerEnabled = firehoseTracerLogLevel == "trace"
@ -80,7 +80,8 @@ func newFirehoseTracer(cfg json.RawMessage) (*tracing.Hooks, error) {
OnStorageChange: tracer.OnStorageChange,
OnGasChange: tracer.OnGasChange,
OnLog: tracer.OnLog,
OnNewAccount: tracer.OnNewAccount,
OnNewAccount: tracer.OnNewAccount,
}, nil
}
@ -522,23 +523,41 @@ func (f *Firehose) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.
}
if opCode == vm.KECCAK256 {
f.onOpcodeSha3(activeCall, scope.StackData(), Memory(scope.MemoryData()))
f.onOpcodeKeccak256(activeCall, scope.StackData(), Memory(scope.MemoryData()))
}
}
}
type Memory []byte
func (m Memory) GetPtr(offset, size int64) []byte {
if size == 0 {
return nil
// onOpcodeKeccak256 is called during the SHA3 (a.k.a KECCAK256) opcode it's known
// in Firehose tracer as Keccak preimages. The preimage is the input data that
// was used to produce the given keccak hash.
func (f *Firehose) onOpcodeKeccak256(call *pbeth.Call, stack []uint256.Int, memory Memory) {
if call.KeccakPreimages == nil {
call.KeccakPreimages = make(map[string]string)
}
if len(m) > int(offset) {
return m[offset : offset+size]
offset, size := stack[len(stack)-1], stack[len(stack)-2]
preImage := memory.GetPtrUint256(&offset, &size)
// We should have exclusive access to the hasher, we can safely reset it.
f.hasher.Reset()
f.hasher.Write(preImage)
f.hasher.Read(f.hasherBuf[:])
// Known Firehose issue: It appears the old Firehose instrumentation have a bug
// where when the keccak256 preimage is empty, it is written as "." which is
// completely wrong.
//
// To keep the same behavior, we will write the preimage as a "." when the encoded
// data is an empty string.
//
// For new chain, this code should be remove so that we just keep `hex.EncodeToString(data)`.
encodedData := hex.EncodeToString(preImage)
if encodedData == "" {
encodedData = "."
}
return nil
call.KeccakPreimages[hex.EncodeToString(f.hasherBuf[:])] = encodedData
}
var opCodeToGasChangeReasonMap = map[vm.OpCode]pbeth.GasChange_Reason{
@ -562,38 +581,6 @@ var opCodeToGasChangeReasonMap = map[vm.OpCode]pbeth.GasChange_Reason{
vm.RETURNDATACOPY: pbeth.GasChange_REASON_RETURN_DATA_COPY,
}
// onOpcodeSha3 is called during the SHA3 (a.k.a KECCAK256) opcode it's known
// in Firehose tracer as Keccak preimages. The preimage is the input data that
// was used to produce the given keccak hash.
func (f *Firehose) onOpcodeSha3(call *pbeth.Call, stack []uint256.Int, memory Memory) {
if call.KeccakPreimages == nil {
call.KeccakPreimages = make(map[string]string)
}
offset, size := stack[0], stack[1]
preImage := memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
// We should have exclusive access to the hasher, we can safely reset it.
f.hasher.Reset()
f.hasher.Write(preImage)
f.hasher.Read(f.hasherBuf[:])
// Known Firehose issue: It appears the old Firehose instrumentation have a bug
// where when the keccak256 preimage is empty, it is written as "." which is
// completely wrong.
//
// To keep the same behavior, we will write the preimage as a "." when the encoded
// data is an empty string.
//
// For new chain, this code should be remove so that we just keep `hex.EncodeToString(data)`.
encodedData := hex.EncodeToString(preImage)
if encodedData == "" {
encodedData = "."
}
call.KeccakPreimages[hex.EncodeToString(f.hasherBuf[:])] = encodedData
}
// OnOpcodeFault implements the EVMLogger interface to trace an execution fault.
func (f *Firehose) OnOpcodeFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) {
if activeCall := f.callStack.Peek(); activeCall != nil {
@ -675,13 +662,13 @@ func (f *Firehose) getExecutedCode(evm *tracing.VMContext, call *pbeth.Call) boo
if !evm.StateDB.Exist(common.BytesToAddress(call.Address)) &&
!precompile && f.blockRules.IsEIP158 &&
(call.Value == nil || call.Value.Native().Sign() == 0) {
firehoseDebug("executed code IsSpuriousDragon callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
firehoseDebug("executed code IsSpuriousDragon callType=%s inputLength=%d", call.CallType.String(), len(call.Input))
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
}
}
if precompile {
firehoseDebug("executed code isprecompile callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
firehoseDebug("executed code isprecompile callType=%s inputLength=%d", call.CallType.String(), len(call.Input))
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
}
@ -691,7 +678,7 @@ func (f *Firehose) getExecutedCode(evm *tracing.VMContext, call *pbeth.Call) boo
return false
}
firehoseDebug("executed code default callTyp=%s inputLength=%d", call.CallType.String(), len(call.Input) > 0)
firehoseDebug("executed code default callType=%s inputLength=%d", call.CallType.String(), len(call.Input))
return call.CallType != pbeth.CallType_CREATE && len(call.Input) > 0
}
@ -1973,3 +1960,21 @@ func validateField[T any](into *validationResult, field string, a, b T, equal bo
func ptr[T any](t T) *T {
return &t
}
type Memory []byte
func (m Memory) GetPtrUint256(offset, size *uint256.Int) []byte {
return m.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
}
func (m Memory) GetPtr(offset, size int64) []byte {
if size == 0 {
return nil
}
if len(m) > int(offset) {
return m[offset : offset+size]
}
return nil
}