diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 52ee5ab2b..095582b04 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -28,3 +28,5 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - [txindex] [\#4466](https://github.com/tendermint/tendermint/pull/4466) Allow to index an event at runtime (@favadi) ### BUG FIXES: + +- [light] [\#4741](https://github.com/tendermint/tendermint/pull/4741) Correctly return `ErrSignedHeaderNotFound` and `ErrValidatorSetNotFound` on corresponding RPC errors (@erikgrinaker) diff --git a/lite2/provider/http/http.go b/lite2/provider/http/http.go index 30fdaf2e8..360338f75 100644 --- a/lite2/provider/http/http.go +++ b/lite2/provider/http/http.go @@ -3,6 +3,7 @@ package http import ( "errors" "fmt" + "regexp" "strings" "github.com/tendermint/tendermint/lite2/provider" @@ -11,6 +12,9 @@ import ( "github.com/tendermint/tendermint/types" ) +// This is very brittle, see: https://github.com/tendermint/tendermint/issues/4740 +var regexpMissingHeight = regexp.MustCompile(`height \d+ (must be less than or equal to|is not available)`) + // http provider uses an RPC client to obtain the necessary information. type http struct { chainID string @@ -62,7 +66,7 @@ func (p *http) SignedHeader(height int64) (*types.SignedHeader, error) { commit, err := p.client.Commit(h) if err != nil { // TODO: standartise errors on the RPC side - if strings.Contains(err.Error(), "height must be less than or equal") { + if regexpMissingHeight.MatchString(err.Error()) { return nil, provider.ErrSignedHeaderNotFound } return nil, err @@ -92,7 +96,7 @@ func (p *http) ValidatorSet(height int64) (*types.ValidatorSet, error) { res, err := p.client.Validators(h, 0, maxPerPage) if err != nil { // TODO: standartise errors on the RPC side - if strings.Contains(err.Error(), "height must be less than or equal") { + if regexpMissingHeight.MatchString(err.Error()) { return nil, provider.ErrValidatorSetNotFound } return nil, err diff --git a/lite2/provider/http/http_test.go b/lite2/provider/http/http_test.go index 49c3d3622..33ab63a37 100644 --- a/lite2/provider/http/http_test.go +++ b/lite2/provider/http/http_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/abci/example/kvstore" + "github.com/tendermint/tendermint/lite2/provider" "github.com/tendermint/tendermint/lite2/provider/http" litehttp "github.com/tendermint/tendermint/lite2/provider/http" rpcclient "github.com/tendermint/tendermint/rpc/client" @@ -33,6 +34,7 @@ func TestNewProvider(t *testing.T) { func TestMain(m *testing.M) { app := kvstore.NewApplication() + app.RetainBlocks = 5 node := rpctest.StartTendermint(app) code := m.Run() @@ -73,8 +75,25 @@ func TestProvider(t *testing.T) { assert.Nil(t, sh.ValidateBasic(chainID)) // historical queries now work :) - lower := sh.Height - 5 + lower := sh.Height - 3 sh, err = p.SignedHeader(lower) assert.Nil(t, err, "%+v", err) assert.Equal(t, lower, sh.Height) + + // fetching missing heights (both future and pruned) should return appropriate errors + _, err = p.SignedHeader(1000) + require.Error(t, err) + assert.Equal(t, provider.ErrSignedHeaderNotFound, err) + + _, err = p.ValidatorSet(1000) + require.Error(t, err) + assert.Equal(t, provider.ErrValidatorSetNotFound, err) + + _, err = p.SignedHeader(1) + require.Error(t, err) + assert.Equal(t, provider.ErrSignedHeaderNotFound, err) + + _, err = p.ValidatorSet(1) + require.Error(t, err) + assert.Equal(t, provider.ErrValidatorSetNotFound, err) }