@@ -22,6 +22,14 @@ import (
22
22
"github.com/evstack/ev-node/types"
23
23
)
24
24
25
+ type daRetriever interface {
26
+ RetrieveFromDA (ctx context.Context , daHeight uint64 ) ([]common.DAHeightEvent , error )
27
+ }
28
+ type p2pHandler interface {
29
+ ProcessHeaderRange (ctx context.Context , fromHeight , toHeight uint64 ) []common.DAHeightEvent
30
+ ProcessDataRange (ctx context.Context , fromHeight , toHeight uint64 ) []common.DAHeightEvent
31
+ }
32
+
25
33
// Syncer handles block synchronization from DA and P2P sources.
26
34
type Syncer struct {
27
35
// Core components
@@ -51,14 +59,12 @@ type Syncer struct {
51
59
dataStore goheader.Store [* types.Data ]
52
60
53
61
// Channels for coordination
54
- heightInCh chan common.DAHeightEvent
55
- headerStoreCh chan struct {}
56
- dataStoreCh chan struct {}
57
- errorCh chan <- error // Channel to report critical execution client failures
62
+ heightInCh chan common.DAHeightEvent
63
+ errorCh chan <- error // Channel to report critical execution client failures
58
64
59
65
// Handlers
60
- daRetriever * DARetriever
61
- p2pHandler * P2PHandler
66
+ daRetriever daRetriever
67
+ p2pHandler p2pHandler
62
68
63
69
// Logging
64
70
logger zerolog.Logger
@@ -85,23 +91,21 @@ func NewSyncer(
85
91
errorCh chan <- error ,
86
92
) * Syncer {
87
93
return & Syncer {
88
- store : store ,
89
- exec : exec ,
90
- da : da ,
91
- cache : cache ,
92
- metrics : metrics ,
93
- config : config ,
94
- genesis : genesis ,
95
- options : options ,
96
- headerStore : headerStore ,
97
- dataStore : dataStore ,
98
- lastStateMtx : & sync.RWMutex {},
99
- daStateMtx : & sync.RWMutex {},
100
- heightInCh : make (chan common.DAHeightEvent , 10000 ),
101
- headerStoreCh : make (chan struct {}, 1 ),
102
- dataStoreCh : make (chan struct {}, 1 ),
103
- errorCh : errorCh ,
104
- logger : logger .With ().Str ("component" , "syncer" ).Logger (),
94
+ store : store ,
95
+ exec : exec ,
96
+ da : da ,
97
+ cache : cache ,
98
+ metrics : metrics ,
99
+ config : config ,
100
+ genesis : genesis ,
101
+ options : options ,
102
+ headerStore : headerStore ,
103
+ dataStore : dataStore ,
104
+ lastStateMtx : & sync.RWMutex {},
105
+ daStateMtx : & sync.RWMutex {},
106
+ heightInCh : make (chan common.DAHeightEvent , 10_000 ),
107
+ errorCh : errorCh ,
108
+ logger : logger .With ().Str ("component" , "syncer" ).Logger (),
105
109
}
106
110
}
107
111
@@ -212,20 +216,10 @@ func (s *Syncer) processLoop() {
212
216
s .logger .Info ().Msg ("starting process loop" )
213
217
defer s .logger .Info ().Msg ("process loop stopped" )
214
218
215
- blockTicker := time .NewTicker (s .config .Node .BlockTime .Duration )
216
- defer blockTicker .Stop ()
217
-
218
219
for {
219
- // Process pending events from cache on every iteration
220
- s .processPendingEvents ()
221
-
222
220
select {
223
221
case <- s .ctx .Done ():
224
222
return
225
- case <- blockTicker .C :
226
- // Signal P2P stores to check for new data
227
- s .sendNonBlockingSignal (s .headerStoreCh , "header_store" )
228
- s .sendNonBlockingSignal (s .dataStoreCh , "data_store" )
229
223
case heightEvent := <- s .heightInCh :
230
224
s .processHeightEvent (& heightEvent )
231
225
}
@@ -250,15 +244,19 @@ func (s *Syncer) syncLoop() {
250
244
var hffDelay time.Duration
251
245
var nextDARequestAt time.Time
252
246
247
+ blockTicker := time .NewTicker (s .config .Node .BlockTime .Duration )
248
+ defer blockTicker .Stop ()
249
+
253
250
// TODO: we should request to see what the head of the chain is at
254
251
// then we know if we are falling behind or in sync mode
255
- syncLoop:
256
252
for {
257
253
select {
258
254
case <- s .ctx .Done ():
259
255
return
260
256
default :
261
257
}
258
+ // Process pending events from cache on every iteration
259
+ s .processPendingEvents ()
262
260
263
261
now := time .Now ()
264
262
// Respect backoff window if set
@@ -291,9 +289,7 @@ syncLoop:
291
289
select {
292
290
case s .heightInCh <- event :
293
291
default :
294
- s .logger .Warn ().Msg ("height channel full, dropping DA event" )
295
- time .Sleep (10 * time .Millisecond )
296
- continue syncLoop
292
+ s .cache .SetPendingEvent (event .Header .Height (), & event )
297
293
}
298
294
}
299
295
@@ -303,34 +299,34 @@ syncLoop:
303
299
}
304
300
}
305
301
302
+ // Opportunistically process any P2P signals
306
303
select {
307
- case <- s . headerStoreCh :
304
+ case <- blockTicker . C :
308
305
newHeaderHeight := s .headerStore .Height ()
309
306
if newHeaderHeight > lastHeaderHeight {
310
307
events := s .p2pHandler .ProcessHeaderRange (s .ctx , lastHeaderHeight + 1 , newHeaderHeight )
311
308
for _ , event := range events {
312
309
select {
313
310
case s .heightInCh <- event :
314
311
default :
315
- s .logger .Warn ().Msg ("height channel full, dropping P2P header event" )
316
- time .Sleep (10 * time .Millisecond )
317
- continue syncLoop
312
+ s .cache .SetPendingEvent (event .Header .Height (), & event )
318
313
}
319
314
}
320
-
321
315
lastHeaderHeight = newHeaderHeight
322
316
}
323
- case <- s . dataStoreCh :
317
+
324
318
newDataHeight := s .dataStore .Height ()
319
+ if newDataHeight == newHeaderHeight {
320
+ lastDataHeight = newDataHeight
321
+ continue
322
+ }
325
323
if newDataHeight > lastDataHeight {
326
324
events := s .p2pHandler .ProcessDataRange (s .ctx , lastDataHeight + 1 , newDataHeight )
327
325
for _ , event := range events {
328
326
select {
329
327
case s .heightInCh <- event :
330
328
default :
331
- s .logger .Warn ().Msg ("height channel full, dropping P2P data event" )
332
- time .Sleep (10 * time .Millisecond )
333
- continue syncLoop
329
+ s .cache .SetPendingEvent (event .Header .Height (), & event )
334
330
}
335
331
}
336
332
lastDataHeight = newDataHeight
0 commit comments