github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/transactions/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 transactionsPkg
    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/base"
    21  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/caps"
    22  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/identifiers"
    23  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
    24  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc"
    25  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate"
    26  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    27  	// EXISTING_CODE
    28  )
    29  
    30  // TransactionsOptions provides all command options for the chifra transactions command.
    31  type TransactionsOptions struct {
    32  	Transactions   []string                 `json:"transactions,omitempty"`   // A space-separated list of one or more transaction identifiers
    33  	TransactionIds []identifiers.Identifier `json:"transactionIds,omitempty"` // Transaction identifiers
    34  	Articulate     bool                     `json:"articulate,omitempty"`     // Articulate the retrieved data if ABIs can be found
    35  	Traces         bool                     `json:"traces,omitempty"`         // Include the transaction's traces in the results
    36  	Uniq           bool                     `json:"uniq,omitempty"`           // Display a list of uniq addresses found in the transaction
    37  	Flow           string                   `json:"flow,omitempty"`           // For the uniq option only, export only from or to (including trace from or to)
    38  	Logs           bool                     `json:"logs,omitempty"`           // Display only the logs found in the transaction(s)
    39  	Emitter        []string                 `json:"emitter,omitempty"`        // For the --logs option only, filter logs to show only those logs emitted by the given address(es)
    40  	Topic          []string                 `json:"topic,omitempty"`          // For the --logs option only, filter logs to show only those with this topic(s)
    41  	CacheTraces    bool                     `json:"cacheTraces,omitempty"`    // Force the transaction's traces into the cache
    42  	Globals        globals.GlobalOptions    `json:"globals,omitempty"`        // The global options
    43  	Conn           *rpc.Connection          `json:"conn,omitempty"`           // The connection to the RPC server
    44  	BadFlag        error                    `json:"badFlag,omitempty"`        // An error flag if needed
    45  	// EXISTING_CODE
    46  	AccountForAddr base.Address `json:"-"`
    47  	// EXISTING_CODE
    48  }
    49  
    50  var defaultTransactionsOptions = TransactionsOptions{}
    51  
    52  // testLog is used only during testing to export the options for this test case.
    53  func (opts *TransactionsOptions) testLog() {
    54  	logger.TestLog(len(opts.Transactions) > 0, "Transactions: ", opts.Transactions)
    55  	logger.TestLog(opts.Articulate, "Articulate: ", opts.Articulate)
    56  	logger.TestLog(opts.Traces, "Traces: ", opts.Traces)
    57  	logger.TestLog(opts.Uniq, "Uniq: ", opts.Uniq)
    58  	logger.TestLog(len(opts.Flow) > 0, "Flow: ", opts.Flow)
    59  	logger.TestLog(opts.Logs, "Logs: ", opts.Logs)
    60  	logger.TestLog(len(opts.Emitter) > 0, "Emitter: ", opts.Emitter)
    61  	logger.TestLog(len(opts.Topic) > 0, "Topic: ", opts.Topic)
    62  	logger.TestLog(opts.CacheTraces, "CacheTraces: ", opts.CacheTraces)
    63  	opts.Conn.TestLog(opts.getCaches())
    64  	opts.Globals.TestLog()
    65  }
    66  
    67  // String implements the Stringer interface
    68  func (opts *TransactionsOptions) String() string {
    69  	b, _ := json.MarshalIndent(opts, "", "  ")
    70  	return string(b)
    71  }
    72  
    73  // transactionsFinishParseApi finishes the parsing for server invocations. Returns a new TransactionsOptions.
    74  func transactionsFinishParseApi(w http.ResponseWriter, r *http.Request) *TransactionsOptions {
    75  	values := r.URL.Query()
    76  	if r.Header.Get("User-Agent") == "testRunner" {
    77  		values.Set("testRunner", "true")
    78  	}
    79  	return TransactionsFinishParseInternal(w, values)
    80  }
    81  
    82  func TransactionsFinishParseInternal(w io.Writer, values url.Values) *TransactionsOptions {
    83  	copy := defaultTransactionsOptions
    84  	copy.Globals.Caps = getCaps()
    85  	opts := &copy
    86  	for key, value := range values {
    87  		switch key {
    88  		case "transactions":
    89  			for _, val := range value {
    90  				s := strings.Split(val, " ") // may contain space separated items
    91  				opts.Transactions = append(opts.Transactions, s...)
    92  			}
    93  		case "articulate":
    94  			opts.Articulate = true
    95  		case "traces":
    96  			opts.Traces = true
    97  		case "uniq":
    98  			opts.Uniq = true
    99  		case "flow":
   100  			opts.Flow = value[0]
   101  		case "logs":
   102  			opts.Logs = true
   103  		case "emitter":
   104  			for _, val := range value {
   105  				s := strings.Split(val, " ") // may contain space separated items
   106  				opts.Emitter = append(opts.Emitter, s...)
   107  			}
   108  		case "topic":
   109  			for _, val := range value {
   110  				s := strings.Split(val, " ") // may contain space separated items
   111  				opts.Topic = append(opts.Topic, s...)
   112  			}
   113  		case "cacheTraces":
   114  			opts.CacheTraces = true
   115  		default:
   116  			if !copy.Globals.Caps.HasKey(key) {
   117  				err := validate.Usage("Invalid key ({0}) in {1} route.", key, "transactions")
   118  				if opts.BadFlag == nil || opts.BadFlag.Error() > err.Error() {
   119  					opts.BadFlag = err
   120  				}
   121  			}
   122  		}
   123  	}
   124  	opts.Conn = opts.Globals.FinishParseApi(w, values, opts.getCaches())
   125  
   126  	// EXISTING_CODE
   127  	// EXISTING_CODE
   128  	opts.Emitter, _ = opts.Conn.GetEnsAddresses(opts.Emitter)
   129  
   130  	return opts
   131  }
   132  
   133  // transactionsFinishParse finishes the parsing for command line invocations. Returns a new TransactionsOptions.
   134  func transactionsFinishParse(args []string) *TransactionsOptions {
   135  	// remove duplicates from args if any (not needed in api mode because the server does it).
   136  	dedup := map[string]int{}
   137  	if len(args) > 0 {
   138  		tmp := []string{}
   139  		for _, arg := range args {
   140  			if value := dedup[arg]; value == 0 {
   141  				tmp = append(tmp, arg)
   142  			}
   143  			dedup[arg]++
   144  		}
   145  		args = tmp
   146  	}
   147  
   148  	defFmt := "txt"
   149  	opts := GetOptions()
   150  	opts.Conn = opts.Globals.FinishParse(args, opts.getCaches())
   151  
   152  	// EXISTING_CODE
   153  	opts.Transactions = args
   154  	// EXISTING_CODE
   155  	opts.Emitter, _ = opts.Conn.GetEnsAddresses(opts.Emitter)
   156  	if len(opts.Globals.Format) == 0 || opts.Globals.Format == "none" {
   157  		opts.Globals.Format = defFmt
   158  	}
   159  
   160  	return opts
   161  }
   162  
   163  func GetOptions() *TransactionsOptions {
   164  	// EXISTING_CODE
   165  	// EXISTING_CODE
   166  	return &defaultTransactionsOptions
   167  }
   168  
   169  func getCaps() caps.Capability {
   170  	var capabilities caps.Capability // capabilities for chifra transactions
   171  	capabilities = capabilities.Add(caps.Default)
   172  	capabilities = capabilities.Add(caps.Caching)
   173  	capabilities = capabilities.Add(caps.Ether)
   174  	capabilities = capabilities.Add(caps.Names)
   175  	// EXISTING_CODE
   176  	// EXISTING_CODE
   177  	return capabilities
   178  }
   179  
   180  func ResetOptions(testMode bool) {
   181  	// We want to keep writer between command file calls
   182  	w := GetOptions().Globals.Writer
   183  	opts := TransactionsOptions{}
   184  	globals.SetDefaults(&opts.Globals)
   185  	opts.Globals.TestMode = testMode
   186  	opts.Globals.Writer = w
   187  	opts.Globals.Caps = getCaps()
   188  	defaultTransactionsOptions = opts
   189  }
   190  
   191  func (opts *TransactionsOptions) getCaches() (caches map[walk.CacheType]bool) {
   192  	// EXISTING_CODE
   193  	caches = map[walk.CacheType]bool{
   194  		walk.Cache_Transactions: true,
   195  		walk.Cache_Traces:       opts.CacheTraces || (opts.Globals.Cache && (opts.Traces || opts.Uniq)),
   196  	}
   197  	// EXISTING_CODE
   198  	return
   199  }
   200  
   201  // EXISTING_CODE
   202  // EXISTING_CODE