@@ -36,9 +36,8 @@ const (
3636	// This prevents us exceeding the configured recv queue size in the block-fetch protocol 
3737	blockfetchBatchSize  =  500 
3838
39- 	// TODO: calculate from protocol params 
40- 	// Number of slots from upstream tip to stop doing blockfetch batches 
41- 	blockfetchBatchSlotThreshold  =  2500  *  20 
39+ 	// Default/fallback slot threshold for blockfetch batches 
40+ 	blockfetchBatchSlotThresholdDefault  =  2500  *  20 
4241
4342	// Timeout for updates on a blockfetch operation. This is based on a 2s BatchStart 
4443	// and a 2s Block timeout for blockfetch 
@@ -141,8 +140,10 @@ func (ls *LedgerState) handleEventChainsyncBlockHeader(e ChainsyncEvent) error {
141140	}
142141	// Wait for additional block headers before fetching block bodies if we're 
143142	// far enough out from upstream tip 
143+ 	// Use security window as slot threshold if available 
144+ 	slotThreshold  :=  ls .calculateStabilityWindow ()
144145	if  e .Point .Slot  <  e .Tip .Point .Slot  && 
145- 		(e .Tip .Point .Slot - e .Point .Slot  >  blockfetchBatchSlotThreshold ) && 
146+ 		(e .Tip .Point .Slot - e .Point .Slot  >  slotThreshold ) && 
146147		(headerCount + 1 ) <  allowedHeaderCount  {
147148		return  nil 
148149	}
@@ -267,18 +268,59 @@ func (ls *LedgerState) calculateEpochNonce(
267268		return  genesisHashBytes , nil 
268269	}
269270	// Calculate stability window 
270- 	byronGenesis  :=  ls .config .CardanoNodeConfig .ByronGenesis ()
271271	shelleyGenesis  :=  ls .config .CardanoNodeConfig .ShelleyGenesis ()
272- 	if  byronGenesis  ==  nil  ||  shelleyGenesis  ==  nil  {
273- 		return  nil , errors .New ("could not get genesis config" )
272+ 	if  shelleyGenesis  ==  nil  {
273+ 		return  nil , errors .New ("could not get Shelley genesis config" )
274+ 	}
275+ 	var  securityParam  uint64 
276+ 	// Use K parameter from Byron Genesis during Byron era, SecurityParam from Shelley Genesis for later eras 
277+ 	if  ls .currentEra .Id  ==  0  { // Byron era ID is 0 
278+ 		byronGenesis  :=  ls .config .CardanoNodeConfig .ByronGenesis ()
279+ 		if  byronGenesis  ==  nil  {
280+ 			return  nil , errors .New ("cloud not get Byron genesis config" )
281+ 		}
282+ 		k  :=  byronGenesis .ProtocolConsts .K 
283+ 		if  k  <  0  {
284+ 			return  nil , fmt .Errorf ("k parameter must be non-negative: %d" , k )
285+ 		}
286+ 		// Safe conversion: K is non-negative 
287+ 		securityParam  =  uint64 (k ) // #nosec G115 
288+ 	} else  {
289+ 		secParam  :=  shelleyGenesis .SecurityParam 
290+ 		if  secParam  <  0  {
291+ 			return  nil , fmt .Errorf ("security param must be non-negative: %d" , secParam )
292+ 		}
293+ 		// Safe conversion: SecurityParam is non-negative 
294+ 		securityParam  =  uint64 (secParam ) // #nosec G115 
295+ 	}
296+ 	// Calculate stability window: 3k/f for Shelley+ eras, just k for Byron 
297+ 	var  stabilityWindow  uint64 
298+ 	if  ls .currentEra .Id  ==  0  { // Byron era 
299+ 		stabilityWindow  =  securityParam 
300+ 	} else  {
301+ 		// Validate ActiveSlotsCoeff before using it 
302+ 		if  shelleyGenesis .ActiveSlotsCoeff .Rat  ==  nil  {
303+ 			return  nil , errors .New ("empty ActiveSlotsCoeff" )
304+ 		}
305+ 		activeSlotsRat  :=  shelleyGenesis .ActiveSlotsCoeff .Rat 
306+ 		// Check for division by zero 
307+ 		if  activeSlotsRat .Num ().Sign () ==  0  {
308+ 			return  nil , errors .New ("divide by zero" )
309+ 		}
310+ 		// Compute stability window: floor((3 * securityParam) / f) 
311+ 		// Using integer arithmetic to avoid floating point precision issues 
312+ 		numerator  :=  new (big.Int ).SetUint64 (3  *  securityParam )
313+ 		quotient  :=  new (big.Int ).Div (
314+ 			new (big.Int ).Mul (numerator , activeSlotsRat .Denom ()),
315+ 			activeSlotsRat .Num (),
316+ 		)
317+ 
318+ 		// Check if result fits in uint64 
319+ 		if  ! quotient .IsUint64 () {
320+ 			return  nil , errors .New ("stability window calculation result too large" )
321+ 		}
322+ 		stabilityWindow  =  quotient .Uint64 ()
274323	}
275- 	stabilityWindow  :=  new (big.Rat ).Quo (
276- 		big .NewRat (
277- 			int64 (3 * byronGenesis .ProtocolConsts .K ),
278- 			1 ,
279- 		),
280- 		shelleyGenesis .ActiveSlotsCoeff .Rat ,
281- 	).Num ().Uint64 ()
282324	var  stabilityWindowStartSlot  uint64 
283325	if  epochStartSlot  >  stabilityWindow  {
284326		stabilityWindowStartSlot  =  epochStartSlot  -  stabilityWindow 
0 commit comments