@@ -43,6 +43,8 @@ const (
4343	// Size of cache for recent chainsync cursors 
4444	cursorCacheSize  =  20 
4545
46+ 	blockBatchSize  =  500 
47+ 
4648	maxAutoReconnectDelay  =  60  *  time .Second 
4749	defaultKupoTimeout     =  30  *  time .Second 
4850)
@@ -55,7 +57,6 @@ type ChainSync struct {
5557	address             string 
5658	socketPath          string 
5759	ntcTcp              bool 
58- 	bulkMode            bool 
5960	intersectTip        bool 
6061	intersectPoints     []ocommon.Point 
6162	includeCbor         bool 
@@ -65,15 +66,16 @@ type ChainSync struct {
6566	status              * ChainSyncStatus 
6667	errorChan           chan  error 
6768	eventChan           chan  event.Event 
68- 	bulkRangeStart      ocommon.Point 
69- 	bulkRangeEnd        ocommon.Point 
7069	cursorCache         []ocommon.Point 
7170	dialAddress         string 
7271	dialFamily          string 
7372	kupoUrl             string 
7473	kupoClient          * kugo.Client 
7574	delayConfirmations  uint 
7675	delayBuffer         [][]event.Event 
76+ 	pendingBlockPoints  []ocommon.Point 
77+ 	blockfetchDoneChan  chan  struct {}
78+ 	lastTip             ochainsync.Tip 
7779}
7880
7981type  ChainSyncStatus  struct  {
@@ -111,41 +113,16 @@ func (c *ChainSync) Start() error {
111113	if  c .oConn .BlockFetch () !=  nil  {
112114		c .oConn .BlockFetch ().Client .Start ()
113115	}
114- 	// TODO: remove me 
115- 	// Disable bulk mode until we can fix it 
116- 	// https://github.com/blinklabs-io/adder/issues/412 
117- 	c .bulkMode  =  false 
118- 	if  c .bulkMode  &&  ! c .intersectTip  &&  c .oConn .BlockFetch () !=  nil  {
119- 		// Get available block range between our intersect point(s) and the chain tip 
120- 		var  err  error 
121- 		c .bulkRangeStart , c .bulkRangeEnd , err  =  c .oConn .ChainSync ().Client .GetAvailableBlockRange (
122- 			c .intersectPoints ,
123- 		)
116+ 	c .pendingBlockPoints  =  make ([]ocommon.Point , 0 )
117+ 	if  c .intersectTip  {
118+ 		tip , err  :=  c .oConn .ChainSync ().Client .GetCurrentTip ()
124119		if  err  !=  nil  {
125120			return  err 
126121		}
127- 		if  c .bulkRangeStart .Slot  ==  0  ||  c .bulkRangeEnd .Slot  ==  0  {
128- 			// We're already at chain tip, so start a normal sync 
129- 			if  err  :=  c .oConn .ChainSync ().Client .Sync (c .intersectPoints ); err  !=  nil  {
130- 				return  err 
131- 			}
132- 		} else  {
133- 			// Use BlockFetch to request the entire available block range at once 
134- 			if  err  :=  c .oConn .BlockFetch ().Client .GetBlockRange (c .bulkRangeStart , c .bulkRangeEnd ); err  !=  nil  {
135- 				return  err 
136- 			}
137- 		}
138- 	} else  {
139- 		if  c .intersectTip  {
140- 			tip , err  :=  c .oConn .ChainSync ().Client .GetCurrentTip ()
141- 			if  err  !=  nil  {
142- 				return  err 
143- 			}
144- 			c .intersectPoints  =  []ocommon.Point {tip .Point }
145- 		}
146- 		if  err  :=  c .oConn .ChainSync ().Client .Sync (c .intersectPoints ); err  !=  nil  {
147- 			return  err 
148- 		}
122+ 		c .intersectPoints  =  []ocommon.Point {tip .Point }
123+ 	}
124+ 	if  err  :=  c .oConn .ChainSync ().Client .Sync (c .intersectPoints ); err  !=  nil  {
125+ 		return  err 
149126	}
150127	return  nil 
151128}
@@ -228,6 +205,9 @@ func (c *ChainSync) setupConnection() error {
228205		ouroboros .WithBlockFetchConfig (
229206			blockfetch .NewConfig (
230207				blockfetch .WithBlockFunc (c .handleBlockFetchBlock ),
208+ 				blockfetch .WithBatchDoneFunc (c .handleBlockFetchBatchDone ),
209+ 				// Set the recv queue size to 2x our block batch size 
210+ 				blockfetch .WithRecvQueueSize (1000 ),
231211			),
232212		),
233213	)
@@ -309,6 +289,7 @@ func (c *ChainSync) handleRollBackward(
309289	point  ocommon.Point ,
310290	tip  ochainsync.Tip ,
311291) error  {
292+ 	c .lastTip  =  tip 
312293	evt  :=  event .New (
313294		"chainsync.rollback" ,
314295		time .Now (),
@@ -350,21 +331,33 @@ func (c *ChainSync) handleRollForward(
350331	blockData  any ,
351332	tip  ochainsync.Tip ,
352333) error  {
334+ 	c .lastTip  =  tip 
353335	var  block  ledger.Block 
354- 	var  err  error 
355336	tmpEvents  :=  make ([]event.Event , 0 , 20 )
356337	switch  v  :=  blockData .(type ) {
357338	case  ledger.Block :
358339		block  =  v 
359340	case  ledger.BlockHeader :
360- 		blockSlot  :=  v .SlotNumber ()
361- 		block , err  =  c .oConn .BlockFetch ().Client .GetBlock (ocommon.Point {Slot : blockSlot , Hash : v .Hash ().Bytes ()})
362- 		if  err  !=  nil  {
363- 			return  err 
341+ 		c .pendingBlockPoints  =  append (
342+ 			c .pendingBlockPoints ,
343+ 			ocommon.Point {
344+ 				Hash : v .Hash ().Bytes (),
345+ 				Slot : v .SlotNumber (),
346+ 			},
347+ 		)
348+ 		// Don't fetch block unless we hit the batch size or are close to tip 
349+ 		if  v .SlotNumber () <  (tip .Point .Slot - 10000 ) &&  len (c .pendingBlockPoints ) <  blockBatchSize  {
350+ 			return  nil 
364351		}
365- 		if  block  ==  nil  {
366- 			return  errors .New ("blockfetch returned empty" )
352+ 		// Request pending block range 
353+ 		c .blockfetchDoneChan  =  make (chan  struct {})
354+ 		if  err  :=  c .oConn .BlockFetch ().Client .GetBlockRange (c .pendingBlockPoints [0 ], c .pendingBlockPoints [len (c .pendingBlockPoints )- 1 ]); err  !=  nil  {
355+ 			return  err 
367356		}
357+ 		c .pendingBlockPoints  =  make ([]ocommon.Point , 0 )
358+ 		// Wait for block-fetch to finish 
359+ 		<- c .blockfetchDoneChan 
360+ 		return  nil 
368361	default :
369362		return  errors .New ("unknown type" )
370363	}
@@ -462,15 +455,16 @@ func (c *ChainSync) handleBlockFetchBlock(
462455		block .SlotNumber (),
463456		block .BlockNumber (),
464457		block .Hash ().String (),
465- 		c .bulkRangeEnd .Slot ,
466- 		hex .EncodeToString (c .bulkRangeEnd .Hash ),
458+ 		c .lastTip . Point .Slot ,
459+ 		hex .EncodeToString (c .lastTip . Point .Hash ),
467460	)
468- 	// Start normal chain-sync if we've reached the last block of our bulk range 
469- 	if  block .SlotNumber () ==  c .bulkRangeEnd .Slot  {
470- 		if  err  :=  c .oConn .ChainSync ().Client .Sync ([]ocommon.Point {c .bulkRangeEnd }); err  !=  nil  {
471- 			return  err 
472- 		}
473- 	}
461+ 	return  nil 
462+ }
463+ 
464+ func  (c  * ChainSync ) handleBlockFetchBatchDone (
465+ 	ctx  blockfetch.CallbackContext ,
466+ ) error  {
467+ 	close (c .blockfetchDoneChan )
474468	return  nil 
475469}
476470
@@ -492,12 +486,9 @@ func (c *ChainSync) updateStatus(
492486	}
493487	// Determine if we've reached the chain tip 
494488	if  ! c .status .TipReached  {
495- 		// Make sure we're past the end slot in any bulk range, since we don't update the tip during bulk sync 
496- 		if  slotNumber  >  c .bulkRangeEnd .Slot  {
497- 			// Make sure our current slot is equal/higher than our last known tip slot 
498- 			if  c .status .SlotNumber  >  0  &&  slotNumber  >=  c .status .TipSlotNumber  {
499- 				c .status .TipReached  =  true 
500- 			}
489+ 		// Make sure our current slot is equal/higher than our last known tip slot 
490+ 		if  c .status .SlotNumber  >  0  &&  slotNumber  >=  c .status .TipSlotNumber  {
491+ 			c .status .TipReached  =  true 
501492		}
502493	}
503494	c .status .SlotNumber  =  slotNumber 
0 commit comments