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.

161 lines
4.6 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. ptypes "github.com/tendermint/tendermint/permission/types"
  12. "github.com/tendermint/tendermint/types"
  13. )
  14. type GenesisAccount struct {
  15. Address []byte `json:"address"`
  16. Amount uint64 `json:"amount"`
  17. Permissions *ptypes.AccountPermissions `json:"global_permissions"` // pointer so optional
  18. }
  19. type GenesisValidator struct {
  20. PubKey account.PubKeyEd25519 `json:"pub_key"`
  21. Amount int64 `json:"amount"`
  22. UnbondTo []GenesisAccount `json:"unbond_to"`
  23. }
  24. type GenesisParams struct {
  25. // Default permissions for newly created accounts
  26. GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
  27. // TODO: other params we may want to tweak?
  28. }
  29. type GenesisDoc struct {
  30. GenesisTime time.Time `json:"genesis_time"`
  31. ChainID string `json:"chain_id"`
  32. Params *GenesisParams `json:"params"` // pointer so optional
  33. Accounts []GenesisAccount `json:"accounts"`
  34. Validators []GenesisValidator `json:"validators"`
  35. }
  36. func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
  37. var err error
  38. binary.ReadJSON(&genState, jsonBlob, &err)
  39. if err != nil {
  40. log.Error(Fmt("Couldn't read GenesisDoc: %v", err))
  41. os.Exit(1)
  42. }
  43. return
  44. }
  45. func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) *State {
  46. jsonBlob, err := ioutil.ReadFile(genDocFile)
  47. if err != nil {
  48. log.Error(Fmt("Couldn't read GenesisDoc file: %v", err))
  49. os.Exit(1)
  50. }
  51. genDoc := GenesisDocFromJSON(jsonBlob)
  52. return MakeGenesisState(db, genDoc)
  53. }
  54. func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
  55. if len(genDoc.Validators) == 0 {
  56. Exit(Fmt("The genesis file has no validators"))
  57. }
  58. if genDoc.GenesisTime.IsZero() {
  59. genDoc.GenesisTime = time.Now()
  60. }
  61. // Make accounts state tree
  62. accounts := merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
  63. for _, genAcc := range genDoc.Accounts {
  64. perm := ptypes.NewDefaultAccountPermissions()
  65. if genAcc.Permissions != nil {
  66. perm = genAcc.Permissions
  67. }
  68. acc := &account.Account{
  69. Address: genAcc.Address,
  70. PubKey: nil,
  71. Sequence: 0,
  72. Balance: genAcc.Amount,
  73. Permissions: perm,
  74. }
  75. accounts.Set(acc.Address, acc)
  76. }
  77. // global permissions are saved as the 0 address
  78. // so they are included in the accounts tree
  79. globalPerms := ptypes.NewDefaultAccountPermissions()
  80. if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil {
  81. globalPerms = genDoc.Params.GlobalPermissions
  82. // XXX: make sure the set bits are all true
  83. globalPerms.Base.SetBit = ptypes.AllSet
  84. }
  85. permsAcc := &account.Account{
  86. Address: ptypes.GlobalPermissionsAddress,
  87. PubKey: nil,
  88. Sequence: 0,
  89. Balance: 1337,
  90. Permissions: globalPerms,
  91. }
  92. accounts.Set(permsAcc.Address, permsAcc)
  93. // Make validatorInfos state tree && validators slice
  94. validatorInfos := merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db)
  95. validators := make([]*Validator, len(genDoc.Validators))
  96. for i, val := range genDoc.Validators {
  97. pubKey := val.PubKey
  98. address := pubKey.Address()
  99. // Make ValidatorInfo
  100. valInfo := &ValidatorInfo{
  101. Address: address,
  102. PubKey: pubKey,
  103. UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)),
  104. FirstBondHeight: 0,
  105. FirstBondAmount: val.Amount,
  106. }
  107. for i, unbondTo := range val.UnbondTo {
  108. valInfo.UnbondTo[i] = &types.TxOutput{
  109. Address: unbondTo.Address,
  110. Amount: unbondTo.Amount,
  111. }
  112. }
  113. validatorInfos.Set(address, valInfo)
  114. // Make validator
  115. validators[i] = &Validator{
  116. Address: address,
  117. PubKey: pubKey,
  118. VotingPower: val.Amount,
  119. }
  120. }
  121. // Make namereg tree
  122. nameReg := merkle.NewIAVLTree(binary.BasicCodec, NameRegCodec, 0, db)
  123. // TODO: add names to genesis.json
  124. // IAVLTrees must be persisted before copy operations.
  125. accounts.Save()
  126. validatorInfos.Save()
  127. nameReg.Save()
  128. return &State{
  129. DB: db,
  130. ChainID: genDoc.ChainID,
  131. LastBlockHeight: 0,
  132. LastBlockHash: nil,
  133. LastBlockParts: types.PartSetHeader{},
  134. LastBlockTime: genDoc.GenesisTime,
  135. BondedValidators: NewValidatorSet(validators),
  136. LastBondedValidators: NewValidatorSet(nil),
  137. UnbondingValidators: NewValidatorSet(nil),
  138. accounts: accounts,
  139. validatorInfos: validatorInfos,
  140. nameReg: nameReg,
  141. }
  142. }