|
1 | 1 | package syncing |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "context" |
5 | 6 | crand "crypto/rand" |
6 | 7 | "crypto/sha512" |
7 | 8 | "errors" |
8 | 9 | "math" |
| 10 | + "strings" |
9 | 11 | "sync/atomic" |
10 | 12 | "testing" |
11 | 13 | "testing/synctest" |
@@ -34,6 +36,16 @@ import ( |
34 | 36 | "github.com/evstack/ev-node/types" |
35 | 37 | ) |
36 | 38 |
|
| 39 | +type stubP2PHandler struct { |
| 40 | + processHeight func(ctx context.Context, height uint64, heightInCh chan<- common.DAHeightEvent) error |
| 41 | +} |
| 42 | + |
| 43 | +func (s *stubP2PHandler) ProcessHeight(ctx context.Context, height uint64, heightInCh chan<- common.DAHeightEvent) error { |
| 44 | + return s.processHeight(ctx, height, heightInCh) |
| 45 | +} |
| 46 | + |
| 47 | +func (s *stubP2PHandler) SetProcessedHeight(uint64) {} |
| 48 | + |
37 | 49 | // helper to create a signer, pubkey and address for tests |
38 | 50 | func buildSyncTestSigner(tb testing.TB) (addr []byte, pub crypto.PubKey, signer signerpkg.Signer) { |
39 | 51 | tb.Helper() |
@@ -165,6 +177,65 @@ func TestSyncer_validateBlock_DataHashMismatch(t *testing.T) { |
165 | 177 | require.Error(t, err) |
166 | 178 | } |
167 | 179 |
|
| 180 | +func TestSyncer_processP2PHeight_LogsWhenBlocked(t *testing.T) { |
| 181 | + ds := dssync.MutexWrap(datastore.NewMapDatastore()) |
| 182 | + st := store.New(ds) |
| 183 | + |
| 184 | + batch, err := st.NewBatch(t.Context()) |
| 185 | + require.NoError(t, err) |
| 186 | + require.NoError(t, batch.SetHeight(7)) |
| 187 | + require.NoError(t, batch.Commit()) |
| 188 | + |
| 189 | + cm, err := cache.NewManager(config.DefaultConfig(), st, zerolog.Nop()) |
| 190 | + require.NoError(t, err) |
| 191 | + cm.SetPendingEvent(10, &common.DAHeightEvent{}) |
| 192 | + |
| 193 | + headerStore := extmocks.NewMockStore[*types.P2PSignedHeader](t) |
| 194 | + headerStore.EXPECT().Height().Return(uint64(11)).Maybe() |
| 195 | + dataStore := extmocks.NewMockStore[*types.P2PData](t) |
| 196 | + dataStore.EXPECT().Height().Return(uint64(12)).Maybe() |
| 197 | + |
| 198 | + var logBuf bytes.Buffer |
| 199 | + logger := zerolog.New(&logBuf) |
| 200 | + |
| 201 | + originalInterval := p2pWaitLogInterval |
| 202 | + p2pWaitLogInterval = 10 * time.Millisecond |
| 203 | + t.Cleanup(func() { |
| 204 | + p2pWaitLogInterval = originalInterval |
| 205 | + }) |
| 206 | + |
| 207 | + s := &Syncer{ |
| 208 | + store: st, |
| 209 | + cache: cm, |
| 210 | + headerStore: headerStore, |
| 211 | + dataStore: dataStore, |
| 212 | + heightInCh: make(chan common.DAHeightEvent, 2), |
| 213 | + logger: logger, |
| 214 | + p2pHandler: &stubP2PHandler{ |
| 215 | + processHeight: func(ctx context.Context, _ uint64, _ chan<- common.DAHeightEvent) error { |
| 216 | + select { |
| 217 | + case <-time.After(35 * time.Millisecond): |
| 218 | + return nil |
| 219 | + case <-ctx.Done(): |
| 220 | + return ctx.Err() |
| 221 | + } |
| 222 | + }, |
| 223 | + }, |
| 224 | + } |
| 225 | + |
| 226 | + err = s.processP2PHeight(t.Context(), 8, logger) |
| 227 | + require.NoError(t, err) |
| 228 | + |
| 229 | + logs := logBuf.String() |
| 230 | + require.Contains(t, logs, "waiting for P2P height to become available") |
| 231 | + require.Contains(t, logs, "\"target_height\":8") |
| 232 | + require.Contains(t, logs, "\"local_height\":7") |
| 233 | + require.Contains(t, logs, "\"header_store_height\":11") |
| 234 | + require.Contains(t, logs, "\"data_store_height\":12") |
| 235 | + require.Contains(t, logs, "\"pending_events\":1") |
| 236 | + require.True(t, strings.Contains(logs, "P2P height became available")) |
| 237 | +} |
| 238 | + |
168 | 239 | func TestProcessHeightEvent_SyncsAndUpdatesState(t *testing.T) { |
169 | 240 | ds := dssync.MutexWrap(datastore.NewMapDatastore()) |
170 | 241 | st := store.New(ds) |
|
0 commit comments