From 609be4e28e754e0d5d2373e908d7b3334d75c274 Mon Sep 17 00:00:00 2001 From: William Banfield Date: Mon, 28 Nov 2022 12:41:32 -0500 Subject: [PATCH] add addTimeSample to exported store calls --- state/store.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/state/store.go b/state/store.go index 3a174d103..39aed9ebd 100644 --- a/state/store.go +++ b/state/store.go @@ -3,8 +3,10 @@ package state import ( "errors" "fmt" + "time" "github.com/cosmos/gogoproto/proto" + "github.com/go-kit/kit/metrics" dbm "github.com/tendermint/tm-db" abci "github.com/tendermint/tendermint/abci/types" @@ -115,6 +117,7 @@ func NewStore(db dbm.DB, options StoreOptions) Store { // LoadStateFromDBOrGenesisFile loads the most recent state from the database, // or creates a new one from the given genesisFilePath. func (store dbStore) LoadFromDBOrGenesisFile(genesisFilePath string) (State, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", "LoadFromDBOrGenesisFile"))() state, err := store.Load() if err != nil { return State{}, err @@ -133,6 +136,7 @@ func (store dbStore) LoadFromDBOrGenesisFile(genesisFilePath string) (State, err // LoadStateFromDBOrGenesisDoc loads the most recent state from the database, // or creates a new one from the given genesisDoc. func (store dbStore) LoadFromDBOrGenesisDoc(genesisDoc *types.GenesisDoc) (State, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " LoadFromDBOrGenesisDoc"))() state, err := store.Load() if err != nil { return State{}, err @@ -151,6 +155,7 @@ func (store dbStore) LoadFromDBOrGenesisDoc(genesisDoc *types.GenesisDoc) (State // LoadState loads the State from the database. func (store dbStore) Load() (State, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " Load"))() return store.loadState(stateKey) } @@ -183,6 +188,7 @@ func (store dbStore) loadState(key []byte) (state State, err error) { // Save persists the State, the ValidatorsInfo, and the ConsensusParamsInfo to the database. // This flushes the writes (e.g. calls SetSync). func (store dbStore) Save(state State) error { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " Save"))() return store.save(state, stateKey) } @@ -217,6 +223,7 @@ func (store dbStore) save(state State, key []byte) error { // BootstrapState saves a new state, used e.g. by state sync when starting from non-zero height. func (store dbStore) Bootstrap(state State) error { height := state.LastBlockHeight + 1 + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " Bootstrap"))() if height == 1 { height = state.InitialHeight } @@ -252,6 +259,7 @@ func (store dbStore) Bootstrap(state State) error { // This will cause some old states to be left behind when doing incremental partial prunes, // specifically older checkpoints and LastHeightChanged targets. func (store dbStore) PruneStates(from int64, to int64, evidenceThresholdHeight int64) error { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " PruneStates"))() if from <= 0 || to <= 0 { return fmt.Errorf("from height %v and to height %v must be greater than 0", from, to) } @@ -393,6 +401,7 @@ func ABCIResponsesResultsHash(ar *tmstate.ABCIResponses) []byte { // 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) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " LoadABCIResponses"))() if store.DiscardABCIResponses { return nil, ErrABCIResponsesNotPersisted } @@ -425,6 +434,7 @@ func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, er // This method is used for recovering in the case that we called the Commit ABCI // method on the application but crashed before persisting the results. func (store dbStore) LoadLastABCIResponse(height int64) (*tmstate.ABCIResponses, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " LoadLastABCIResponse"))() bz, err := store.db.Get(lastABCIResponseKey) if err != nil { return nil, err @@ -456,6 +466,7 @@ func (store dbStore) LoadLastABCIResponse(height int64) (*tmstate.ABCIResponses, // // CONTRACT: height must be monotonically increasing every time this is called. func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " SaveABCIResponses"))() var dtxs []*abci.ResponseDeliverTx // strip nil values, for _, tx := range abciResponses.DeliverTxs { @@ -496,6 +507,7 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI // LoadValidators loads the ValidatorSet for a given height. // Returns ErrNoValSetForHeight if the validator set can't be found for this height. func (store dbStore) LoadValidators(height int64) (*types.ValidatorSet, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " LoadValidators"))() valInfo, err := loadValidatorsInfo(store.db, height) if err != nil { return nil, ErrNoValSetForHeight{height} @@ -604,6 +616,7 @@ func (store dbStore) saveValidatorsInfo(height, lastHeightChanged int64, valSet // LoadConsensusParams loads the ConsensusParams for a given height. func (store dbStore) LoadConsensusParams(height int64) (types.ConsensusParams, error) { + defer addTimeSample(store.metrics.StoreAccessDurationSeconds.With("method", " LoadConsensusParams"))() var ( empty = types.ConsensusParams{} emptypb = tmproto.ConsensusParams{} @@ -685,3 +698,12 @@ func min(a int64, b int64) int64 { } return b } + +// addTimeSample returns a function that, when called, adds an observation to m. +// The observation added to m is the number of seconds ellapsed since addTimeSample +// was initially called. addTimeSample is meant to be called in a defer to calculate +// the amount of time a function takes to complete. +func addTimeSample(m metrics.Histogram) func() { + start := time.Now() + return func() { m.Observe(time.Since(start).Seconds()) } +}