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.

188 lines
5.5 KiB

8 years ago
10 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "time"
  7. wire "github.com/tendermint/go-wire"
  8. "github.com/tendermint/tendermint/types"
  9. )
  10. // database keys
  11. var (
  12. stateKey = []byte("stateKey")
  13. )
  14. //-----------------------------------------------------------------------------
  15. // State is a short description of the latest committed block of the Tendermint consensus.
  16. // It keeps all information necessary to validate new blocks,
  17. // including the last validator set and the consensus params.
  18. // All fields are exposed so the struct can be easily serialized,
  19. // but none of them should be mutated directly.
  20. // Instead, use state.Copy() ro state.NextState(...).
  21. // NOTE: not goroutine-safe.
  22. type State struct {
  23. // Immutable
  24. ChainID string
  25. // LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
  26. LastBlockHeight int64
  27. LastBlockTotalTx int64
  28. LastBlockID types.BlockID
  29. LastBlockTime time.Time
  30. // LastValidators is used to validate block.LastCommit.
  31. // Validators are persisted to the database separately every time they change,
  32. // so we can query for historical validator sets.
  33. // Note that if s.LastBlockHeight causes a valset change,
  34. // we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1
  35. Validators *types.ValidatorSet
  36. LastValidators *types.ValidatorSet
  37. LastHeightValidatorsChanged int64
  38. // Consensus parameters used for validating blocks.
  39. // Changes returned by EndBlock and updated after Commit.
  40. ConsensusParams types.ConsensusParams
  41. LastHeightConsensusParamsChanged int64
  42. // Merkle root of the results from executing prev block
  43. LastResultsHash []byte
  44. // The latest AppHash we've received from calling abci.Commit()
  45. AppHash []byte
  46. }
  47. // Copy makes a copy of the State for mutating.
  48. func (s State) Copy() State {
  49. return State{
  50. ChainID: s.ChainID,
  51. LastBlockHeight: s.LastBlockHeight,
  52. LastBlockTotalTx: s.LastBlockTotalTx,
  53. LastBlockID: s.LastBlockID,
  54. LastBlockTime: s.LastBlockTime,
  55. Validators: s.Validators.Copy(),
  56. LastValidators: s.LastValidators.Copy(),
  57. LastHeightValidatorsChanged: s.LastHeightValidatorsChanged,
  58. ConsensusParams: s.ConsensusParams,
  59. LastHeightConsensusParamsChanged: s.LastHeightConsensusParamsChanged,
  60. AppHash: s.AppHash,
  61. LastResultsHash: s.LastResultsHash,
  62. }
  63. }
  64. // Equals returns true if the States are identical.
  65. func (s State) Equals(s2 State) bool {
  66. return bytes.Equal(s.Bytes(), s2.Bytes())
  67. }
  68. // Bytes serializes the State using go-wire.
  69. func (s State) Bytes() []byte {
  70. return wire.BinaryBytes(s)
  71. }
  72. // IsEmpty returns true if the State is equal to the empty State.
  73. func (s State) IsEmpty() bool {
  74. return s.LastBlockHeight == 0 // XXX can't compare to Empty
  75. }
  76. // GetValidators returns the last and current validator sets.
  77. func (s State) GetValidators() (last *types.ValidatorSet, current *types.ValidatorSet) {
  78. return s.LastValidators, s.Validators
  79. }
  80. //------------------------------------------------------------------------
  81. // Create a block from the latest state
  82. // MakeBlock builds a block with the given txs and commit from the current state.
  83. func (s State) MakeBlock(height int64, txs []types.Tx, commit *types.Commit) (*types.Block, *types.PartSet) {
  84. // build base block
  85. block := types.MakeBlock(height, txs, commit)
  86. // fill header with state data
  87. block.ChainID = s.ChainID
  88. block.TotalTxs = s.LastBlockTotalTx + block.NumTxs
  89. block.LastBlockID = s.LastBlockID
  90. block.ValidatorsHash = s.Validators.Hash()
  91. block.AppHash = s.AppHash
  92. block.ConsensusHash = s.ConsensusParams.Hash()
  93. block.LastResultsHash = s.LastResultsHash
  94. return block, block.MakePartSet(s.ConsensusParams.BlockGossip.BlockPartSizeBytes)
  95. }
  96. //------------------------------------------------------------------------
  97. // Genesis
  98. // MakeGenesisStateFromFile reads and unmarshals state from the given
  99. // file.
  100. //
  101. // Used during replay and in tests.
  102. func MakeGenesisStateFromFile(genDocFile string) (State, error) {
  103. genDoc, err := MakeGenesisDocFromFile(genDocFile)
  104. if err != nil {
  105. return State{}, err
  106. }
  107. return MakeGenesisState(genDoc)
  108. }
  109. // MakeGenesisDocFromFile reads and unmarshals genesis doc from the given file.
  110. func MakeGenesisDocFromFile(genDocFile string) (*types.GenesisDoc, error) {
  111. genDocJSON, err := ioutil.ReadFile(genDocFile)
  112. if err != nil {
  113. return nil, fmt.Errorf("Couldn't read GenesisDoc file: %v", err)
  114. }
  115. genDoc, err := types.GenesisDocFromJSON(genDocJSON)
  116. if err != nil {
  117. return nil, fmt.Errorf("Error reading GenesisDoc: %v", err)
  118. }
  119. return genDoc, nil
  120. }
  121. // MakeGenesisState creates state from types.GenesisDoc.
  122. func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
  123. err := genDoc.ValidateAndComplete()
  124. if err != nil {
  125. return State{}, fmt.Errorf("Error in genesis file: %v", err)
  126. }
  127. // Make validators slice
  128. validators := make([]*types.Validator, len(genDoc.Validators))
  129. for i, val := range genDoc.Validators {
  130. pubKey := val.PubKey
  131. address := pubKey.Address()
  132. // Make validator
  133. validators[i] = &types.Validator{
  134. Address: address,
  135. PubKey: pubKey,
  136. VotingPower: val.Power,
  137. }
  138. }
  139. return State{
  140. ChainID: genDoc.ChainID,
  141. LastBlockHeight: 0,
  142. LastBlockID: types.BlockID{},
  143. LastBlockTime: genDoc.GenesisTime,
  144. Validators: types.NewValidatorSet(validators),
  145. LastValidators: types.NewValidatorSet(nil),
  146. LastHeightValidatorsChanged: 1,
  147. ConsensusParams: *genDoc.ConsensusParams,
  148. LastHeightConsensusParamsChanged: 1,
  149. AppHash: genDoc.AppHash,
  150. }, nil
  151. }