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.

118 lines
3.1 KiB

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