Skip to content

Commit bd70a0e

Browse files
committed
Mark ready on populated cache, not on epoch event
1 parent 287a9c3 commit bd70a0e

2 files changed

Lines changed: 45 additions & 13 deletions

File tree

core/process/peer/peerTypeProvider.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ func NewPeerTypeProvider(arg ArgPeerTypeProvider) (*PeerTypeProvider, error) {
5555
return ptp, nil
5656
}
5757

58-
// IsCachePopulated returns true once the cache has been refreshed by an epoch-start event.
59-
// During the bootstrap window before the first epoch-start notification fires, the cache
60-
// is either empty or seeded from a NodesCoordinator that is not yet fully populated, so
61-
// callers should treat its peer-type result as unreliable.
58+
// IsCachePopulated returns true once at least one updateCache call has produced a
59+
// non-empty cache. Until then, the NodesCoordinator has not yet exposed any
60+
// validator keys for the active epoch, so callers should treat the peer-type result
61+
// as unreliable and avoid overwriting startup-seeded values.
6262
func (ptp *PeerTypeProvider) IsCachePopulated() bool {
6363
ptp.mutCache.RLock()
6464
defer ptp.mutCache.RUnlock()
@@ -103,7 +103,6 @@ func (ptp *PeerTypeProvider) epochStartEventHandler() sharding.EpochStartActionH
103103
"slot", hdr.GetSlot(),
104104
"epoch", hdr.GetEpoch())
105105
ptp.updateCache(hdr.GetEpoch())
106-
ptp.markReady()
107106
},
108107
func(_ data.HeaderHandler) {},
109108
core.IndexerOrder,
@@ -117,12 +116,9 @@ func (ptp *PeerTypeProvider) updateCache(epoch uint32) {
117116

118117
ptp.mutCache.Lock()
119118
ptp.cache = newCache
120-
ptp.mutCache.Unlock()
121-
}
122-
123-
func (ptp *PeerTypeProvider) markReady() {
124-
ptp.mutCache.Lock()
125-
ptp.isReady = true
119+
if len(newCache) > 0 {
120+
ptp.isReady = true
121+
}
126122
ptp.mutCache.Unlock()
127123
}
128124

core/process/peer/peerTypeProvider_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func TestNewPeerTypeProvider_ComputeForKeyNotFoundInCacheReturnsObserver(t *test
205205
assert.Nil(t, err)
206206
}
207207

208-
func TestPeerTypeProvider_IsCachePopulated_FalseAtConstruction(t *testing.T) {
208+
func TestPeerTypeProvider_IsCachePopulated_FalseWhenCoordinatorReturnsEmpty(t *testing.T) {
209209
arg := createDefaultArgPeerTypeProvider()
210210

211211
ptp, err := NewPeerTypeProvider(arg)
@@ -215,21 +215,57 @@ func TestPeerTypeProvider_IsCachePopulated_FalseAtConstruction(t *testing.T) {
215215
assert.False(t, ptp.IsCachePopulated())
216216
}
217217

218-
func TestPeerTypeProvider_IsCachePopulated_TrueAfterEpochStart(t *testing.T) {
218+
func TestPeerTypeProvider_IsCachePopulated_TrueAtConstructionWhenCachePopulated(t *testing.T) {
219+
arg := createDefaultArgPeerTypeProvider()
220+
arg.NodesCoordinator = &mock.NodesCoordinatorMock{
221+
GetAllElectedValidatorsKeysCalled: func() ([][]byte, error) {
222+
return [][]byte{[]byte("validator-pk")}, nil
223+
},
224+
}
225+
226+
ptp, err := NewPeerTypeProvider(arg)
227+
require.Nil(t, err)
228+
require.NotNil(t, ptp)
229+
230+
assert.True(t, ptp.IsCachePopulated())
231+
}
232+
233+
func TestPeerTypeProvider_IsCachePopulated_TrueAfterEpochStartFillsCache(t *testing.T) {
219234
arg := createDefaultArgPeerTypeProvider()
220235
epochStartNotifier := &mock.EpochStartNotifierStub{}
221236
arg.EpochStartEventNotifier = epochStartNotifier
222237

238+
coordinator := &mock.NodesCoordinatorMock{}
239+
arg.NodesCoordinator = coordinator
240+
223241
ptp, err := NewPeerTypeProvider(arg)
224242
require.Nil(t, err)
225243
require.NotNil(t, ptp)
226244
require.False(t, ptp.IsCachePopulated())
227245

246+
coordinator.GetAllElectedValidatorsKeysCalled = func() ([][]byte, error) {
247+
return [][]byte{[]byte("validator-pk")}, nil
248+
}
228249
epochStartNotifier.NotifyAll(&block.Block{Header: &block.BlockHeader{Nonce: 1, Epoch: 1}})
229250

230251
assert.True(t, ptp.IsCachePopulated())
231252
}
232253

254+
func TestPeerTypeProvider_IsCachePopulated_StaysFalseWhenEpochStartFiresButCacheEmpty(t *testing.T) {
255+
arg := createDefaultArgPeerTypeProvider()
256+
epochStartNotifier := &mock.EpochStartNotifierStub{}
257+
arg.EpochStartEventNotifier = epochStartNotifier
258+
259+
ptp, err := NewPeerTypeProvider(arg)
260+
require.Nil(t, err)
261+
require.NotNil(t, ptp)
262+
require.False(t, ptp.IsCachePopulated())
263+
264+
epochStartNotifier.NotifyAll(&block.Block{Header: &block.BlockHeader{Nonce: 1, Epoch: 1}})
265+
266+
assert.False(t, ptp.IsCachePopulated())
267+
}
268+
233269
func TestNewPeerTypeProvider_IsInterfaceNil(t *testing.T) {
234270
arg := createDefaultArgPeerTypeProvider()
235271

0 commit comments

Comments
 (0)