github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/blocks/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 blocksPkg
    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  // BlocksOptions provides all command options for the chifra blocks command.
    30  type BlocksOptions struct {
    31  	Blocks      []string                 `json:"blocks,omitempty"`      // A space-separated list of one or more block identifiers
    32  	BlockIds    []identifiers.Identifier `json:"blockIds,omitempty"`    // Block identifiers
    33  	Hashes      bool                     `json:"hashes,omitempty"`      // Display only transaction hashes, default is to display full transaction detail
    34  	Uncles      bool                     `json:"uncles,omitempty"`      // Display uncle blocks (if any) instead of the requested block
    35  	Traces      bool                     `json:"traces,omitempty"`      // Export the traces from the block as opposed to the block data
    36  	Uniq        bool                     `json:"uniq,omitempty"`        // Display a list of uniq address appearances per 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 block(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  	Withdrawals bool                     `json:"withdrawals,omitempty"` // Export the withdrawals from the block as opposed to the block data
    42  	Articulate  bool                     `json:"articulate,omitempty"`  // For the --logs option only, articulate the retrieved data if ABIs can be found
    43  	Count       bool                     `json:"count,omitempty"`       // Display only the count of appearances for --addrs or --uniq
    44  	CacheTxs    bool                     `json:"cacheTxs,omitempty"`    // Force a write of the block's transactions to the cache (slow)
    45  	CacheTraces bool                     `json:"cacheTraces,omitempty"` // Force a write of the block's traces to the cache (slower)
    46  	Globals     globals.GlobalOptions    `json:"globals,omitempty"`     // The global options
    47  	Conn        *rpc.Connection          `json:"conn,omitempty"`        // The connection to the RPC server
    48  	BadFlag     error                    `json:"badFlag,omitempty"`     // An error flag if needed
    49  	// EXISTING_CODE
    50  	// EXISTING_CODE
    51  }
    52  
    53  var defaultBlocksOptions = BlocksOptions{}
    54  
    55  // testLog is used only during testing to export the options for this test case.
    56  func (opts *BlocksOptions) testLog() {
    57  	logger.TestLog(len(opts.Blocks) > 0, "Blocks: ", opts.Blocks)
    58  	logger.TestLog(opts.Hashes, "Hashes: ", opts.Hashes)
    59  	logger.TestLog(opts.Uncles, "Uncles: ", opts.Uncles)
    60  	logger.TestLog(opts.Traces, "Traces: ", opts.Traces)
    61  	logger.TestLog(opts.Uniq, "Uniq: ", opts.Uniq)
    62  	logger.TestLog(len(opts.Flow) > 0, "Flow: ", opts.Flow)
    63  	logger.TestLog(opts.Logs, "Logs: ", opts.Logs)
    64  	logger.TestLog(len(opts.Emitter) > 0, "Emitter: ", opts.Emitter)
    65  	logger.TestLog(len(opts.Topic) > 0, "Topic: ", opts.Topic)
    66  	logger.TestLog(opts.Withdrawals, "Withdrawals: ", opts.Withdrawals)
    67  	logger.TestLog(opts.Articulate, "Articulate: ", opts.Articulate)
    68  	logger.TestLog(opts.Count, "Count: ", opts.Count)
    69  	logger.TestLog(opts.CacheTxs, "CacheTxs: ", opts.CacheTxs)
    70  	logger.TestLog(opts.CacheTraces, "CacheTraces: ", opts.CacheTraces)
    71  	opts.Conn.TestLog(opts.getCaches())
    72  	opts.Globals.TestLog()
    73  }
    74  
    75  // String implements the Stringer interface
    76  func (opts *BlocksOptions) String() string {
    77  	b, _ := json.MarshalIndent(opts, "", "  ")
    78  	return string(b)
    79  }
    80  
    81  // blocksFinishParseApi finishes the parsing for server invocations. Returns a new BlocksOptions.
    82  func blocksFinishParseApi(w http.ResponseWriter, r *http.Request) *BlocksOptions {
    83  	values := r.URL.Query()
    84  	if r.Header.Get("User-Agent") == "testRunner" {
    85  		values.Set("testRunner", "true")
    86  	}
    87  	return BlocksFinishParseInternal(w, values)
    88  }
    89  
    90  func BlocksFinishParseInternal(w io.Writer, values url.Values) *BlocksOptions {
    91  	copy := defaultBlocksOptions
    92  	copy.Globals.Caps = getCaps()
    93  	opts := &copy
    94  	for key, value := range values {
    95  		switch key {
    96  		case "blocks":
    97  			for _, val := range value {
    98  				s := strings.Split(val, " ") // may contain space separated items
    99  				opts.Blocks = append(opts.Blocks, s...)
   100  			}
   101  		case "hashes":
   102  			opts.Hashes = true
   103  		case "uncles":
   104  			opts.Uncles = true
   105  		case "traces":
   106  			opts.Traces = true
   107  		case "uniq":
   108  			opts.Uniq = true
   109  		case "flow":
   110  			opts.Flow = value[0]
   111  		case "logs":
   112  			opts.Logs = true
   113  		case "emitter":
   114  			for _, val := range value {
   115  				s := strings.Split(val, " ") // may contain space separated items
   116  				opts.Emitter = append(opts.Emitter, s...)
   117  			}
   118  		case "topic":
   119  			for _, val := range value {
   120  				s := strings.Split(val, " ") // may contain space separated items
   121  				opts.Topic = append(opts.Topic, s...)
   122  			}
   123  		case "withdrawals":
   124  			opts.Withdrawals = true
   125  		case "articulate":
   126  			opts.Articulate = true
   127  		case "count":
   128  			opts.Count = true
   129  		case "cacheTxs":
   130  			opts.CacheTxs = true
   131  		case "cacheTraces":
   132  			opts.CacheTraces = true
   133  		default:
   134  			if !copy.Globals.Caps.HasKey(key) {
   135  				err := validate.Usage("Invalid key ({0}) in {1} route.", key, "blocks")
   136  				if opts.BadFlag == nil || opts.BadFlag.Error() > err.Error() {
   137  					opts.BadFlag = err
   138  				}
   139  			}
   140  		}
   141  	}
   142  	opts.Conn = opts.Globals.FinishParseApi(w, values, opts.getCaches())
   143  
   144  	// EXISTING_CODE
   145  	// EXISTING_CODE
   146  	opts.Emitter, _ = opts.Conn.GetEnsAddresses(opts.Emitter)
   147  
   148  	return opts
   149  }
   150  
   151  // blocksFinishParse finishes the parsing for command line invocations. Returns a new BlocksOptions.
   152  func blocksFinishParse(args []string) *BlocksOptions {
   153  	// remove duplicates from args if any (not needed in api mode because the server does it).
   154  	dedup := map[string]int{}
   155  	if len(args) > 0 {
   156  		tmp := []string{}
   157  		for _, arg := range args {
   158  			if value := dedup[arg]; value == 0 {
   159  				tmp = append(tmp, arg)
   160  			}
   161  			dedup[arg]++
   162  		}
   163  		args = tmp
   164  	}
   165  
   166  	defFmt := "txt"
   167  	opts := GetOptions()
   168  	opts.Conn = opts.Globals.FinishParse(args, opts.getCaches())
   169  
   170  	// EXISTING_CODE
   171  	opts.Blocks = args
   172  	if !opts.Uniq {
   173  		defFmt = "json"
   174  	}
   175  	// EXISTING_CODE
   176  	opts.Emitter, _ = opts.Conn.GetEnsAddresses(opts.Emitter)
   177  	if len(opts.Globals.Format) == 0 || opts.Globals.Format == "none" {
   178  		opts.Globals.Format = defFmt
   179  	}
   180  
   181  	return opts
   182  }
   183  
   184  func GetOptions() *BlocksOptions {
   185  	// EXISTING_CODE
   186  	// EXISTING_CODE
   187  	return &defaultBlocksOptions
   188  }
   189  
   190  func getCaps() caps.Capability {
   191  	var capabilities caps.Capability // capabilities for chifra blocks
   192  	capabilities = capabilities.Add(caps.Default)
   193  	capabilities = capabilities.Add(caps.Caching)
   194  	capabilities = capabilities.Add(caps.Ether)
   195  	capabilities = capabilities.Add(caps.Names)
   196  	// EXISTING_CODE
   197  	// EXISTING_CODE
   198  	return capabilities
   199  }
   200  
   201  func ResetOptions(testMode bool) {
   202  	// We want to keep writer between command file calls
   203  	w := GetOptions().Globals.Writer
   204  	opts := BlocksOptions{}
   205  	globals.SetDefaults(&opts.Globals)
   206  	opts.Globals.TestMode = testMode
   207  	opts.Globals.Writer = w
   208  	opts.Globals.Caps = getCaps()
   209  	defaultBlocksOptions = opts
   210  }
   211  
   212  func (opts *BlocksOptions) getCaches() (caches map[walk.CacheType]bool) {
   213  	// EXISTING_CODE
   214  	caches = map[walk.CacheType]bool{
   215  		walk.Cache_Blocks:       !opts.Uncles,
   216  		walk.Cache_Receipts:     !opts.Uncles,
   217  		walk.Cache_Transactions: opts.CacheTxs || opts.Uniq,
   218  		walk.Cache_Traces:       opts.CacheTraces || (opts.Globals.Cache && (opts.Traces || opts.Uniq)),
   219  		walk.Cache_Logs:         opts.Logs,
   220  	}
   221  	// EXISTING_CODE
   222  	return
   223  }
   224  
   225  // EXISTING_CODE
   226  // EXISTING_CODE