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.

388 lines
11 KiB

8 years ago
8 years ago
8 years ago
10 years ago
8 years ago
10 years ago
8 years ago
8 years ago
8 years ago
8 years ago
7 years ago
8 years ago
8 years ago
8 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "sync"
  7. "time"
  8. abci "github.com/tendermint/abci/types"
  9. cmn "github.com/tendermint/tmlibs/common"
  10. dbm "github.com/tendermint/tmlibs/db"
  11. "github.com/tendermint/tmlibs/log"
  12. wire "github.com/tendermint/go-wire"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. var (
  16. stateKey = []byte("stateKey")
  17. abciResponsesKey = []byte("abciResponsesKey")
  18. )
  19. func calcValidatorsKey(height int64) []byte {
  20. return []byte(cmn.Fmt("validatorsKey:%v", height))
  21. }
  22. //-----------------------------------------------------------------------------
  23. // State represents the latest committed state of the Tendermint consensus,
  24. // including the last committed block and validator set.
  25. // Newly committed blocks are validated and executed against the State.
  26. // NOTE: not goroutine-safe.
  27. type State struct {
  28. // mtx for writing to db
  29. mtx sync.Mutex
  30. db dbm.DB
  31. ChainID string
  32. // Consensus parameters used for validating blocks
  33. Params types.ConsensusParams
  34. // These fields are updated by SetBlockAndValidators.
  35. // LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
  36. // LastValidators is used to validate block.LastCommit.
  37. LastBlockHeight int64
  38. LastBlockTotalTx int64
  39. LastBlockID types.BlockID
  40. LastBlockTime time.Time
  41. Validators *types.ValidatorSet
  42. LastValidators *types.ValidatorSet
  43. // When a block returns a validator set change via EndBlock,
  44. // the change only applies to the next block.
  45. // So, if s.LastBlockHeight causes a valset change,
  46. // we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1
  47. LastHeightValidatorsChanged int64
  48. // AppHash is updated after Commit
  49. AppHash []byte
  50. logger log.Logger
  51. }
  52. // GetState loads the most recent state from the database,
  53. // or creates a new one from the given genesisFile and persists the result
  54. // to the database.
  55. func GetState(stateDB dbm.DB, genesisFile string) (*State, error) {
  56. state := LoadState(stateDB)
  57. if state == nil {
  58. var err error
  59. state, err = MakeGenesisStateFromFile(stateDB, genesisFile)
  60. if err != nil {
  61. return nil, err
  62. }
  63. state.Save()
  64. }
  65. return state, nil
  66. }
  67. // LoadState loads the State from the database.
  68. func LoadState(db dbm.DB) *State {
  69. return loadState(db, stateKey)
  70. }
  71. func loadState(db dbm.DB, key []byte) *State {
  72. buf := db.Get(key)
  73. if len(buf) == 0 {
  74. return nil
  75. }
  76. s := &State{db: db}
  77. r, n, err := bytes.NewReader(buf), new(int), new(error)
  78. wire.ReadBinaryPtr(&s, r, 0, n, err)
  79. if *err != nil {
  80. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  81. cmn.Exit(cmn.Fmt(`LoadState: Data has been corrupted or its spec has changed:
  82. %v\n`, *err))
  83. }
  84. // TODO: ensure that buf is completely read.
  85. return s
  86. }
  87. // SetLogger sets the logger on the State.
  88. func (s *State) SetLogger(l log.Logger) {
  89. s.logger = l
  90. }
  91. // Copy makes a copy of the State for mutating.
  92. func (s *State) Copy() *State {
  93. return &State{
  94. db: s.db,
  95. LastBlockHeight: s.LastBlockHeight,
  96. LastBlockTotalTx: s.LastBlockTotalTx,
  97. LastBlockID: s.LastBlockID,
  98. LastBlockTime: s.LastBlockTime,
  99. Validators: s.Validators.Copy(),
  100. LastValidators: s.LastValidators.Copy(),
  101. AppHash: s.AppHash,
  102. LastHeightValidatorsChanged: s.LastHeightValidatorsChanged,
  103. logger: s.logger,
  104. ChainID: s.ChainID,
  105. Params: s.Params,
  106. }
  107. }
  108. // Save persists the State to the database.
  109. func (s *State) Save() {
  110. s.mtx.Lock()
  111. defer s.mtx.Unlock()
  112. s.saveValidatorsInfo()
  113. s.db.SetSync(stateKey, s.Bytes())
  114. }
  115. // SaveABCIResponses persists the ABCIResponses to the database.
  116. // This is useful in case we crash after app.Commit and before s.Save().
  117. func (s *State) SaveABCIResponses(abciResponses *ABCIResponses) {
  118. s.db.SetSync(abciResponsesKey, abciResponses.Bytes())
  119. }
  120. // LoadABCIResponses loads the ABCIResponses from the database.
  121. // This is useful for recovering from crashes where we called app.Commit and before we called
  122. // s.Save()
  123. func (s *State) LoadABCIResponses() *ABCIResponses {
  124. buf := s.db.Get(abciResponsesKey)
  125. if len(buf) == 0 {
  126. return nil
  127. }
  128. abciResponses := new(ABCIResponses)
  129. r, n, err := bytes.NewReader(buf), new(int), new(error)
  130. wire.ReadBinaryPtr(abciResponses, r, 0, n, err)
  131. if *err != nil {
  132. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  133. cmn.Exit(cmn.Fmt(`LoadABCIResponses: Data has been corrupted or its spec has
  134. changed: %v\n`, *err))
  135. }
  136. // TODO: ensure that buf is completely read.
  137. return abciResponses
  138. }
  139. // LoadValidators loads the ValidatorSet for a given height.
  140. func (s *State) LoadValidators(height int64) (*types.ValidatorSet, error) {
  141. valInfo := s.loadValidators(height)
  142. if valInfo == nil {
  143. return nil, ErrNoValSetForHeight{height}
  144. }
  145. if valInfo.ValidatorSet == nil {
  146. valInfo = s.loadValidators(valInfo.LastHeightChanged)
  147. if valInfo == nil {
  148. cmn.PanicSanity(fmt.Sprintf(`Couldn't find validators at height %d as
  149. last changed from height %d`, valInfo.LastHeightChanged, height))
  150. }
  151. }
  152. return valInfo.ValidatorSet, nil
  153. }
  154. func (s *State) loadValidators(height int64) *ValidatorsInfo {
  155. buf := s.db.Get(calcValidatorsKey(height))
  156. if len(buf) == 0 {
  157. return nil
  158. }
  159. v := new(ValidatorsInfo)
  160. r, n, err := bytes.NewReader(buf), new(int), new(error)
  161. wire.ReadBinaryPtr(v, r, 0, n, err)
  162. if *err != nil {
  163. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  164. cmn.Exit(cmn.Fmt(`LoadValidators: Data has been corrupted or its spec has changed:
  165. %v\n`, *err))
  166. }
  167. // TODO: ensure that buf is completely read.
  168. return v
  169. }
  170. // saveValidatorsInfo persists the validator set for the next block to disk.
  171. // It should be called from s.Save(), right before the state itself is persisted.
  172. // If the validator set did not change after processing the latest block,
  173. // only the last height for which the validators changed is persisted.
  174. func (s *State) saveValidatorsInfo() {
  175. changeHeight := s.LastHeightValidatorsChanged
  176. nextHeight := s.LastBlockHeight + 1
  177. valInfo := &ValidatorsInfo{
  178. LastHeightChanged: changeHeight,
  179. }
  180. if changeHeight == nextHeight {
  181. valInfo.ValidatorSet = s.Validators
  182. }
  183. s.db.SetSync(calcValidatorsKey(nextHeight), valInfo.Bytes())
  184. }
  185. // Equals returns true if the States are identical.
  186. func (s *State) Equals(s2 *State) bool {
  187. return bytes.Equal(s.Bytes(), s2.Bytes())
  188. }
  189. // Bytes serializes the State using go-wire.
  190. func (s *State) Bytes() []byte {
  191. return wire.BinaryBytes(s)
  192. }
  193. // SetBlockAndValidators mutates State variables
  194. // to update block and validators after running EndBlock.
  195. func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader types.PartSetHeader,
  196. abciResponses *ABCIResponses) {
  197. // copy the valset so we can apply changes from EndBlock
  198. // and update s.LastValidators and s.Validators
  199. prevValSet := s.Validators.Copy()
  200. nextValSet := prevValSet.Copy()
  201. // update the validator set with the latest abciResponses
  202. if len(abciResponses.EndBlock.Changes) > 0 {
  203. err := updateValidators(nextValSet, abciResponses.EndBlock.Changes)
  204. if err != nil {
  205. s.logger.Error("Error changing validator set", "err", err)
  206. // TODO: err or carry on?
  207. }
  208. // change results from this height but only applies to the next height
  209. s.LastHeightValidatorsChanged = header.Height + 1
  210. }
  211. // Update validator accums and set state variables
  212. nextValSet.IncrementAccum(1)
  213. nextParams := s.Params.ApplyChanges(
  214. abciResponses.EndBlock.ConsensusParamChanges)
  215. s.setBlockAndValidators(header.Height,
  216. header.NumTxs,
  217. types.BlockID{header.Hash(), blockPartsHeader},
  218. header.Time,
  219. prevValSet, nextValSet,
  220. nextParams)
  221. }
  222. func (s *State) setBlockAndValidators(height int64,
  223. newTxs int64, blockID types.BlockID, blockTime time.Time,
  224. prevValSet, nextValSet *types.ValidatorSet,
  225. nextParams types.ConsensusParams) {
  226. s.LastBlockHeight = height
  227. s.LastBlockTotalTx += newTxs
  228. s.LastBlockID = blockID
  229. s.LastBlockTime = blockTime
  230. s.Validators = nextValSet
  231. s.LastValidators = prevValSet
  232. s.Params = nextParams
  233. }
  234. // GetValidators returns the last and current validator sets.
  235. func (s *State) GetValidators() (last *types.ValidatorSet, current *types.ValidatorSet) {
  236. return s.LastValidators, s.Validators
  237. }
  238. //------------------------------------------------------------------------
  239. // ABCIResponses retains the responses of the various ABCI calls during block processing.
  240. // It is persisted to disk before calling Commit.
  241. type ABCIResponses struct {
  242. Height int64
  243. DeliverTx []*abci.ResponseDeliverTx
  244. EndBlock *abci.ResponseEndBlock
  245. txs types.Txs // reference for indexing results by hash
  246. }
  247. // NewABCIResponses returns a new ABCIResponses
  248. func NewABCIResponses(block *types.Block) *ABCIResponses {
  249. return &ABCIResponses{
  250. Height: block.Height,
  251. DeliverTx: make([]*abci.ResponseDeliverTx, block.NumTxs),
  252. txs: block.Data.Txs,
  253. }
  254. }
  255. // Bytes serializes the ABCIResponse using go-wire
  256. func (a *ABCIResponses) Bytes() []byte {
  257. return wire.BinaryBytes(*a)
  258. }
  259. //-----------------------------------------------------------------------------
  260. // ValidatorsInfo represents the latest validator set, or the last height it changed
  261. type ValidatorsInfo struct {
  262. ValidatorSet *types.ValidatorSet
  263. LastHeightChanged int64
  264. }
  265. // Bytes serializes the ValidatorsInfo using go-wire
  266. func (valInfo *ValidatorsInfo) Bytes() []byte {
  267. return wire.BinaryBytes(*valInfo)
  268. }
  269. //------------------------------------------------------------------------
  270. // Genesis
  271. // MakeGenesisStateFromFile reads and unmarshals state from the given
  272. // file.
  273. //
  274. // Used during replay and in tests.
  275. func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*State, error) {
  276. genDoc, err := MakeGenesisDocFromFile(genDocFile)
  277. if err != nil {
  278. return nil, err
  279. }
  280. return MakeGenesisState(db, genDoc)
  281. }
  282. // MakeGenesisDocFromFile reads and unmarshals genesis doc from the given file.
  283. func MakeGenesisDocFromFile(genDocFile string) (*types.GenesisDoc, error) {
  284. genDocJSON, err := ioutil.ReadFile(genDocFile)
  285. if err != nil {
  286. return nil, fmt.Errorf("Couldn't read GenesisDoc file: %v", err)
  287. }
  288. genDoc, err := types.GenesisDocFromJSON(genDocJSON)
  289. if err != nil {
  290. return nil, fmt.Errorf("Error reading GenesisDoc: %v", err)
  291. }
  292. return genDoc, nil
  293. }
  294. // MakeGenesisState creates state from types.GenesisDoc.
  295. func MakeGenesisState(db dbm.DB, genDoc *types.GenesisDoc) (*State, error) {
  296. err := genDoc.ValidateAndComplete()
  297. if err != nil {
  298. return nil, fmt.Errorf("Error in genesis file: %v", err)
  299. }
  300. // Make validators slice
  301. validators := make([]*types.Validator, len(genDoc.Validators))
  302. for i, val := range genDoc.Validators {
  303. pubKey := val.PubKey
  304. address := pubKey.Address()
  305. // Make validator
  306. validators[i] = &types.Validator{
  307. Address: address,
  308. PubKey: pubKey,
  309. VotingPower: val.Power,
  310. }
  311. }
  312. return &State{
  313. db: db,
  314. ChainID: genDoc.ChainID,
  315. Params: *genDoc.ConsensusParams,
  316. LastBlockHeight: 0,
  317. LastBlockID: types.BlockID{},
  318. LastBlockTime: genDoc.GenesisTime,
  319. Validators: types.NewValidatorSet(validators),
  320. LastValidators: types.NewValidatorSet(nil),
  321. AppHash: genDoc.AppHash,
  322. LastHeightValidatorsChanged: 1,
  323. }, nil
  324. }