mirror of
https://github.com/luxfi/geth.git
synced 2026-10-30 15:05:39 +00:00
- Format 137 Go files with gofmt - Add CGO_ENABLED=0 to test step (accel C headers unavailable in CI) - Remove -race flag (incompatible with CGO_ENABLED=0)
87 lines
3.0 KiB
Go
87 lines
3.0 KiB
Go
package native
|
|
|
|
// Copyright 2021 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/luxfi/crypto"
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/luxfi/geth/common/hexutil"
|
|
"github.com/luxfi/geth/core/tracing"
|
|
"github.com/luxfi/geth/core/vm"
|
|
"github.com/luxfi/geth/eth/tracers"
|
|
"github.com/luxfi/geth/eth/tracers/internal"
|
|
"github.com/luxfi/geth/params"
|
|
log "github.com/luxfi/log"
|
|
)
|
|
|
|
func init() {
|
|
tracers.DefaultDirectory.Register("keccak256PreimageTracer", newKeccak256PreimageTracer, false)
|
|
}
|
|
|
|
// keccak256PreimageTracer is a native tracer that collects preimages of all KECCAK256 operations.
|
|
// This tracer is particularly useful for analyzing smart contract execution patterns,
|
|
// especially when debugging storage access in Solidity mappings and dynamic arrays.
|
|
type keccak256PreimageTracer struct {
|
|
computedHashes map[common.Hash]hexutil.Bytes
|
|
}
|
|
|
|
// newKeccak256PreimageTracer returns a new keccak256PreimageTracer instance.
|
|
func newKeccak256PreimageTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
|
|
t := &keccak256PreimageTracer{
|
|
computedHashes: make(map[common.Hash]hexutil.Bytes),
|
|
}
|
|
return &tracers.Tracer{
|
|
Hooks: &tracing.Hooks{
|
|
OnOpcode: t.OnOpcode,
|
|
},
|
|
GetResult: t.GetResult,
|
|
}, nil
|
|
}
|
|
|
|
func (t *keccak256PreimageTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
|
|
if op == byte(vm.KECCAK256) {
|
|
sd := scope.StackData()
|
|
// it turns out that sometimes the stack is empty, evm will fail in this case, but we should not panic here
|
|
if len(sd) < 2 {
|
|
return
|
|
}
|
|
|
|
dataOffset := internal.StackBack(sd, 0).Uint64()
|
|
dataLength := internal.StackBack(sd, 1).Uint64()
|
|
preimage, err := internal.GetMemoryCopyPadded(scope.MemoryData(), int64(dataOffset), int64(dataLength))
|
|
if err != nil {
|
|
log.Warn("keccak256PreimageTracer: failed to copy keccak preimage from memory", "err", err)
|
|
return
|
|
}
|
|
|
|
hash := crypto.Keccak256(preimage)
|
|
|
|
t.computedHashes[common.Hash(hash)] = hexutil.Bytes(preimage)
|
|
}
|
|
}
|
|
|
|
// GetResult returns the collected keccak256 preimages as a JSON object mapping hashes to preimages.
|
|
func (t *keccak256PreimageTracer) GetResult() (json.RawMessage, error) {
|
|
msg, err := json.Marshal(t.computedHashes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return msg, nil
|
|
}
|