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
9 years ago
9 years ago
9 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. }