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  }