github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/blocks/validate.go (about) 1 // Copyright 2021 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 package blocksPkg 6 7 import ( 8 "errors" 9 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate" 13 ) 14 15 func (opts *BlocksOptions) validateBlocks() error { 16 chain := opts.Globals.Chain 17 18 opts.testLog() 19 20 if opts.BadFlag != nil { 21 return opts.BadFlag 22 } 23 24 if !config.IsChainConfigured(chain) { 25 return validate.Usage("chain {0} is not properly configured.", chain) 26 } 27 28 for _, emitter := range opts.Emitter { 29 valid, err := base.IsValidAddressE(emitter) 30 if !valid { 31 return err 32 } 33 } 34 35 for _, topic := range opts.Topic { 36 valid, err := validate.IsValidTopicE(topic) 37 if !valid { 38 return err 39 } 40 } 41 42 if opts.tooMany() { 43 return validate.Usage("Please choose only a single mode (--uncles, --logs, --withdrawal, etc.)") 44 } 45 46 err := validate.ValidateIdentifiers( 47 chain, 48 opts.Blocks, 49 validate.ValidBlockIdWithRange, 50 1, 51 &opts.BlockIds, 52 ) 53 if err != nil { 54 if invalidLiteral, ok := err.(*validate.InvalidIdentifierLiteralError); ok { 55 return invalidLiteral 56 } 57 58 if errors.Is(err, validate.ErrTooManyRanges) { 59 return validate.Usage("Specify only a single block range at a time.") 60 } 61 62 return err 63 } 64 65 if len(opts.Flow) > 0 { 66 if !opts.Uniq { 67 return validate.Usage("The {0} option is only available with the {1} option", "--flow", "--uniq") 68 } 69 err := validate.ValidateEnum("flow", opts.Flow, "[from|to|reward]") 70 if err != nil { 71 return err 72 } 73 } 74 75 if len(opts.Globals.File) > 0 { 76 // Do nothing 77 } else { 78 if len(opts.Blocks) == 0 { 79 return validate.Usage("Please supply at least one {0}.", "block identifier") 80 } 81 if !opts.Logs && (len(opts.Emitter) > 0 || len(opts.Topic) > 0) { 82 return validate.Usage("The {0} option are only available with the {1} option.", "--emitter and --topic", "--log") 83 } 84 if opts.Traces && opts.Hashes { 85 return validate.Usage("The {0} option is not available{1}.", "--traces", " with the --hashes option") 86 } 87 if !validate.HasArticulationKey(opts.Articulate) { 88 return validate.Usage("The {0} option requires an Etherscan API key.", "--articulate") 89 } 90 if opts.Articulate && !opts.Logs { 91 return validate.Usage("The {0} option is only available with the {1} option.", "--articulate", "--logs") 92 } 93 if opts.Uniq && !opts.Count { 94 if opts.Traces { 95 return validate.Usage("The {0} option is not available{1}.", "--traces", " with the --uniq option") 96 } 97 if opts.Uncles { 98 return validate.Usage("The {0} option is not available{1}.", "--uncles", " with the --uniq option") 99 } 100 if opts.Logs { 101 return validate.Usage("The {0} option is not available{1}.", "--logs", " with the --uniq option") 102 } 103 } 104 105 if opts.Traces { 106 err, ok := opts.Conn.IsNodeTracing() 107 if !ok { 108 return validate.Usage("{0} requires tracing, err: {1}", "chifra blocks --traces", err.Error()) 109 } 110 } 111 112 if opts.Articulate { 113 if opts.Uncles { 114 return validate.Usage("The {0} option is not available{1}.", "--articulate", " with the --uncles option") 115 } 116 } 117 118 // We cannot cache uncles because they are identical to the cannonical blocks of the same number and would be incorrectly retreived. 119 if opts.Globals.Cache && opts.Uncles { 120 return validate.Usage("The {0} option is currently not available{1}.", "--cache", " with the --uncles option") 121 } 122 if opts.Globals.Decache && opts.Uncles { 123 return validate.Usage("The {0} option is currently not available{1}.", "--decache", " with the --uncles option") 124 } 125 } 126 127 return opts.Globals.Validate() 128 } 129 130 func (opts *BlocksOptions) tooMany() bool { 131 cnt := 0 132 if opts.Uncles { 133 cnt++ 134 } 135 if opts.Traces { 136 cnt++ 137 } 138 if opts.Uniq { 139 cnt++ 140 } 141 if opts.Logs { 142 cnt++ 143 } 144 if opts.Withdrawals { 145 cnt++ 146 } 147 return !opts.Count && cnt > 1 148 }