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.

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