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.

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