Skip to content

Commit

Permalink
fix: correctly return legacy block_results response
Browse files Browse the repository at this point in the history
  • Loading branch information
mbreithecker committed Jun 6, 2024
1 parent 1519562 commit a3ee162
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
1 change: 1 addition & 0 deletions rpc/core/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func (env *Environment) BlockResults(_ *rpctypes.Context, heightPtr *int64) (*ct
FinalizeBlockEvents: results.Events,
ValidatorUpdates: results.ValidatorUpdates,
ConsensusParamUpdates: results.ConsensusParamUpdates,
AppHash: results.AppHash,
}, nil
}

Expand Down
16 changes: 16 additions & 0 deletions state/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ type (
ErrNoABCIResponsesForHeight struct {
Height int64
}

ErrABCIResponseResponseUnmarshalForHeight struct {
Height int64
}

ErrABCIResponseCorruptedOrSpecChangeForHeight struct {
Height int64
}
)

func (e ErrUnknownBlock) Error() string {
Expand Down Expand Up @@ -103,4 +111,12 @@ func (e ErrNoABCIResponsesForHeight) Error() string {
return fmt.Sprintf("could not find results for height #%d", e.Height)
}

func (e ErrABCIResponseResponseUnmarshalForHeight) Error() string {
return fmt.Sprintf("could not decode results for height %d", e.Height)
}

func (e ErrABCIResponseCorruptedOrSpecChangeForHeight) Error() string {
return fmt.Sprintf("could not retrieve results for height %d", e.Height)
}

var ErrFinalizeBlockResponsesNotPersisted = errors.New("node is not persisting finalize block responses")
32 changes: 25 additions & 7 deletions state/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type Store interface {
LoadValidators(int64) (*types.ValidatorSet, error)
// LoadFinalizeBlockResponse loads the abciResponse for a given height
LoadFinalizeBlockResponse(int64) (*abci.ResponseFinalizeBlock, error)
// LoadLastABCIResponse loads the last abciResponse for a given height
// LoadLastFinalizeBlockResponse loads the last abciResponse for a given height
LoadLastFinalizeBlockResponse(int64) (*abci.ResponseFinalizeBlock, error)
// LoadConsensusParams loads the consensus params for a given height
LoadConsensusParams(int64) (types.ConsensusParams, error)
Expand Down Expand Up @@ -430,15 +430,14 @@ func (store dbStore) LoadFinalizeBlockResponse(height int64) (*abci.ResponseFina

resp := new(abci.ResponseFinalizeBlock)
err = resp.Unmarshal(buf)
if err != nil {
if err != nil || resp.AppHash == nil {
// The data might be of the legacy ABCI response type, so
// we try to unmarshal that
legacyResp := new(cmtstate.LegacyABCIResponses)
rerr := legacyResp.Unmarshal(buf)
if rerr != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
cmtos.Exit(fmt.Sprintf(`LoadFinalizeBlockResponse: Data has been corrupted or its spec has
changed: %v\n`, err))
if err := legacyResp.Unmarshal(buf); err != nil {
// only return an error, this method is only invoked through the `/block_results` not for state logic and
// some tests, so no need to exit cometbft if there's an error, just return it.
return nil, ErrABCIResponseCorruptedOrSpecChangeForHeight{Height: height}
}
// The state store contains the old format. Migrate to
// the new ResponseFinalizeBlock format. Note that the
Expand Down Expand Up @@ -761,6 +760,25 @@ func min(a int64, b int64) int64 {
// responseFinalizeBlockFromLegacy is a convenience function that takes the old abci responses and morphs
// it to the finalize block response. Note that the app hash is missing
func responseFinalizeBlockFromLegacy(legacyResp *cmtstate.LegacyABCIResponses) *abci.ResponseFinalizeBlock {

// Add BeginBlock attribute to BeginBlock events
for idx, event := range legacyResp.BeginBlock.Events {
legacyResp.BeginBlock.Events[idx].Attributes = append(event.Attributes, abci.EventAttribute{
Key: "mode",
Value: "BeginBlock",
Index: false,
})
}

// Add EndBlock attribute to BeginBlock events
for idx, event := range legacyResp.EndBlock.Events {
legacyResp.EndBlock.Events[idx].Attributes = append(event.Attributes, abci.EventAttribute{
Key: "mode",
Value: "EndBlock",
Index: false,
})
}

return &abci.ResponseFinalizeBlock{
TxResults: legacyResp.DeliverTxs,
ValidatorUpdates: legacyResp.EndBlock.ValidatorUpdates,
Expand Down

0 comments on commit a3ee162

Please sign in to comment.