diff --git a/internal/statesync/dispatcher.go b/internal/statesync/dispatcher.go index 3f3e2a117..b12922343 100644 --- a/internal/statesync/dispatcher.go +++ b/internal/statesync/dispatcher.go @@ -195,7 +195,7 @@ func (p *BlockProvider) LightBlock(ctx context.Context, height int64) (*types.Li case errPeerAlreadyBusy: return nil, provider.ErrLightBlockNotFound default: - return nil, provider.ErrUnreliableProvider{Reason: err.Error()} + return nil, provider.ErrUnreliableProvider{Reason: err} } // check that the height requested is the same one returned diff --git a/light/provider/errors.go b/light/provider/errors.go index 355ec3475..d1a39f0c0 100644 --- a/light/provider/errors.go +++ b/light/provider/errors.go @@ -28,16 +28,20 @@ type ErrBadLightBlock struct { } func (e ErrBadLightBlock) Error() string { - return fmt.Sprintf("client provided bad signed header: %s", e.Reason.Error()) + return fmt.Sprintf("client provided bad signed header: %v", e.Reason) } +func (e ErrBadLightBlock) Unwrap() error { return e.Reason } + // ErrUnreliableProvider is a generic error that indicates that the provider isn't // behaving in a reliable manner to the light client. The light client will // remove the provider type ErrUnreliableProvider struct { - Reason string + Reason error } func (e ErrUnreliableProvider) Error() string { - return fmt.Sprintf("client deemed unreliable: %s", e.Reason) + return fmt.Sprintf("client deemed unreliable: %v", e.Reason) } + +func (e ErrUnreliableProvider) Unwrap() error { return e.Reason } diff --git a/light/provider/http/http.go b/light/provider/http/http.go index f8bf7d29e..79bb56c56 100644 --- a/light/provider/http/http.go +++ b/light/provider/http/http.go @@ -212,7 +212,7 @@ func (p *http) validatorSet(ctx context.Context, height *int64) (*types.Validato // If we don't know the error then by default we return an unreliable provider error and // terminate the connection with the peer. - return nil, provider.ErrUnreliableProvider{Reason: e.Error()} + return nil, provider.ErrUnreliableProvider{Reason: e} } // update the total and increment the page index so we can fetch the @@ -268,7 +268,7 @@ func (p *http) signedHeader(ctx context.Context, height *int64) (*types.SignedHe // If we don't know the error then by default we return an unreliable provider error and // terminate the connection with the peer. - return nil, provider.ErrUnreliableProvider{Reason: e.Error()} + return nil, provider.ErrUnreliableProvider{Reason: e} } } return nil, p.noResponse() @@ -278,7 +278,7 @@ func (p *http) noResponse() error { p.noResponseCount++ if p.noResponseCount > p.noResponseThreshold { return provider.ErrUnreliableProvider{ - Reason: fmt.Sprintf("failed to respond after %d attempts", p.noResponseCount), + Reason: fmt.Errorf("failed to respond after %d attempts", p.noResponseCount), } } return provider.ErrNoResponse @@ -288,7 +288,7 @@ func (p *http) noBlock(e error) error { p.noBlockCount++ if p.noBlockCount > p.noBlockThreshold { return provider.ErrUnreliableProvider{ - Reason: fmt.Sprintf("failed to provide a block after %d attempts", p.noBlockCount), + Reason: fmt.Errorf("failed to provide a block after %d attempts", p.noBlockCount), } } return e diff --git a/light/provider/http/http_test.go b/light/provider/http/http_test.go index 384a570ae..71cd78563 100644 --- a/light/provider/http/http_test.go +++ b/light/provider/http/http_test.go @@ -2,6 +2,7 @@ package http_test import ( "context" + "errors" "fmt" "testing" "time" @@ -100,8 +101,10 @@ func TestProvider(t *testing.T) { time.Sleep(10 * time.Second) lb, err = p.LightBlock(ctx, lower+2) - // we should see a connection refused + // Either the connection should be refused, or the context canceled. require.Error(t, err) require.Nil(t, lb) - assert.Equal(t, provider.ErrConnectionClosed, err) + if !errors.Is(err, provider.ErrConnectionClosed) && !errors.Is(err, context.Canceled) { + assert.Fail(t, "Incorrect error", "wanted connection closed or context canceled, got %v", err) + } }