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 := © 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