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.

276 lines
8.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
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. "bytes"
  4. "fmt"
  5. "time"
  6. "github.com/tendermint/tendermint/account"
  7. "github.com/tendermint/tendermint/binary"
  8. dbm "github.com/tendermint/tendermint/db"
  9. "github.com/tendermint/tendermint/merkle"
  10. "github.com/tendermint/tendermint/types"
  11. )
  12. var (
  13. stateKey = []byte("stateKey")
  14. minBondAmount = uint64(1) // TODO adjust
  15. defaultAccountsCacheCapacity = 1000 // TODO adjust
  16. unbondingPeriodBlocks = uint(60 * 24 * 365) // TODO probably better to make it time based.
  17. validatorTimeoutBlocks = uint(10) // TODO adjust
  18. )
  19. //-----------------------------------------------------------------------------
  20. // NOTE: not goroutine-safe.
  21. type State struct {
  22. DB dbm.DB
  23. LastBlockHeight uint
  24. LastBlockHash []byte
  25. LastBlockParts types.PartSetHeader
  26. LastBlockTime time.Time
  27. BondedValidators *ValidatorSet
  28. LastBondedValidators *ValidatorSet
  29. UnbondingValidators *ValidatorSet
  30. accounts merkle.Tree // Shouldn't be accessed directly.
  31. validatorInfos merkle.Tree // Shouldn't be accessed directly.
  32. }
  33. func LoadState(db dbm.DB) *State {
  34. s := &State{DB: db}
  35. buf := db.Get(stateKey)
  36. if len(buf) == 0 {
  37. return nil
  38. } else {
  39. r, n, err := bytes.NewReader(buf), new(int64), new(error)
  40. s.LastBlockHeight = binary.ReadUvarint(r, n, err)
  41. s.LastBlockHash = binary.ReadByteSlice(r, n, err)
  42. s.LastBlockParts = binary.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader)
  43. s.LastBlockTime = binary.ReadTime(r, n, err)
  44. s.BondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  45. s.LastBondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  46. s.UnbondingValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  47. accountsHash := binary.ReadByteSlice(r, n, err)
  48. s.accounts = merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
  49. s.accounts.Load(accountsHash)
  50. validatorInfosHash := binary.ReadByteSlice(r, n, err)
  51. s.validatorInfos = merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db)
  52. s.validatorInfos.Load(validatorInfosHash)
  53. if *err != nil {
  54. panic(*err)
  55. }
  56. // TODO: ensure that buf is completely read.
  57. }
  58. return s
  59. }
  60. func (s *State) Save() {
  61. s.accounts.Save()
  62. s.validatorInfos.Save()
  63. buf, n, err := new(bytes.Buffer), new(int64), new(error)
  64. binary.WriteUvarint(s.LastBlockHeight, buf, n, err)
  65. binary.WriteByteSlice(s.LastBlockHash, buf, n, err)
  66. binary.WriteBinary(s.LastBlockParts, buf, n, err)
  67. binary.WriteTime(s.LastBlockTime, buf, n, err)
  68. binary.WriteBinary(s.BondedValidators, buf, n, err)
  69. binary.WriteBinary(s.LastBondedValidators, buf, n, err)
  70. binary.WriteBinary(s.UnbondingValidators, buf, n, err)
  71. binary.WriteByteSlice(s.accounts.Hash(), buf, n, err)
  72. binary.WriteByteSlice(s.validatorInfos.Hash(), buf, n, err)
  73. if *err != nil {
  74. panic(*err)
  75. }
  76. s.DB.Set(stateKey, buf.Bytes())
  77. }
  78. // CONTRACT:
  79. // Copy() is a cheap way to take a snapshot,
  80. // as if State were copied by value.
  81. func (s *State) Copy() *State {
  82. return &State{
  83. DB: s.DB,
  84. LastBlockHeight: s.LastBlockHeight,
  85. LastBlockHash: s.LastBlockHash,
  86. LastBlockParts: s.LastBlockParts,
  87. LastBlockTime: s.LastBlockTime,
  88. BondedValidators: s.BondedValidators.Copy(), // TODO remove need for Copy() here.
  89. LastBondedValidators: s.LastBondedValidators.Copy(), // That is, make updates to the validator set
  90. UnbondingValidators: s.UnbondingValidators.Copy(), // copy the valSet lazily.
  91. accounts: s.accounts.Copy(),
  92. validatorInfos: s.validatorInfos.Copy(),
  93. }
  94. }
  95. // Returns a hash that represents the state data, excluding Last*
  96. func (s *State) Hash() []byte {
  97. hashables := []merkle.Hashable{
  98. s.BondedValidators,
  99. s.UnbondingValidators,
  100. s.accounts,
  101. s.validatorInfos,
  102. }
  103. return merkle.HashFromHashables(hashables)
  104. }
  105. // Mutates the block in place and updates it with new state hash.
  106. func (s *State) SetBlockStateHash(block *types.Block) error {
  107. sCopy := s.Copy()
  108. err := execBlock(sCopy, block, types.PartSetHeader{})
  109. if err != nil {
  110. return err
  111. }
  112. // Set block.StateHash
  113. block.StateHash = sCopy.Hash()
  114. return nil
  115. }
  116. //-------------------------------------
  117. // State.accounts
  118. // The returned Account is a copy, so mutating it
  119. // has no side effects.
  120. // Implements Statelike
  121. func (s *State) GetAccount(address []byte) *account.Account {
  122. _, acc := s.accounts.Get(address)
  123. if acc == nil {
  124. return nil
  125. }
  126. return acc.(*account.Account).Copy()
  127. }
  128. // The account is copied before setting, so mutating it
  129. // afterwards has no side effects.
  130. // Implements Statelike
  131. func (s *State) UpdateAccount(account *account.Account) bool {
  132. return s.accounts.Set(account.Address, account.Copy())
  133. }
  134. // Implements Statelike
  135. func (s *State) RemoveAccount(address []byte) bool {
  136. _, removed := s.accounts.Remove(address)
  137. return removed
  138. }
  139. // The returned Account is a copy, so mutating it
  140. // has no side effects.
  141. func (s *State) GetAccounts() merkle.Tree {
  142. return s.accounts.Copy()
  143. }
  144. // State.accounts
  145. //-------------------------------------
  146. // State.validators
  147. // The returned ValidatorInfo is a copy, so mutating it
  148. // has no side effects.
  149. func (s *State) GetValidatorInfo(address []byte) *ValidatorInfo {
  150. _, valInfo := s.validatorInfos.Get(address)
  151. if valInfo == nil {
  152. return nil
  153. }
  154. return valInfo.(*ValidatorInfo).Copy()
  155. }
  156. // Returns false if new, true if updated.
  157. // The valInfo is copied before setting, so mutating it
  158. // afterwards has no side effects.
  159. func (s *State) SetValidatorInfo(valInfo *ValidatorInfo) (updated bool) {
  160. return s.validatorInfos.Set(valInfo.Address, valInfo.Copy())
  161. }
  162. func (s *State) unbondValidator(val *Validator) {
  163. // Move validator to UnbondingValidators
  164. val, removed := s.BondedValidators.Remove(val.Address)
  165. if !removed {
  166. panic("Couldn't remove validator for unbonding")
  167. }
  168. val.UnbondHeight = s.LastBlockHeight + 1
  169. added := s.UnbondingValidators.Add(val)
  170. if !added {
  171. panic("Couldn't add validator for unbonding")
  172. }
  173. }
  174. func (s *State) rebondValidator(val *Validator) {
  175. // Move validator to BondingValidators
  176. val, removed := s.UnbondingValidators.Remove(val.Address)
  177. if !removed {
  178. panic("Couldn't remove validator for rebonding")
  179. }
  180. val.BondHeight = s.LastBlockHeight + 1
  181. added := s.BondedValidators.Add(val)
  182. if !added {
  183. panic("Couldn't add validator for rebonding")
  184. }
  185. }
  186. func (s *State) releaseValidator(val *Validator) {
  187. // Update validatorInfo
  188. valInfo := s.GetValidatorInfo(val.Address)
  189. if valInfo == nil {
  190. panic("Couldn't find validatorInfo for release")
  191. }
  192. valInfo.ReleasedHeight = s.LastBlockHeight + 1
  193. s.SetValidatorInfo(valInfo)
  194. // Send coins back to UnbondTo outputs
  195. accounts, err := getOrMakeAccounts(s, nil, valInfo.UnbondTo)
  196. if err != nil {
  197. panic("Couldn't get or make unbondTo accounts")
  198. }
  199. adjustByOutputs(accounts, valInfo.UnbondTo)
  200. for _, acc := range accounts {
  201. s.UpdateAccount(acc)
  202. }
  203. // Remove validator from UnbondingValidators
  204. _, removed := s.UnbondingValidators.Remove(val.Address)
  205. if !removed {
  206. panic("Couldn't remove validator for release")
  207. }
  208. }
  209. func (s *State) destroyValidator(val *Validator) {
  210. // Update validatorInfo
  211. valInfo := s.GetValidatorInfo(val.Address)
  212. if valInfo == nil {
  213. panic("Couldn't find validatorInfo for release")
  214. }
  215. valInfo.DestroyedHeight = s.LastBlockHeight + 1
  216. valInfo.DestroyedAmount = val.VotingPower
  217. s.SetValidatorInfo(valInfo)
  218. // Remove validator
  219. _, removed := s.BondedValidators.Remove(val.Address)
  220. if !removed {
  221. _, removed := s.UnbondingValidators.Remove(val.Address)
  222. if !removed {
  223. panic("Couldn't remove validator for destruction")
  224. }
  225. }
  226. }
  227. // State.validators
  228. //-------------------------------------
  229. // State.storage
  230. func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) {
  231. storage = merkle.NewIAVLTree(binary.BasicCodec, binary.BasicCodec, 1024, s.DB)
  232. storage.Load(hash)
  233. return storage
  234. }
  235. // State.storage
  236. //-------------------------------------
  237. //-----------------------------------------------------------------------------
  238. type InvalidTxError struct {
  239. Tx types.Tx
  240. Reason error
  241. }
  242. func (txErr InvalidTxError) Error() string {
  243. return fmt.Sprintf("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
  244. }