github.com/cosmos/cosmos-sdk@v0.50.10/x/genutil/types/chain_id.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 "strings" 9 10 "github.com/cometbft/cometbft/types" 11 ) 12 13 const ChainIDFieldName = "chain_id" 14 15 // ParseChainIDFromGenesis parses the `chain_id` from a genesis JSON file, aborting early after finding the `chain_id`. 16 // For efficiency, it's recommended to place the `chain_id` field before any large entries in the JSON file. 17 // Returns an error if the `chain_id` field is not found. 18 func ParseChainIDFromGenesis(r io.Reader) (string, error) { 19 dec := json.NewDecoder(r) 20 21 t, err := dec.Token() 22 if err != nil { 23 return "", err 24 } 25 if t != json.Delim('{') { 26 return "", fmt.Errorf("expected {, got %s", t) 27 } 28 29 for dec.More() { 30 t, err = dec.Token() 31 if err != nil { 32 return "", err 33 } 34 key, ok := t.(string) 35 if !ok { 36 return "", fmt.Errorf("expected string for the key type, got %s", t) 37 } 38 39 if key == ChainIDFieldName { 40 var chainID string 41 if err := dec.Decode(&chainID); err != nil { 42 return "", err 43 } 44 if err := validateChainID(chainID); err != nil { 45 return "", err 46 } 47 return chainID, nil 48 } 49 50 // skip the value 51 var value json.RawMessage 52 if err := dec.Decode(&value); err != nil { 53 return "", err 54 } 55 } 56 57 return "", errors.New("missing chain-id in genesis file") 58 } 59 60 func validateChainID(chainID string) error { 61 if strings.TrimSpace(chainID) == "" { 62 return errors.New("genesis doc must include non-empty chain_id") 63 } 64 if len(chainID) > types.MaxChainIDLen { 65 return fmt.Errorf("chain_id in genesis doc is too long (max: %d)", types.MaxChainIDLen) 66 } 67 68 return nil 69 }