github.com/evdatsion/aphelion-dpos-bft@v0.32.1/types/genesis.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "time" 9 10 "github.com/evdatsion/aphelion-dpos-bft/crypto" 11 cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common" 12 tmtime "github.com/evdatsion/aphelion-dpos-bft/types/time" 13 ) 14 15 const ( 16 // MaxChainIDLen is a maximum length of the chain ID. 17 MaxChainIDLen = 50 18 ) 19 20 //------------------------------------------------------------ 21 // core types for a genesis definition 22 // NOTE: any changes to the genesis definition should 23 // be reflected in the documentation: 24 // docs/tendermint-core/using-tendermint.md 25 26 // GenesisValidator is an initial validator. 27 type GenesisValidator struct { 28 Address Address `json:"address"` 29 PubKey crypto.PubKey `json:"pub_key"` 30 Power int64 `json:"power"` 31 Name string `json:"name"` 32 } 33 34 // GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set. 35 type GenesisDoc struct { 36 GenesisTime time.Time `json:"genesis_time"` 37 ChainID string `json:"chain_id"` 38 ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"` 39 Validators []GenesisValidator `json:"validators,omitempty"` 40 AppHash cmn.HexBytes `json:"app_hash"` 41 AppState json.RawMessage `json:"app_state,omitempty"` 42 } 43 44 // SaveAs is a utility method for saving GenensisDoc as a JSON file. 45 func (genDoc *GenesisDoc) SaveAs(file string) error { 46 genDocBytes, err := cdc.MarshalJSONIndent(genDoc, "", " ") 47 if err != nil { 48 return err 49 } 50 return cmn.WriteFile(file, genDocBytes, 0644) 51 } 52 53 // ValidatorHash returns the hash of the validator set contained in the GenesisDoc 54 func (genDoc *GenesisDoc) ValidatorHash() []byte { 55 vals := make([]*Validator, len(genDoc.Validators)) 56 for i, v := range genDoc.Validators { 57 vals[i] = NewValidator(v.PubKey, v.Power) 58 } 59 vset := NewValidatorSet(vals) 60 return vset.Hash() 61 } 62 63 // ValidateAndComplete checks that all necessary fields are present 64 // and fills in defaults for optional fields left empty 65 func (genDoc *GenesisDoc) ValidateAndComplete() error { 66 if genDoc.ChainID == "" { 67 return cmn.NewError("Genesis doc must include non-empty chain_id") 68 } 69 if len(genDoc.ChainID) > MaxChainIDLen { 70 return cmn.NewError("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen) 71 } 72 73 if genDoc.ConsensusParams == nil { 74 genDoc.ConsensusParams = DefaultConsensusParams() 75 } else { 76 if err := genDoc.ConsensusParams.Validate(); err != nil { 77 return err 78 } 79 } 80 81 for i, v := range genDoc.Validators { 82 if v.Power == 0 { 83 return cmn.NewError("The genesis file cannot contain validators with no voting power: %v", v) 84 } 85 if len(v.Address) > 0 && !bytes.Equal(v.PubKey.Address(), v.Address) { 86 return cmn.NewError("Incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address()) 87 } 88 if len(v.Address) == 0 { 89 genDoc.Validators[i].Address = v.PubKey.Address() 90 } 91 } 92 93 if genDoc.GenesisTime.IsZero() { 94 genDoc.GenesisTime = tmtime.Now() 95 } 96 97 return nil 98 } 99 100 //------------------------------------------------------------ 101 // Make genesis state from file 102 103 // GenesisDocFromJSON unmarshalls JSON data into a GenesisDoc. 104 func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) { 105 genDoc := GenesisDoc{} 106 err := cdc.UnmarshalJSON(jsonBlob, &genDoc) 107 if err != nil { 108 return nil, err 109 } 110 111 if err := genDoc.ValidateAndComplete(); err != nil { 112 return nil, err 113 } 114 115 return &genDoc, err 116 } 117 118 // GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc. 119 func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) { 120 jsonBlob, err := ioutil.ReadFile(genDocFile) 121 if err != nil { 122 return nil, cmn.ErrorWrap(err, "Couldn't read GenesisDoc file") 123 } 124 genDoc, err := GenesisDocFromJSON(jsonBlob) 125 if err != nil { 126 return nil, cmn.ErrorWrap(err, fmt.Sprintf("Error reading GenesisDoc at %v", genDocFile)) 127 } 128 return genDoc, nil 129 }