@@ -45,6 +45,8 @@ type Manager interface {
45
45
Stop ()
46
46
NewBlockHashes () chan <- * ffcapi.BlockHashEvent
47
47
CheckInFlight (listenerID * fftypes.UUID ) bool
48
+ StartConfirmedBlockListener (ctx context.Context , id * fftypes.UUID , fromBlock string , checkpoint * ffcapi.BlockListenerCheckpoint , eventStream chan <- * ffcapi.ListenerEvent ) error
49
+ StopConfirmedBlockListener (ctx context.Context , id * fftypes.UUID ) error
48
50
}
49
51
50
52
type NotificationType string
@@ -99,6 +101,8 @@ type blockConfirmationManager struct {
99
101
pendingMux sync.Mutex
100
102
receiptChecker * receiptChecker
101
103
retry * retry.Retry
104
+ cblLock sync.Mutex
105
+ cbls map [fftypes.UUID ]* confirmedBlockListener
102
106
fetchReceiptUponEntry bool
103
107
done chan struct {}
104
108
}
@@ -108,6 +112,7 @@ func NewBlockConfirmationManager(baseContext context.Context, connector ffcapi.A
108
112
bcm := & blockConfirmationManager {
109
113
baseContext : baseContext ,
110
114
connector : connector ,
115
+ cbls : make (map [fftypes.UUID ]* confirmedBlockListener ),
111
116
blockListenerStale : true ,
112
117
requiredConfirmations : config .GetInt (tmconfig .ConfirmationsRequired ),
113
118
staleReceiptTimeout : config .GetDuration (tmconfig .ConfirmationsStaleReceiptTimeout ),
@@ -233,6 +238,9 @@ func (bcm *blockConfirmationManager) Stop() {
233
238
// Reset context ready for restart
234
239
bcm .ctx , bcm .cancelFunc = context .WithCancel (bcm .baseContext )
235
240
}
241
+ for _ , cbl := range bcm .copyCBLsList () {
242
+ _ = bcm .StopConfirmedBlockListener (bcm .ctx , cbl .id )
243
+ }
236
244
}
237
245
238
246
func (bcm * blockConfirmationManager ) NewBlockHashes () chan <- * ffcapi.BlockHashEvent {
@@ -301,9 +309,10 @@ func (bcm *blockConfirmationManager) getBlockByHash(blockHash string) (*apitypes
301
309
return blockInfo , nil
302
310
}
303
311
304
- func (bcm * blockConfirmationManager ) getBlockByNumber (blockNumber uint64 , expectedParentHash string ) (* apitypes.BlockInfo , error ) {
312
+ func (bcm * blockConfirmationManager ) getBlockByNumber (blockNumber uint64 , allowCache bool , expectedParentHash string ) (* apitypes.BlockInfo , error ) {
305
313
res , reason , err := bcm .connector .BlockInfoByNumber (bcm .ctx , & ffcapi.BlockInfoByNumberRequest {
306
314
BlockNumber : fftypes .NewFFBigInt (int64 (blockNumber )),
315
+ AllowCache : allowCache ,
307
316
ExpectedParentHash : expectedParentHash ,
308
317
})
309
318
if err != nil {
@@ -326,6 +335,27 @@ func transformBlockInfo(res *ffcapi.BlockInfo) *apitypes.BlockInfo {
326
335
}
327
336
}
328
337
338
+ func (bcm * blockConfirmationManager ) copyCBLsList () []* confirmedBlockListener {
339
+ bcm .cblLock .Lock ()
340
+ defer bcm .cblLock .Unlock ()
341
+ cbls := make ([]* confirmedBlockListener , 0 , len (bcm .cbls ))
342
+ for _ , cbl := range bcm .cbls {
343
+ cbls = append (cbls , cbl )
344
+ }
345
+ return cbls
346
+ }
347
+
348
+ func (bcm * blockConfirmationManager ) propagateBlockHashToCBLs (bhe * ffcapi.BlockHashEvent ) {
349
+ bcm .cblLock .Lock ()
350
+ defer bcm .cblLock .Unlock ()
351
+ for _ , cbl := range bcm .cbls {
352
+ select {
353
+ case cbl .newBlockHashes <- bhe :
354
+ case <- cbl .processorDone :
355
+ }
356
+ }
357
+ }
358
+
329
359
func (bcm * blockConfirmationManager ) confirmationsListener () {
330
360
defer close (bcm .done )
331
361
notifications := make ([]* Notification , 0 )
@@ -340,6 +370,11 @@ func (bcm *blockConfirmationManager) confirmationsListener() {
340
370
}
341
371
blockHashes = append (blockHashes , bhe .BlockHashes ... )
342
372
373
+ // Need to also pass this event to any confirmed block listeners
374
+ // (they promise to always be efficient in handling these, having a go-routine
375
+ // dedicated to spinning fast just processing those separate to dispatching them)
376
+ bcm .propagateBlockHashToCBLs (bhe )
377
+
343
378
if bhe .Created != nil {
344
379
for i := 0 ; i < len (bhe .BlockHashes ); i ++ {
345
380
bcm .metricsEmitter .RecordBlockHashQueueingMetrics (bcm .ctx , time .Since (* bhe .Created .Time ()).Seconds ())
@@ -371,7 +406,7 @@ func (bcm *blockConfirmationManager) confirmationsListener() {
371
406
372
407
if bcm .blockListenerStale {
373
408
if err := bcm .walkChain (blocks ); err != nil {
374
- log .L (bcm .ctx ).Errorf ("Failed to create walk chain after restoring blockListener: %s" , err )
409
+ log .L (bcm .ctx ).Errorf ("Failed to walk chain after restoring blockListener: %s" , err )
375
410
continue
376
411
}
377
412
bcm .blockListenerStale = false
@@ -704,7 +739,7 @@ func (bs *blockState) getByNumber(blockNumber uint64, expectedParentHash string)
704
739
if block != nil {
705
740
return block , nil
706
741
}
707
- block , err := bs .bcm .getBlockByNumber (blockNumber , expectedParentHash )
742
+ block , err := bs .bcm .getBlockByNumber (blockNumber , true , expectedParentHash )
708
743
if err != nil {
709
744
return nil , err
710
745
}
0 commit comments