Browse Source

state: save in batches within the state store (#6067)

pull/6177/head
githubsands 4 years ago
committed by GitHub
parent
commit
d5cf7831f1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 21 deletions
  1. +1
    -0
      CHANGELOG_PENDING.md
  2. +41
    -21
      state/store.go

+ 1
- 0
CHANGELOG_PENDING.md View File

@ -66,6 +66,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [types] \#5994 Reduce the use of protobuf types in core logic. (@marbar3778)
- `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams`, `sm.Version` and `version.Consensus` have become native types. They still utilize protobuf when being sent over the wire or written to disk.
- [node] \#6059 Validate and complete genesis doc before saving to state store (@silasdavis)
- [state] \#6067 Batch save state data (@githubsands & @cmwaters)
### BUG FIXES


+ 41
- 21
state/store.go View File

@ -186,31 +186,36 @@ func (store dbStore) Save(state State) error {
}
func (store dbStore) save(state State, key []byte) error {
batch := store.db.NewBatch()
defer batch.Close()
nextHeight := state.LastBlockHeight + 1
// If first block, save validators for the block.
if nextHeight == 1 {
nextHeight = state.InitialHeight
// This extra logic due to Tendermint validator set changes being delayed 1 block.
// It may get overwritten due to InitChain validator updates.
if err := store.saveValidatorsInfo(nextHeight, nextHeight, state.Validators); err != nil {
if err := store.saveValidatorsInfo(nextHeight, nextHeight, state.Validators, batch); err != nil {
return err
}
}
// Save next validators.
if err := store.saveValidatorsInfo(nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators); err != nil {
err := store.saveValidatorsInfo(nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators, batch)
if err != nil {
return err
}
// Save next consensus params.
if err := store.saveConsensusParamsInfo(nextHeight,
state.LastHeightConsensusParamsChanged, state.ConsensusParams); err != nil {
state.LastHeightConsensusParamsChanged, state.ConsensusParams, batch); err != nil {
return err
}
err := store.db.SetSync(key, state.Bytes())
if err != nil {
if err := batch.Set(key, state.Bytes()); err != nil {
return err
}
return nil
return batch.WriteSync()
}
// BootstrapState saves a new state, used e.g. by state sync when starting from non-zero height.
@ -220,26 +225,33 @@ func (store dbStore) Bootstrap(state State) error {
height = state.InitialHeight
}
batch := store.db.NewBatch()
defer batch.Close()
if height > 1 && !state.LastValidators.IsNilOrEmpty() {
if err := store.saveValidatorsInfo(height-1, height-1, state.LastValidators); err != nil {
if err := store.saveValidatorsInfo(height-1, height-1, state.LastValidators, batch); err != nil {
return err
}
}
if err := store.saveValidatorsInfo(height, height, state.Validators); err != nil {
if err := store.saveValidatorsInfo(height, height, state.Validators, batch); err != nil {
return err
}
if err := store.saveValidatorsInfo(height+1, height+1, state.NextValidators); err != nil {
if err := store.saveValidatorsInfo(height+1, height+1, state.NextValidators, batch); err != nil {
return err
}
if err := store.saveConsensusParamsInfo(height,
state.LastHeightConsensusParamsChanged, state.ConsensusParams); err != nil {
state.LastHeightConsensusParamsChanged, state.ConsensusParams, batch); err != nil {
return err
}
return store.db.SetSync(stateKey, state.Bytes())
if err := batch.Set(stateKey, state.Bytes()); err != nil {
return err
}
return batch.WriteSync()
}
// PruneStates deletes states up to the height specified (exclusive). It is not
@ -468,6 +480,10 @@ func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, er
//
// Exposed for testing.
func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error {
return store.saveABCIResponses(height, abciResponses)
}
func (store dbStore) saveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error {
var dtxs []*abci.ResponseDeliverTx
// strip nil values,
for _, tx := range abciResponses.DeliverTxs {
@ -475,6 +491,7 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI
dtxs = append(dtxs, tx)
}
}
abciResponses.DeliverTxs = dtxs
bz, err := abciResponses.Marshal()
@ -482,12 +499,7 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI
return err
}
err = store.db.SetSync(abciResponsesKey(height), bz)
if err != nil {
return err
}
return nil
return store.db.SetSync(abciResponsesKey(height), bz)
}
//-----------------------------------------------------------------------------
@ -568,7 +580,11 @@ func loadValidatorsInfo(db dbm.DB, height int64) (*tmstate.ValidatorsInfo, error
// `height` is the effective height for which the validator is responsible for
// signing. It should be called from s.Save(), right before the state itself is
// persisted.
func (store dbStore) saveValidatorsInfo(height, lastHeightChanged int64, valSet *types.ValidatorSet) error {
func (store dbStore) saveValidatorsInfo(
height, lastHeightChanged int64,
valSet *types.ValidatorSet,
batch dbm.Batch,
) error {
if lastHeightChanged > height {
return errors.New("lastHeightChanged cannot be greater than ValidatorsInfo height")
}
@ -590,7 +606,7 @@ func (store dbStore) saveValidatorsInfo(height, lastHeightChanged int64, valSet
return err
}
err = store.db.Set(validatorsKey(height), bz)
err = batch.Set(validatorsKey(height), bz)
if err != nil {
return err
}
@ -656,7 +672,11 @@ func (store dbStore) loadConsensusParamsInfo(height int64) (*tmstate.ConsensusPa
// It should be called from s.Save(), right before the state itself is persisted.
// If the consensus params did not change after processing the latest block,
// only the last height for which they changed is persisted.
func (store dbStore) saveConsensusParamsInfo(nextHeight, changeHeight int64, params types.ConsensusParams) error {
func (store dbStore) saveConsensusParamsInfo(
nextHeight, changeHeight int64,
params types.ConsensusParams,
batch dbm.Batch,
) error {
paramsInfo := &tmstate.ConsensusParamsInfo{
LastHeightChanged: changeHeight,
}
@ -669,7 +689,7 @@ func (store dbStore) saveConsensusParamsInfo(nextHeight, changeHeight int64, par
return err
}
err = store.db.Set(consensusParamsKey(nextHeight), bz)
err = batch.Set(consensusParamsKey(nextHeight), bz)
if err != nil {
return err
}


Loading…
Cancel
Save