statesync: improve e2e test outcomes (#6378)

I believe that this, in my testing seems to help the e2e state-sync
tests complete more reliably, by fixing some potential, range-related
slice building, as well as the way the test app hashes snapshots.

Additionally, and I'm not sure if we want to do this, but I added this
hook to the reactor that re-sends the request for snapshots during the
retry. This helps in tests prevent systems from getting stuck, but I
think in reality, it might create more traffic, and operators would
just restart a state-syncing node to get a similar effect.
This commit is contained in:
Sam Kleinman
2021-04-21 16:00:15 +00:00
committed by GitHub
parent fea04c8e67
commit d36a5905a6
7 changed files with 44 additions and 30 deletions
+10 -6
View File
@@ -477,14 +477,18 @@ func (r *Reactor) Sync(stateProvider StateProvider, discoveryTime time.Duration)
r.syncer = newSyncer(r.Logger, r.conn, r.connQuery, stateProvider, r.snapshotCh.Out, r.chunkCh.Out, r.tempDir)
r.mtx.Unlock()
// request snapshots from all currently connected peers
r.Logger.Debug("requesting snapshots from known peers")
r.snapshotCh.Out <- p2p.Envelope{
Broadcast: true,
Message: &ssproto.SnapshotsRequest{},
hook := func() {
// request snapshots from all currently connected peers
r.Logger.Debug("requesting snapshots from known peers")
r.snapshotCh.Out <- p2p.Envelope{
Broadcast: true,
Message: &ssproto.SnapshotsRequest{},
}
}
state, commit, err := r.syncer.SyncAny(discoveryTime)
hook()
state, commit, err := r.syncer.SyncAny(discoveryTime, hook)
r.mtx.Lock()
r.syncer = nil
+2 -2
View File
@@ -178,8 +178,8 @@ func (p *snapshotPool) Ranked() []*snapshot {
defer p.Unlock()
candidates := make([]*snapshot, 0, len(p.snapshots))
for _, snapshot := range p.snapshots {
candidates = append(candidates, snapshot)
for key := range p.snapshots {
candidates = append(candidates, p.snapshots[key])
}
sort.Slice(candidates, func(i, j int) bool {
+9 -1
View File
@@ -24,6 +24,9 @@ const (
chunkTimeout = 2 * time.Minute
// requestTimeout is the timeout before rerequesting a chunk, possibly from a different peer.
chunkRequestTimeout = 10 * time.Second
// minimumDiscoveryTime is the lowest allowable time for a
// SyncAny discovery time.
minimumDiscoveryTime = 5 * time.Second
)
var (
@@ -138,7 +141,11 @@ func (s *syncer) RemovePeer(peerID p2p.NodeID) {
// SyncAny tries to sync any of the snapshots in the snapshot pool, waiting to discover further
// snapshots if none were found and discoveryTime > 0. It returns the latest state and block commit
// which the caller must use to bootstrap the node.
func (s *syncer) SyncAny(discoveryTime time.Duration) (sm.State, *types.Commit, error) {
func (s *syncer) SyncAny(discoveryTime time.Duration, retryHook func()) (sm.State, *types.Commit, error) {
if discoveryTime != 0 && discoveryTime < minimumDiscoveryTime {
discoveryTime = 5 * minimumDiscoveryTime
}
if discoveryTime > 0 {
s.logger.Info(fmt.Sprintf("Discovering snapshots for %v", discoveryTime))
time.Sleep(discoveryTime)
@@ -161,6 +168,7 @@ func (s *syncer) SyncAny(discoveryTime time.Duration) (sm.State, *types.Commit,
if discoveryTime == 0 {
return sm.State{}, nil, errNoSnapshots
}
retryHook()
s.logger.Info(fmt.Sprintf("Discovering snapshots for %v", discoveryTime))
time.Sleep(discoveryTime)
continue
+7 -7
View File
@@ -175,7 +175,7 @@ func TestSyncer_SyncAny(t *testing.T) {
LastBlockAppHash: []byte("app_hash"),
}, nil)
newState, lastCommit, err := rts.syncer.SyncAny(0)
newState, lastCommit, err := rts.syncer.SyncAny(0, func() {})
require.NoError(t, err)
wg.Wait()
@@ -201,7 +201,7 @@ func TestSyncer_SyncAny_noSnapshots(t *testing.T) {
rts := setup(t, nil, nil, stateProvider, 2)
_, _, err := rts.syncer.SyncAny(0)
_, _, err := rts.syncer.SyncAny(0, func() {})
require.Equal(t, errNoSnapshots, err)
}
@@ -221,7 +221,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) {
Snapshot: toABCI(s), AppHash: []byte("app_hash"),
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil)
_, _, err = rts.syncer.SyncAny(0)
_, _, err = rts.syncer.SyncAny(0, func() {})
require.Equal(t, errAbort, err)
rts.conn.AssertExpectations(t)
}
@@ -260,7 +260,7 @@ func TestSyncer_SyncAny_reject(t *testing.T) {
Snapshot: toABCI(s11), AppHash: []byte("app_hash"),
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
_, _, err = rts.syncer.SyncAny(0)
_, _, err = rts.syncer.SyncAny(0, func() {})
require.Equal(t, errNoSnapshots, err)
rts.conn.AssertExpectations(t)
}
@@ -295,7 +295,7 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) {
Snapshot: toABCI(s11), AppHash: []byte("app_hash"),
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil)
_, _, err = rts.syncer.SyncAny(0)
_, _, err = rts.syncer.SyncAny(0, func() {})
require.Equal(t, errAbort, err)
rts.conn.AssertExpectations(t)
}
@@ -341,7 +341,7 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) {
Snapshot: toABCI(sa), AppHash: []byte("app_hash"),
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
_, _, err = rts.syncer.SyncAny(0)
_, _, err = rts.syncer.SyncAny(0, func() {})
require.Equal(t, errNoSnapshots, err)
rts.conn.AssertExpectations(t)
}
@@ -364,7 +364,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) {
Snapshot: toABCI(s), AppHash: []byte("app_hash"),
}).Once().Return(nil, errBoom)
_, _, err = rts.syncer.SyncAny(0)
_, _, err = rts.syncer.SyncAny(0, func() {})
require.True(t, errors.Is(err, errBoom))
rts.conn.AssertExpectations(t)
}