github.com/tirogen/go-ethereum@v1.10.12-0.20221226051715-250cfede41b6/eth/tracers/native/tracer.go (about)

     1  // Copyright 2021 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package native is a collection of tracers written in go.
    18  //
    19  // In order to add a native tracer and have it compiled into the binary, a new
    20  // file needs to be added to this folder, containing an implementation of the
    21  // `eth.tracers.Tracer` interface.
    22  //
    23  // Aside from implementing the tracer, it also needs to register itself, using the
    24  // `register` method -- and this needs to be done in the package initialization.
    25  //
    26  // Example:
    27  //
    28  //	func init() {
    29  //		register("noopTracerNative", newNoopTracer)
    30  //	}
    31  package native
    32  
    33  import (
    34  	"encoding/json"
    35  	"errors"
    36  
    37  	"github.com/tirogen/go-ethereum/eth/tracers"
    38  )
    39  
    40  // init registers itself this packages as a lookup for tracers.
    41  func init() {
    42  	tracers.RegisterLookup(false, lookup)
    43  }
    44  
    45  // ctorFn is the constructor signature of a native tracer.
    46  type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error)
    47  
    48  /*
    49  ctors is a map of package-local tracer constructors.
    50  
    51  We cannot be certain about the order of init-functions within a package,
    52  The go spec (https://golang.org/ref/spec#Package_initialization) says
    53  
    54  > To ensure reproducible initialization behavior, build systems
    55  > are encouraged to present multiple files belonging to the same
    56  > package in lexical file name order to a compiler.
    57  
    58  Hence, we cannot make the map in init, but must make it upon first use.
    59  */
    60  var ctors map[string]ctorFn
    61  
    62  // register is used by native tracers to register their presence.
    63  func register(name string, ctor ctorFn) {
    64  	if ctors == nil {
    65  		ctors = make(map[string]ctorFn)
    66  	}
    67  	ctors[name] = ctor
    68  }
    69  
    70  // lookup returns a tracer, if one can be matched to the given name.
    71  func lookup(name string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
    72  	if ctors == nil {
    73  		ctors = make(map[string]ctorFn)
    74  	}
    75  	if ctor, ok := ctors[name]; ok {
    76  		return ctor(ctx, cfg)
    77  	}
    78  	return nil, errors.New("no tracer found")
    79  }