checkpoint

This commit is contained in:
Callum Waters
2022-07-11 13:59:37 +02:00
parent 2dbc76d79f
commit c0eb5da04c
8 changed files with 51 additions and 26 deletions
+6 -1
View File
@@ -1,6 +1,9 @@
package state
import "fmt"
import (
"errors"
"fmt"
)
type (
ErrInvalidBlock error
@@ -99,3 +102,5 @@ func (e ErrNoConsensusParamsForHeight) Error() string {
func (e ErrNoABCIResponsesForHeight) Error() string {
return fmt.Sprintf("could not find results for height #%d", e.Height)
}
var ErrABCIResponsesNotPersisted = errors.New("node is not persisting abci responses")
+1 -1
View File
@@ -111,7 +111,7 @@ func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValida
})
stateDB := dbm.NewMemDB()
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, false)
if err := stateStore.Save(s); err != nil {
panic(err)
}
+31 -15
View File
@@ -110,16 +110,16 @@ type Store interface {
type dbStore struct {
db dbm.DB
// persistABCIResponses determines if all
// discardABCIResponses determines if all
// ABCI responses are persisted or just the last
persistABCIResponses bool
discardABCIResponses bool
}
var _ Store = (*dbStore)(nil)
// NewStore creates the dbStore of the state pkg.
func NewStore(db dbm.DB, persistABCIResponses bool) Store {
return dbStore{db, persistABCIResponses}
func NewStore(db dbm.DB, discardABCIResponses bool) Store {
return dbStore{db, discardABCIResponses}
}
// LoadState loads the State from the database.
@@ -420,22 +420,19 @@ func ABCIResponsesResultsHash(ar *tmstate.ABCIResponses) []byte {
}
// LoadABCIResponses loads the ABCIResponses for the given height from the
// database. If not found, ErrNoABCIResponsesForHeight is returned.
//
// This is useful for recovering from crashes where we called app.Commit and
// before we called s.Save(). It can also be used to produce Merkle proofs of
// the result of txs.
// database. If the node has DiscardABCIResponses set to true, ErrABCIResponsesNotPersisted
// is persisted. If not found, ErrNoABCIResponsesForHeight is returned.
func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, error) {
if !store.persistABCIResponses {
return nil, errors.New("this is not supported")
if !store.discardABCIResponses {
return nil, ErrABCIResponsesNotPersisted
}
buf, err := store.db.Get(abciResponsesKey(height))
if err != nil {
return nil, err
}
if len(buf) == 0 {
if len(buf) == 0 {
return nil, ErrNoABCIResponsesForHeight{height}
}
abciResponses := new(tmstate.ABCIResponses)
@@ -450,6 +447,21 @@ func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, er
return abciResponses, nil
}
// LoadLastABCIResponses loads the last ABCI response specifically after a crash
// We conduct a sanity check here which compares the height from the last ABICResponse to the
// height that is given
//
// This is used for recovering from crashes where we called app.Commit and
// before we called s.Save(). It can also be used to produce Merkle proofs of
// the result of txs.
func (store dbStore) LoadLastABCIResponse(height int64) (*tmstate.ABCIResponses, error) {
bz, err := store.db.Get(lastABCIResponseKey())
abciResponse := new(tmstate.ABCIResponses)
err = abciResponses.Unmarshal(bz)
return abciResponse, nil
}
// SaveABCIResponses persists the ABCIResponses to the database.
// This is useful in case we crash after app.Commit and before s.Save().
// Responses are indexed by height so they can also be loaded later to produce
@@ -472,9 +484,9 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI
return err
}
// If the flag is true then we save the ABCIResponse. This can be used for the /BlockResults
// If the flag is false then we save the ABCIResponse. This can be used for the /BlockResults
// query or to reindex an event using the command line.
if store.persistABCIResponses {
if !store.discardABCIResponses {
if err := store.db.Set(abciResponsesKey(height), bz); err != nil {
return err
}
@@ -485,6 +497,10 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI
return store.db.SetSync(lastABCIResponseKey(), bz)
}
type ResponsesInfo struct {
abcu
}
// SaveValidatorSets is used to save the validator set over multiple heights.
// It is exposed so that a backfill operation during state sync can populate
// the store with the necessary amount of validator sets to verify any evidence