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