github.com/MikyChow/arbitrum-go-ethereum@v0.0.0-20230306102812-078da49636de/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  /*
    18  Package native is a collection of tracers written in go.
    19  
    20  In order to add a native tracer and have it compiled into the binary, a new
    21  file needs to be added to this folder, containing an implementation of the
    22  `eth.tracers.Tracer` interface.
    23  
    24  Aside from implementing the tracer, it also needs to register itself, using the
    25  `register` method -- and this needs to be done in the package initialization.
    26  
    27  Example:
    28  
    29  ```golang
    30  
    31  	func init() {
    32  		register("noopTracerNative", newNoopTracer)
    33  	}
    34  
    35  ```
    36  */
    37  package native
    38  
    39  import (
    40  	"encoding/json"
    41  	"errors"
    42  
    43  	"github.com/MikyChow/arbitrum-go-ethereum/eth/tracers"
    44  )
    45  
    46  // init registers itself this packages as a lookup for tracers.
    47  func init() {
    48  	tracers.RegisterLookup(false, lookup)
    49  }
    50  
    51  // ctorFn is the constructor signature of a native tracer.
    52  type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error)
    53  
    54  /*
    55  ctors is a map of package-local tracer constructors.
    56  
    57  We cannot be certain about the order of init-functions within a package,
    58  The go spec (https://golang.org/ref/spec#Package_initialization) says
    59  
    60  > To ensure reproducible initialization behavior, build systems
    61  > are encouraged to present multiple files belonging to the same
    62  > package in lexical file name order to a compiler.
    63  
    64  Hence, we cannot make the map in init, but must make it upon first use.
    65  */
    66  var ctors map[string]ctorFn
    67  
    68  // register is used by native tracers to register their presence.
    69  func register(name string, ctor ctorFn) {
    70  	if ctors == nil {
    71  		ctors = make(map[string]ctorFn)
    72  	}
    73  	ctors[name] = ctor
    74  }
    75  
    76  // lookup returns a tracer, if one can be matched to the given name.
    77  func lookup(name string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
    78  	if ctors == nil {
    79  		ctors = make(map[string]ctorFn)
    80  	}
    81  	if ctor, ok := ctors[name]; ok {
    82  		return ctor(ctx, cfg)
    83  	}
    84  	return nil, errors.New("no tracer found")
    85  }