You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.4 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package state
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "time"
  6. "github.com/tendermint/tendermint/account"
  7. "github.com/tendermint/tendermint/binary"
  8. . "github.com/tendermint/tendermint/common"
  9. dbm "github.com/tendermint/tendermint/db"
  10. "github.com/tendermint/tendermint/merkle"
  11. "github.com/tendermint/tendermint/types"
  12. )
  13. type GenesisAccount struct {
  14. Address []byte `json:"address"`
  15. Amount int64 `json:"amount"`
  16. }
  17. type GenesisValidator struct {
  18. PubKey account.PubKeyEd25519 `json:"pub_key"`
  19. Amount int64 `json:"amount"`
  20. UnbondTo []GenesisAccount `json:"unbond_to"`
  21. }
  22. type GenesisDoc struct {
  23. GenesisTime time.Time `json:"genesis_time"`
  24. ChainID string `json:"chain_id"`
  25. Accounts []GenesisAccount `json:"accounts"`
  26. Validators []GenesisValidator `json:"validators"`
  27. }
  28. func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
  29. var err error
  30. binary.ReadJSON(&genState, jsonBlob, &err)
  31. if err != nil {
  32. log.Error(Fmt("Couldn't read GenesisDoc: %v", err))
  33. os.Exit(1)
  34. }
  35. return
  36. }
  37. func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) *State {
  38. jsonBlob, err := ioutil.ReadFile(genDocFile)
  39. if err != nil {
  40. log.Error(Fmt("Couldn't read GenesisDoc file: %v", err))
  41. os.Exit(1)
  42. }
  43. genDoc := GenesisDocFromJSON(jsonBlob)
  44. return MakeGenesisState(db, genDoc)
  45. }
  46. func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
  47. if len(genDoc.Validators) == 0 {
  48. Exit(Fmt("The genesis file has no validators"))
  49. }
  50. if genDoc.GenesisTime.IsZero() {
  51. genDoc.GenesisTime = time.Now()
  52. }
  53. // Make accounts state tree
  54. accounts := merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
  55. for _, genAcc := range genDoc.Accounts {
  56. acc := &account.Account{
  57. Address: genAcc.Address,
  58. PubKey: nil,
  59. Sequence: 0,
  60. Balance: genAcc.Amount,
  61. }
  62. accounts.Set(acc.Address, acc)
  63. }
  64. // Make validatorInfos state tree && validators slice
  65. validatorInfos := merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db)
  66. validators := make([]*Validator, len(genDoc.Validators))
  67. for i, val := range genDoc.Validators {
  68. pubKey := val.PubKey
  69. address := pubKey.Address()
  70. // Make ValidatorInfo
  71. valInfo := &ValidatorInfo{
  72. Address: address,
  73. PubKey: pubKey,
  74. UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)),
  75. FirstBondHeight: 0,
  76. FirstBondAmount: val.Amount,
  77. }
  78. for i, unbondTo := range val.UnbondTo {
  79. valInfo.UnbondTo[i] = &types.TxOutput{
  80. Address: unbondTo.Address,
  81. Amount: unbondTo.Amount,
  82. }
  83. }
  84. validatorInfos.Set(address, valInfo)
  85. // Make validator
  86. validators[i] = &Validator{
  87. Address: address,
  88. PubKey: pubKey,
  89. VotingPower: val.Amount,
  90. }
  91. }
  92. // Make namereg tree
  93. nameReg := merkle.NewIAVLTree(binary.BasicCodec, NameRegCodec, 0, db)
  94. // TODO: add names to genesis.json
  95. // IAVLTrees must be persisted before copy operations.
  96. accounts.Save()
  97. validatorInfos.Save()
  98. nameReg.Save()
  99. return &State{
  100. DB: db,
  101. ChainID: genDoc.ChainID,
  102. LastBlockHeight: 0,
  103. LastBlockHash: nil,
  104. LastBlockParts: types.PartSetHeader{},
  105. LastBlockTime: genDoc.GenesisTime,
  106. BondedValidators: NewValidatorSet(validators),
  107. LastBondedValidators: NewValidatorSet(nil),
  108. UnbondingValidators: NewValidatorSet(nil),
  109. accounts: accounts,
  110. validatorInfos: validatorInfos,
  111. nameReg: nameReg,
  112. }
  113. }