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.

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