From 31013d1e8f46c79bad95d458396afa9cad6b6e21 Mon Sep 17 00:00:00 2001 From: meowsbits Date: Fri, 8 Jan 2021 09:31:32 -0600 Subject: [PATCH] cmd/faucet/main: adds flag use audit checks and refactors logic (#276) * main: adds flag use audit checks and refactors logic -ethstats and -bootnodes and -network flags were not being checked for exclusivity with -attach. Adding those checks, this also refactors the auditor function. Date: 2021-01-05 07:02:15-06:00 Signed-off-by: meows * main: remove ethPort vs. attach flag exclusive check The ethPort default value is nonzero, making this check incorrect. Resolves https://github.com/etclabscore/core-geth/pull/276#discussion_r553692331 Date: 2021-01-08 06:18:43-06:00 Signed-off-by: meows --- cmd/faucet/faucet.go | 80 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 413bc6a27e..14d10d00e1 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -35,6 +35,7 @@ import ( "net/url" "os" "path/filepath" + "reflect" "regexp" "strconv" "strings" @@ -209,28 +210,77 @@ func parseChainFlags() (gs *genesisT.Genesis, bs string, netid uint64) { // auditFlagUse ensures that exclusive/incompatible flag values are not set. // If invalid use if found, the program exits with log.Crit. -func auditFlagUse(genesis *genesisT.Genesis) { - if genesis == nil && *attachFlag == "" { - log.Crit("no -chain. configured and no attach target; use either -chain. or -attach.") - } - if *statsFlag != "" && *attachFlag != "" { - log.Crit("flags are incompatible", "flags", []string{"ethstats", "attach"}, "values", []*string{statsFlag, attachFlag}) - } - var activeChainFlag *bool +func auditFlagUse() { + var ( + ffalse = false + activeChainFlag = &ffalse + ) for _, f := range chainFlags { if *f { - if activeChainFlag != nil { + if *activeChainFlag { log.Crit("cannot use two -chain.* flags simultaneously") } activeChainFlag = f } } - if activeChainFlag != nil && *attachFlag != "" { - log.Crit("cannot use -chain.* with -attach") + + if !*activeChainFlag && *genesisFlag == "" && *attachFlag == "" { + log.Crit("missing chain configuration option; use one of -chain., -genesis, or -attach") } - if *genesisFlag != "" && *attachFlag != "" { - log.Crit("cannot use -genesis flag with -attach") + + type fflag struct { + name string + value interface{} } + exclusiveOrCrit := func(a, b fflag) { + didSetOne := false + for _, f := range []fflag{a, b} { + isSet := false + switch t := f.value.(type) { + case *string: + isSet = *t != "" + case *bool: + isSet = *t + case bool: + isSet = t + case *int64: + isSet = *t != 0 + case *uint64: + isSet = *t != 0 + case *int: + isSet = *t != 0 + default: + panic(fmt.Sprintf("unhandled flag type case: %v %t %s", t, t, f.name)) + } + if didSetOne && isSet { + var av, bv interface{} + av = a.value + bv = b.value + if reflect.TypeOf(a.value).Kind() == reflect.Ptr { + av = reflect.ValueOf(a.value).Elem() + } + if reflect.TypeOf(b.value).Kind() == reflect.Ptr { + bv = reflect.ValueOf(b.value).Elem() + } + log.Crit("flags are exclusive", "flags", []string{a.name, b.name}, "values", []interface{}{av, bv}) + } + didSetOne = isSet + } + } + for _, exclusivePair := range [][]fflag{ + {{"attach", attachFlag}, {"chain.", activeChainFlag}}, + {{"attach", attachFlag}, {"genesis", genesisFlag}}, + {{"attach", attachFlag}, {"ethstats", statsFlag}}, + {{"attach", attachFlag}, {"network", netFlag}}, + {{"attach", attachFlag}, {"bootnodes", bootFlag}}, + } { + exclusiveOrCrit(exclusivePair[0], exclusivePair[1]) + } + + if *attachFlag == "" && *attachChainID != 0 { + log.Crit("must use -attach when using -attach.chainid") + } + if *syncmodeFlag != "" { allowedModes := []string{"light", "fast", "full"} var ok bool @@ -251,6 +301,8 @@ func main() { flag.Parse() log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*logFlag), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + auditFlagUse() + // Load and parse the genesis block requested by the user var genesis *genesisT.Genesis var enodes []*discv5.Node @@ -258,9 +310,7 @@ func main() { // client will be used if the faucet is attaching. If not it won't be touched. var client *ethclient.Client - genesis, *bootFlag, *netFlag = parseChainFlags() - auditFlagUse(genesis) // Construct the payout tiers amounts := make([]string, *tiersFlag)