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.

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