diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index 1e35c1c3a..6608fd763 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -310,12 +310,17 @@ func (r *Reactor) backfill( // waiting on blocks. If it takes 4s to retrieve a block and 1s to verify // it, then steady state involves four workers. for i := 0; i < int(r.cfg.Fetchers); i++ { + ctxWithCancel, cancel := context.WithCancel(ctx) + defer cancel() go func() { for { select { case height := <-queue.nextHeight(): r.Logger.Debug("fetching next block", "height", height) - lb, peer, err := r.dispatcher.LightBlock(ctx, height) + lb, peer, err := r.dispatcher.LightBlock(ctxWithCancel, height) + if errors.Is(err, context.Canceled) { + return + } if err != nil { queue.retry(height) if errors.Is(err, errNoConnectedPeers) { diff --git a/internal/statesync/reactor_test.go b/internal/statesync/reactor_test.go index 5d02ed78b..22b016f89 100644 --- a/internal/statesync/reactor_test.go +++ b/internal/statesync/reactor_test.go @@ -3,12 +3,11 @@ package statesync import ( "context" "fmt" - "math/rand" "sync" "testing" "time" - // "github.com/fortytw2/leaktest" + "github.com/fortytw2/leaktest" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" dbm "github.com/tendermint/tm-db" @@ -421,11 +420,11 @@ func TestReactor_Dispatcher(t *testing.T) { func TestReactor_Backfill(t *testing.T) { // test backfill algorithm with varying failure rates [0, 10] - failureRates := []int{0, 3, 9} + failureRates := []int{0, 2, 9} for _, failureRate := range failureRates { failureRate := failureRate t.Run(fmt.Sprintf("failure rate: %d", failureRate), func(t *testing.T) { - // t.Cleanup(leaktest.Check(t)) + t.Cleanup(leaktest.CheckTimeout(t, 1*time.Minute)) rts := setup(t, nil, nil, nil, 21) var ( @@ -467,7 +466,7 @@ func TestReactor_Backfill(t *testing.T) { factory.MakeBlockIDWithHash(chain[startHeight].Header.Hash()), stopTime, ) - if failureRate > 5 { + if failureRate > 3 { require.Error(t, err) } else { require.NoError(t, err) @@ -506,6 +505,7 @@ func handleLightBlockRequests(t *testing.T, close chan struct{}, failureRate int) { requests := 0 + errorCount := 0 for { select { case envelope := <-receiving: @@ -520,7 +520,7 @@ func handleLightBlockRequests(t *testing.T, }, } } else { - switch rand.Intn(3) { + switch errorCount % 3 { case 0: // send a different block differntLB, err := mockLB(t, int64(msg.Height), factory.DefaultTestTime, factory.MakeBlockID()).ToProto() require.NoError(t, err) @@ -539,6 +539,7 @@ func handleLightBlockRequests(t *testing.T, } case 2: // don't do anything } + errorCount++ } } case <-close: