eth/tracers: package restructuring (#23857)
* eth/tracers: restructure tracer package * core/vm/runtime: load js tracers * eth/tracers: mv bigint js code to own file * eth/tracers: add method docs for native tracers * eth/tracers: minor doc fix * core,eth: cancel evm on nativecalltracer stop * core/vm: fix failing test Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9489853321
commit
6b9c77f060
@ -14,18 +14,25 @@
|
||||
// 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/>.
|
||||
|
||||
// Package tracers is a collection of JavaScript transaction tracers.
|
||||
// Package tracers is a manager for transaction tracing engines.
|
||||
package tracers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"unicode"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers/internal/tracers"
|
||||
)
|
||||
|
||||
// Context contains some contextual infos for a transaction execution that is not
|
||||
// available from within the EVM object.
|
||||
type Context struct {
|
||||
BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call)
|
||||
TxIndex int // Index of the transaction within a block (zero if dangling tx or call)
|
||||
TxHash common.Hash // Hash of the transaction being traced (zero if dangling call)
|
||||
}
|
||||
|
||||
// Tracer interface extends vm.EVMLogger and additionally
|
||||
// allows collecting the tracing result.
|
||||
type Tracer interface {
|
||||
@ -35,50 +42,31 @@ type Tracer interface {
|
||||
Stop(err error)
|
||||
}
|
||||
|
||||
type lookupFunc func(string, *Context) (Tracer, error)
|
||||
|
||||
var (
|
||||
nativeTracers map[string]func() Tracer = make(map[string]func() Tracer)
|
||||
jsTracers = make(map[string]string)
|
||||
lookups []lookupFunc
|
||||
)
|
||||
|
||||
// RegisterNativeTracer makes native tracers which adhere
|
||||
// to the `Tracer` interface available to the rest of the codebase.
|
||||
// It is typically invoked in the `init()` function, e.g. see the `native/call.go`.
|
||||
func RegisterNativeTracer(name string, ctor func() Tracer) {
|
||||
nativeTracers[name] = ctor
|
||||
// RegisterLookup registers a method as a lookup for tracers, meaning that
|
||||
// users can invoke a named tracer through that lookup. If 'wildcard' is true,
|
||||
// then the lookup will be placed last. This is typically meant for interpreted
|
||||
// engines (js) which can evaluate dynamic user-supplied code.
|
||||
func RegisterLookup(wildcard bool, lookup lookupFunc) {
|
||||
if wildcard {
|
||||
lookups = append(lookups, lookup)
|
||||
} else {
|
||||
lookups = append([]lookupFunc{lookup}, lookups...)
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a new instance of a tracer,
|
||||
// 1. If 'code' is the name of a registered native tracer, then that tracer
|
||||
// is instantiated and returned
|
||||
// 2. If 'code' is the name of a registered js-tracer, then that tracer is
|
||||
// instantiated and returned
|
||||
// 3. Otherwise, the code is interpreted as the js code of a js-tracer, and
|
||||
// is evaluated and returned.
|
||||
// New returns a new instance of a tracer, by iterating through the
|
||||
// registered lookups.
|
||||
func New(code string, ctx *Context) (Tracer, error) {
|
||||
// Resolve native tracer
|
||||
if fn, ok := nativeTracers[code]; ok {
|
||||
return fn(), nil
|
||||
}
|
||||
// Resolve js-tracers by name and assemble the tracer object
|
||||
if tracer, ok := jsTracers[code]; ok {
|
||||
code = tracer
|
||||
}
|
||||
return newJsTracer(code, ctx)
|
||||
}
|
||||
|
||||
// camel converts a snake cased input string into a camel cased output.
|
||||
func camel(str string) string {
|
||||
pieces := strings.Split(str, "_")
|
||||
for i := 1; i < len(pieces); i++ {
|
||||
pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
|
||||
}
|
||||
return strings.Join(pieces, "")
|
||||
}
|
||||
|
||||
// init retrieves the JavaScript transaction tracers included in go-ethereum.
|
||||
func init() {
|
||||
for _, file := range tracers.AssetNames() {
|
||||
name := camel(strings.TrimSuffix(file, ".js"))
|
||||
jsTracers[name] = string(tracers.MustAsset(file))
|
||||
for _, lookup := range lookups {
|
||||
if tracer, err := lookup(code, ctx); err == nil {
|
||||
return tracer, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("tracer not found")
|
||||
}
|
||||
|
Reference in New Issue
Block a user