github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/traces/options.go (about)

     1  // Copyright 2016, 2024 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  /*
     5   * Parts of this file were auto generated. Edit only those parts of
     6   * the code inside of 'EXISTING_CODE' tags.
     7   */
     8  
     9  package tracesPkg
    10  
    11  import (
    12  	// EXISTING_CODE
    13  	"encoding/json"
    14  	"io"
    15  	"net/http"
    16  	"net/url"
    17  	"strings"
    18  
    19  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/internal/globals"
    20  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/caps"
    21  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/identifiers"
    22  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
    23  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc"
    24  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate"
    25  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    26  	// EXISTING_CODE
    27  )
    28  
    29  // TracesOptions provides all command options for the chifra traces command.
    30  type TracesOptions struct {
    31  	Transactions   []string                 `json:"transactions,omitempty"`   // A space-separated list of one or more transaction identifiers
    32  	TransactionIds []identifiers.Identifier `json:"transactionIds,omitempty"` // Transaction identifiers
    33  	Articulate     bool                     `json:"articulate,omitempty"`     // Articulate the retrieved data if ABIs can be found
    34  	Filter         string                   `json:"filter,omitempty"`         // Call the node's trace_filter routine with bang-separated filter
    35  	Count          bool                     `json:"count,omitempty"`          // Display only the number of traces for the transaction (fast)
    36  	Globals        globals.GlobalOptions    `json:"globals,omitempty"`        // The global options
    37  	Conn           *rpc.Connection          `json:"conn,omitempty"`           // The connection to the RPC server
    38  	BadFlag        error                    `json:"badFlag,omitempty"`        // An error flag if needed
    39  	// EXISTING_CODE
    40  	// EXISTING_CODE
    41  }
    42  
    43  var defaultTracesOptions = TracesOptions{}
    44  
    45  // testLog is used only during testing to export the options for this test case.
    46  func (opts *TracesOptions) testLog() {
    47  	logger.TestLog(len(opts.Transactions) > 0, "Transactions: ", opts.Transactions)
    48  	logger.TestLog(opts.Articulate, "Articulate: ", opts.Articulate)
    49  	logger.TestLog(len(opts.Filter) > 0, "Filter: ", opts.Filter)
    50  	logger.TestLog(opts.Count, "Count: ", opts.Count)
    51  	opts.Conn.TestLog(opts.getCaches())
    52  	opts.Globals.TestLog()
    53  }
    54  
    55  // String implements the Stringer interface
    56  func (opts *TracesOptions) String() string {
    57  	b, _ := json.MarshalIndent(opts, "", "  ")
    58  	return string(b)
    59  }
    60  
    61  // tracesFinishParseApi finishes the parsing for server invocations. Returns a new TracesOptions.
    62  func tracesFinishParseApi(w http.ResponseWriter, r *http.Request) *TracesOptions {
    63  	values := r.URL.Query()
    64  	if r.Header.Get("User-Agent") == "testRunner" {
    65  		values.Set("testRunner", "true")
    66  	}
    67  	return TracesFinishParseInternal(w, values)
    68  }
    69  
    70  func TracesFinishParseInternal(w io.Writer, values url.Values) *TracesOptions {
    71  	copy := defaultTracesOptions
    72  	copy.Globals.Caps = getCaps()
    73  	opts := &copy
    74  	for key, value := range values {
    75  		switch key {
    76  		case "transactions":
    77  			for _, val := range value {
    78  				s := strings.Split(val, " ") // may contain space separated items
    79  				opts.Transactions = append(opts.Transactions, s...)
    80  			}
    81  		case "articulate":
    82  			opts.Articulate = true
    83  		case "filter":
    84  			opts.Filter = value[0]
    85  		case "count":
    86  			opts.Count = true
    87  		default:
    88  			if !copy.Globals.Caps.HasKey(key) {
    89  				err := validate.Usage("Invalid key ({0}) in {1} route.", key, "traces")
    90  				if opts.BadFlag == nil || opts.BadFlag.Error() > err.Error() {
    91  					opts.BadFlag = err
    92  				}
    93  			}
    94  		}
    95  	}
    96  	opts.Conn = opts.Globals.FinishParseApi(w, values, opts.getCaches())
    97  
    98  	// EXISTING_CODE
    99  	// EXISTING_CODE
   100  
   101  	return opts
   102  }
   103  
   104  // tracesFinishParse finishes the parsing for command line invocations. Returns a new TracesOptions.
   105  func tracesFinishParse(args []string) *TracesOptions {
   106  	// remove duplicates from args if any (not needed in api mode because the server does it).
   107  	dedup := map[string]int{}
   108  	if len(args) > 0 {
   109  		tmp := []string{}
   110  		for _, arg := range args {
   111  			if value := dedup[arg]; value == 0 {
   112  				tmp = append(tmp, arg)
   113  			}
   114  			dedup[arg]++
   115  		}
   116  		args = tmp
   117  	}
   118  
   119  	defFmt := "txt"
   120  	opts := GetOptions()
   121  	opts.Conn = opts.Globals.FinishParse(args, opts.getCaches())
   122  
   123  	// EXISTING_CODE
   124  	opts.Transactions = args
   125  	// EXISTING_CODE
   126  	if len(opts.Globals.Format) == 0 || opts.Globals.Format == "none" {
   127  		opts.Globals.Format = defFmt
   128  	}
   129  
   130  	return opts
   131  }
   132  
   133  func GetOptions() *TracesOptions {
   134  	// EXISTING_CODE
   135  	// EXISTING_CODE
   136  	return &defaultTracesOptions
   137  }
   138  
   139  func getCaps() caps.Capability {
   140  	var capabilities caps.Capability // capabilities for chifra traces
   141  	capabilities = capabilities.Add(caps.Default)
   142  	capabilities = capabilities.Add(caps.Caching)
   143  	capabilities = capabilities.Add(caps.Ether)
   144  	capabilities = capabilities.Add(caps.Names)
   145  	// EXISTING_CODE
   146  	// EXISTING_CODE
   147  	return capabilities
   148  }
   149  
   150  func ResetOptions(testMode bool) {
   151  	// We want to keep writer between command file calls
   152  	w := GetOptions().Globals.Writer
   153  	opts := TracesOptions{}
   154  	globals.SetDefaults(&opts.Globals)
   155  	opts.Globals.TestMode = testMode
   156  	opts.Globals.Writer = w
   157  	opts.Globals.Caps = getCaps()
   158  	defaultTracesOptions = opts
   159  }
   160  
   161  func (opts *TracesOptions) getCaches() (caches map[walk.CacheType]bool) {
   162  	// EXISTING_CODE
   163  	caches = map[walk.CacheType]bool{
   164  		walk.Cache_Transactions: true,
   165  		walk.Cache_Traces:       true,
   166  	}
   167  	// EXISTING_CODE
   168  	return
   169  }
   170  
   171  // EXISTING_CODE
   172  // EXISTING_CODE