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
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. //------------------------------------------------------------
  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.ReadJSONPtr(&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, contracts 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. }