github.com/MetalBlockchain/subnet-evm@v0.4.9/eth/tracers/native/tracer.go (about)

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