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.

543 lines
16 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
  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. // database keys
  16. var (
  17. stateKey = []byte("stateKey")
  18. )
  19. func calcValidatorsKey(height int64) []byte {
  20. return []byte(cmn.Fmt("validatorsKey:%v", height))
  21. }
  22. func calcConsensusParamsKey(height int64) []byte {
  23. return []byte(cmn.Fmt("consensusParamsKey:%v", height))
  24. }
  25. func calcABCIResponsesKey(height int64) []byte {
  26. return []byte(cmn.Fmt("abciResponsesKey:%v", height))
  27. }
  28. //-----------------------------------------------------------------------------
  29. // State is a short description of the latest committed block of the Tendermint consensus.
  30. // It keeps all information necessary to validate new blocks,
  31. // including the last validator set and the consensus params.
  32. // All fields are exposed so the struct can be easily serialized,
  33. // but the fields should only be changed by calling state.SetBlockAndValidators.
  34. // NOTE: not goroutine-safe.
  35. type State struct {
  36. // mtx for writing to db
  37. mtx sync.Mutex
  38. db dbm.DB
  39. // Immutable
  40. ChainID string
  41. // Exposed fields are updated by SetBlockAndValidators.
  42. // LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
  43. LastBlockHeight int64
  44. LastBlockTotalTx int64
  45. LastBlockID types.BlockID
  46. LastBlockTime time.Time
  47. // LastValidators is used to validate block.LastCommit.
  48. // Validators are persisted to the database separately every time they change,
  49. // so we can query for historical validator sets.
  50. // Note that if s.LastBlockHeight causes a valset change,
  51. // we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1
  52. Validators *types.ValidatorSet
  53. LastValidators *types.ValidatorSet
  54. LastHeightValidatorsChanged int64
  55. // Consensus parameters used for validating blocks.
  56. // Changes returned by EndBlock and updated after Commit.
  57. ConsensusParams types.ConsensusParams
  58. LastHeightConsensusParamsChanged int64
  59. // Merkle root of the results from executing prev block
  60. LastResultsHash []byte
  61. // The latest AppHash we've received from calling abci.Commit()
  62. AppHash []byte
  63. logger log.Logger
  64. }
  65. // GetState loads the most recent state from the database,
  66. // or creates a new one from the given genesisFile and persists the result
  67. // to the database.
  68. func GetState(stateDB dbm.DB, genesisFile string) (*State, error) {
  69. state := LoadState(stateDB)
  70. if state == nil {
  71. var err error
  72. state, err = MakeGenesisStateFromFile(stateDB, genesisFile)
  73. if err != nil {
  74. return nil, err
  75. }
  76. state.Save()
  77. }
  78. return state, nil
  79. }
  80. // LoadState loads the State from the database.
  81. func LoadState(db dbm.DB) *State {
  82. return loadState(db, stateKey)
  83. }
  84. func loadState(db dbm.DB, key []byte) *State {
  85. buf := db.Get(key)
  86. if len(buf) == 0 {
  87. return nil
  88. }
  89. s := &State{db: db}
  90. r, n, err := bytes.NewReader(buf), new(int), new(error)
  91. wire.ReadBinaryPtr(&s, r, 0, n, err)
  92. if *err != nil {
  93. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  94. cmn.Exit(cmn.Fmt(`LoadState: Data has been corrupted or its spec has changed:
  95. %v\n`, *err))
  96. }
  97. // TODO: ensure that buf is completely read.
  98. return s
  99. }
  100. // SetLogger sets the logger on the State.
  101. func (s *State) SetLogger(l log.Logger) {
  102. s.logger = l
  103. }
  104. // Copy makes a copy of the State for mutating.
  105. func (s *State) Copy() *State {
  106. return &State{
  107. db: s.db,
  108. ChainID: s.ChainID,
  109. LastBlockHeight: s.LastBlockHeight,
  110. LastBlockTotalTx: s.LastBlockTotalTx,
  111. LastBlockID: s.LastBlockID,
  112. LastBlockTime: s.LastBlockTime,
  113. Validators: s.Validators.Copy(),
  114. LastValidators: s.LastValidators.Copy(),
  115. LastHeightValidatorsChanged: s.LastHeightValidatorsChanged,
  116. ConsensusParams: s.ConsensusParams,
  117. LastHeightConsensusParamsChanged: s.LastHeightConsensusParamsChanged,
  118. AppHash: s.AppHash,
  119. LastResultsHash: s.LastResultsHash,
  120. logger: s.logger,
  121. }
  122. }
  123. // Save persists the State to the database.
  124. func (s *State) Save() {
  125. s.mtx.Lock()
  126. defer s.mtx.Unlock()
  127. s.saveValidatorsInfo()
  128. s.saveConsensusParamsInfo()
  129. s.db.SetSync(stateKey, s.Bytes())
  130. }
  131. // SaveABCIResponses persists the ABCIResponses to the database.
  132. // This is useful in case we crash after app.Commit and before s.Save().
  133. // Responses are indexed by height so they can also be loaded later to produce Merkle proofs.
  134. func (s *State) SaveABCIResponses(height int64, abciResponses *ABCIResponses) {
  135. s.db.SetSync(calcABCIResponsesKey(height), abciResponses.Bytes())
  136. }
  137. // LoadABCIResponses loads the ABCIResponses for the given height from the database.
  138. // This is useful for recovering from crashes where we called app.Commit and before we called
  139. // s.Save(). It can also be used to produce Merkle proofs of the result of txs.
  140. func (s *State) LoadABCIResponses(height int64) (*ABCIResponses, error) {
  141. buf := s.db.Get(calcABCIResponsesKey(height))
  142. if len(buf) == 0 {
  143. return nil, ErrNoABCIResponsesForHeight{height}
  144. }
  145. abciResponses := new(ABCIResponses)
  146. r, n, err := bytes.NewReader(buf), new(int), new(error)
  147. wire.ReadBinaryPtr(abciResponses, r, 0, n, err)
  148. if *err != nil {
  149. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  150. cmn.Exit(cmn.Fmt(`LoadABCIResponses: Data has been corrupted or its spec has
  151. changed: %v\n`, *err))
  152. }
  153. // TODO: ensure that buf is completely read.
  154. return abciResponses, nil
  155. }
  156. // LoadValidators loads the ValidatorSet for a given height.
  157. // Returns ErrNoValSetForHeight if the validator set can't be found for this height.
  158. func (s *State) LoadValidators(height int64) (*types.ValidatorSet, error) {
  159. valInfo := s.loadValidatorsInfo(height)
  160. if valInfo == nil {
  161. return nil, ErrNoValSetForHeight{height}
  162. }
  163. if valInfo.ValidatorSet == nil {
  164. valInfo = s.loadValidatorsInfo(valInfo.LastHeightChanged)
  165. if valInfo == nil {
  166. cmn.PanicSanity(fmt.Sprintf(`Couldn't find validators at height %d as
  167. last changed from height %d`, valInfo.LastHeightChanged, height))
  168. }
  169. }
  170. return valInfo.ValidatorSet, nil
  171. }
  172. func (s *State) loadValidatorsInfo(height int64) *ValidatorsInfo {
  173. buf := s.db.Get(calcValidatorsKey(height))
  174. if len(buf) == 0 {
  175. return nil
  176. }
  177. v := new(ValidatorsInfo)
  178. r, n, err := bytes.NewReader(buf), new(int), new(error)
  179. wire.ReadBinaryPtr(v, r, 0, n, err)
  180. if *err != nil {
  181. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  182. cmn.Exit(cmn.Fmt(`LoadValidators: Data has been corrupted or its spec has changed:
  183. %v\n`, *err))
  184. }
  185. // TODO: ensure that buf is completely read.
  186. return v
  187. }
  188. // saveValidatorsInfo persists the validator set for the next block to disk.
  189. // It should be called from s.Save(), right before the state itself is persisted.
  190. // If the validator set did not change after processing the latest block,
  191. // only the last height for which the validators changed is persisted.
  192. func (s *State) saveValidatorsInfo() {
  193. changeHeight := s.LastHeightValidatorsChanged
  194. nextHeight := s.LastBlockHeight + 1
  195. valInfo := &ValidatorsInfo{
  196. LastHeightChanged: changeHeight,
  197. }
  198. if changeHeight == nextHeight {
  199. valInfo.ValidatorSet = s.Validators
  200. }
  201. s.db.SetSync(calcValidatorsKey(nextHeight), valInfo.Bytes())
  202. }
  203. // LoadConsensusParams loads the ConsensusParams for a given height.
  204. func (s *State) LoadConsensusParams(height int64) (types.ConsensusParams, error) {
  205. empty := types.ConsensusParams{}
  206. paramsInfo := s.loadConsensusParamsInfo(height)
  207. if paramsInfo == nil {
  208. return empty, ErrNoConsensusParamsForHeight{height}
  209. }
  210. if paramsInfo.ConsensusParams == empty {
  211. paramsInfo = s.loadConsensusParamsInfo(paramsInfo.LastHeightChanged)
  212. if paramsInfo == nil {
  213. cmn.PanicSanity(fmt.Sprintf(`Couldn't find consensus params at height %d as
  214. last changed from height %d`, paramsInfo.LastHeightChanged, height))
  215. }
  216. }
  217. return paramsInfo.ConsensusParams, nil
  218. }
  219. func (s *State) loadConsensusParamsInfo(height int64) *ConsensusParamsInfo {
  220. buf := s.db.Get(calcConsensusParamsKey(height))
  221. if len(buf) == 0 {
  222. return nil
  223. }
  224. paramsInfo := new(ConsensusParamsInfo)
  225. r, n, err := bytes.NewReader(buf), new(int), new(error)
  226. wire.ReadBinaryPtr(paramsInfo, r, 0, n, err)
  227. if *err != nil {
  228. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  229. cmn.Exit(cmn.Fmt(`LoadConsensusParams: Data has been corrupted or its spec has changed:
  230. %v\n`, *err))
  231. }
  232. // TODO: ensure that buf is completely read.
  233. return paramsInfo
  234. }
  235. // saveConsensusParamsInfo persists the consensus params for the next block to disk.
  236. // It should be called from s.Save(), right before the state itself is persisted.
  237. // If the consensus params did not change after processing the latest block,
  238. // only the last height for which they changed is persisted.
  239. func (s *State) saveConsensusParamsInfo() {
  240. changeHeight := s.LastHeightConsensusParamsChanged
  241. nextHeight := s.LastBlockHeight + 1
  242. paramsInfo := &ConsensusParamsInfo{
  243. LastHeightChanged: changeHeight,
  244. }
  245. if changeHeight == nextHeight {
  246. paramsInfo.ConsensusParams = s.ConsensusParams
  247. }
  248. s.db.SetSync(calcConsensusParamsKey(nextHeight), paramsInfo.Bytes())
  249. }
  250. // Equals returns true if the States are identical.
  251. func (s *State) Equals(s2 *State) bool {
  252. return bytes.Equal(s.Bytes(), s2.Bytes())
  253. }
  254. // Bytes serializes the State using go-wire.
  255. func (s *State) Bytes() []byte {
  256. return wire.BinaryBytes(s)
  257. }
  258. // SetBlockAndValidators mutates State variables
  259. // to update block and validators after running EndBlock.
  260. func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader types.PartSetHeader,
  261. abciResponses *ABCIResponses) error {
  262. // copy the valset so we can apply changes from EndBlock
  263. // and update s.LastValidators and s.Validators
  264. prevValSet := s.Validators.Copy()
  265. nextValSet := prevValSet.Copy()
  266. // update the validator set with the latest abciResponses
  267. if len(abciResponses.EndBlock.ValidatorUpdates) > 0 {
  268. err := updateValidators(nextValSet, abciResponses.EndBlock.ValidatorUpdates)
  269. if err != nil {
  270. return fmt.Errorf("Error changing validator set: %v", err)
  271. }
  272. // change results from this height but only applies to the next height
  273. s.LastHeightValidatorsChanged = header.Height + 1
  274. }
  275. // Update validator accums and set state variables
  276. nextValSet.IncrementAccum(1)
  277. // update the params with the latest abciResponses
  278. nextParams := s.ConsensusParams
  279. if abciResponses.EndBlock.ConsensusParamUpdates != nil {
  280. // NOTE: must not mutate s.ConsensusParams
  281. nextParams = s.ConsensusParams.Update(abciResponses.EndBlock.ConsensusParamUpdates)
  282. err := nextParams.Validate()
  283. if err != nil {
  284. return fmt.Errorf("Error updating consensus params: %v", err)
  285. }
  286. // change results from this height but only applies to the next height
  287. s.LastHeightConsensusParamsChanged = header.Height + 1
  288. }
  289. s.setBlockAndValidators(header.Height,
  290. header.NumTxs,
  291. types.BlockID{header.Hash(), blockPartsHeader},
  292. header.Time,
  293. nextValSet,
  294. nextParams,
  295. abciResponses.ResultsHash())
  296. return nil
  297. }
  298. func (s *State) setBlockAndValidators(height int64,
  299. newTxs int64, blockID types.BlockID, blockTime time.Time,
  300. valSet *types.ValidatorSet,
  301. params types.ConsensusParams,
  302. resultsHash []byte) {
  303. s.LastBlockHeight = height
  304. s.LastBlockTotalTx += newTxs
  305. s.LastBlockID = blockID
  306. s.LastBlockTime = blockTime
  307. s.LastValidators = s.Validators.Copy()
  308. s.Validators = valSet
  309. s.ConsensusParams = params
  310. s.LastResultsHash = resultsHash
  311. }
  312. // GetValidators returns the last and current validator sets.
  313. func (s *State) GetValidators() (last *types.ValidatorSet, current *types.ValidatorSet) {
  314. return s.LastValidators, s.Validators
  315. }
  316. // VerifyEvidence verifies the evidence fully by checking it is internally
  317. // consistent and corresponds to an existing or previous validator.
  318. // It returns the priority of this evidence, or an error.
  319. // NOTE: return error may be ErrNoValSetForHeight, in which case the validator set
  320. // for the evidence height could not be loaded.
  321. func (s *State) VerifyEvidence(evidence types.Evidence) (priority int64, err error) {
  322. evidenceAge := s.LastBlockHeight - evidence.Height()
  323. maxAge := s.ConsensusParams.EvidenceParams.MaxAge
  324. if evidenceAge > maxAge {
  325. return priority, fmt.Errorf("Evidence from height %d is too old. Min height is %d",
  326. evidence.Height(), s.LastBlockHeight-maxAge)
  327. }
  328. if err := evidence.Verify(s.ChainID); err != nil {
  329. return priority, err
  330. }
  331. // The address must have been an active validator at the height
  332. ev := evidence
  333. height, addr, idx := ev.Height(), ev.Address(), ev.Index()
  334. valset, err := s.LoadValidators(height)
  335. if err != nil {
  336. // XXX/TODO: what do we do if we can't load the valset?
  337. // eg. if we have pruned the state or height is too high?
  338. return priority, err
  339. }
  340. valIdx, val := valset.GetByAddress(addr)
  341. if val == nil {
  342. return priority, fmt.Errorf("Address %X was not a validator at height %d", addr, height)
  343. } else if idx != valIdx {
  344. return priority, fmt.Errorf("Address %X was validator %d at height %d, not %d", addr, valIdx, height, idx)
  345. }
  346. priority = val.VotingPower
  347. return priority, nil
  348. }
  349. //------------------------------------------------------------------------
  350. // ABCIResponses retains the responses
  351. // of the various ABCI calls during block processing.
  352. // It is persisted to disk for each height before calling Commit.
  353. type ABCIResponses struct {
  354. DeliverTx []*abci.ResponseDeliverTx
  355. EndBlock *abci.ResponseEndBlock
  356. }
  357. // NewABCIResponses returns a new ABCIResponses
  358. func NewABCIResponses(block *types.Block) *ABCIResponses {
  359. return &ABCIResponses{
  360. DeliverTx: make([]*abci.ResponseDeliverTx, block.NumTxs),
  361. }
  362. }
  363. // Bytes serializes the ABCIResponse using go-wire
  364. func (a *ABCIResponses) Bytes() []byte {
  365. return wire.BinaryBytes(*a)
  366. }
  367. func (a *ABCIResponses) ResultsHash() []byte {
  368. results := types.NewResults(a.DeliverTx)
  369. return results.Hash()
  370. }
  371. //-----------------------------------------------------------------------------
  372. // ValidatorsInfo represents the latest validator set, or the last height it changed
  373. type ValidatorsInfo struct {
  374. ValidatorSet *types.ValidatorSet
  375. LastHeightChanged int64
  376. }
  377. // Bytes serializes the ValidatorsInfo using go-wire
  378. func (valInfo *ValidatorsInfo) Bytes() []byte {
  379. return wire.BinaryBytes(*valInfo)
  380. }
  381. //-----------------------------------------------------------------------------
  382. // ConsensusParamsInfo represents the latest consensus params, or the last height it changed
  383. type ConsensusParamsInfo struct {
  384. ConsensusParams types.ConsensusParams
  385. LastHeightChanged int64
  386. }
  387. // Bytes serializes the ConsensusParamsInfo using go-wire
  388. func (params ConsensusParamsInfo) Bytes() []byte {
  389. return wire.BinaryBytes(params)
  390. }
  391. //------------------------------------------------------------------------
  392. // Genesis
  393. // MakeGenesisStateFromFile reads and unmarshals state from the given
  394. // file.
  395. //
  396. // Used during replay and in tests.
  397. func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*State, error) {
  398. genDoc, err := MakeGenesisDocFromFile(genDocFile)
  399. if err != nil {
  400. return nil, err
  401. }
  402. return MakeGenesisState(db, genDoc)
  403. }
  404. // MakeGenesisDocFromFile reads and unmarshals genesis doc from the given file.
  405. func MakeGenesisDocFromFile(genDocFile string) (*types.GenesisDoc, error) {
  406. genDocJSON, err := ioutil.ReadFile(genDocFile)
  407. if err != nil {
  408. return nil, fmt.Errorf("Couldn't read GenesisDoc file: %v", err)
  409. }
  410. genDoc, err := types.GenesisDocFromJSON(genDocJSON)
  411. if err != nil {
  412. return nil, fmt.Errorf("Error reading GenesisDoc: %v", err)
  413. }
  414. return genDoc, nil
  415. }
  416. // MakeGenesisState creates state from types.GenesisDoc.
  417. func MakeGenesisState(db dbm.DB, genDoc *types.GenesisDoc) (*State, error) {
  418. err := genDoc.ValidateAndComplete()
  419. if err != nil {
  420. return nil, fmt.Errorf("Error in genesis file: %v", err)
  421. }
  422. // Make validators slice
  423. validators := make([]*types.Validator, len(genDoc.Validators))
  424. for i, val := range genDoc.Validators {
  425. pubKey := val.PubKey
  426. address := pubKey.Address()
  427. // Make validator
  428. validators[i] = &types.Validator{
  429. Address: address,
  430. PubKey: pubKey,
  431. VotingPower: val.Power,
  432. }
  433. }
  434. return &State{
  435. db: db,
  436. ChainID: genDoc.ChainID,
  437. LastBlockHeight: 0,
  438. LastBlockID: types.BlockID{},
  439. LastBlockTime: genDoc.GenesisTime,
  440. Validators: types.NewValidatorSet(validators),
  441. LastValidators: types.NewValidatorSet(nil),
  442. LastHeightValidatorsChanged: 1,
  443. ConsensusParams: *genDoc.ConsensusParams,
  444. LastHeightConsensusParamsChanged: 1,
  445. AppHash: genDoc.AppHash,
  446. }, nil
  447. }