From 4bedb577b04e12eead7a532fde5fc552bbf7bf70 Mon Sep 17 00:00:00 2001 From: Agnish Ghosh Date: Mon, 20 Oct 2025 03:38:10 +0530 Subject: [PATCH] make reconstruction timeout dynamic + prevent reconstruction in nonSupernodes --- beacon_chain/nimbus_beacon_node.nim | 13 ++++++++++++- beacon_chain/spec/peerdas_helpers.nim | 22 +++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index ca01ff1354..96532e735b 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -1713,6 +1713,16 @@ proc reconstructDataColumns(node: BeaconNode, slot: Slot) = warn "Failed to get the current slot head" return + let + currentCgc = node.dataColumnQuarantine.custodyColumns.lenu64 + nonSupernode = + currentCgc > node.dag.cfg.NUMBER_OF_CUSTODY_GROUPS div 2 and + currentCgc < node.dag.cfg.NUMBER_OF_CUSTODY_GROUPS + + if not(node.config.peerdasSupernode) or + nonSupernode: + return + withBlck(blck): when consensusFork >= ConsensusFork.Fulu: let maxColCount = node.dag.cfg.NUMBER_OF_COLUMNS @@ -1741,7 +1751,8 @@ proc reconstructDataColumns(node: BeaconNode, slot: Slot) = # Reconstruct columns let recovered = recover_cells_and_proofs_parallel( - node.batchVerifier[].taskpool, columns).valueOr: + node.batchVerifier[].taskpool, columns, + node.dag.cfg.time.SECONDS_PER_SLOT.int64).valueOr: error "Data column reconstruction incomplete" return let rowCount = recovered.len diff --git a/beacon_chain/spec/peerdas_helpers.nim b/beacon_chain/spec/peerdas_helpers.nim index cf43fd386d..ac66e76729 100644 --- a/beacon_chain/spec/peerdas_helpers.nim +++ b/beacon_chain/spec/peerdas_helpers.nim @@ -9,7 +9,7 @@ # Uncategorized helper functions from the spec import - chronos, chronicles, results, taskpools, + chronos, chronicles, results, taskpools, times, eth/p2p/discoveryv5/node, kzg4844/kzg, ssz_serialization/[ @@ -151,7 +151,8 @@ proc recoverCellsAndKzgProofsTask(cellIndices: seq[CellIndex], proc recover_cells_and_proofs_parallel*( tp: Taskpool, - dataColumns: seq[ref fulu.DataColumnSidecar]): + dataColumns: seq[ref fulu.DataColumnSidecar], + slotDuration: int64): Result[seq[CellsAndProofs], cstring] = ## This helper recovers blobs from the data column sidecars parallelly if dataColumns.len == 0: @@ -170,13 +171,15 @@ proc recover_cells_and_proofs_parallel*( res = newSeq[CellsAndProofs](blobCount) let startTime = Moment.now() - const reconstructionTimeout = 2.seconds + let reconstructionTimeout = + (initDuration(nanoseconds = slotDuration * 100_000_000)).inNanoseconds() + # ---- Spawn phase with time limit ---- for blobIdx in 0 ..< blobCount: let now = Moment.now() - if (now - startTime) > reconstructionTimeout: - debug "PeerDAS reconstruction timed out while preparing columns", + if (now - startTime).nanoseconds > reconstructionTimeout: + debug "PeerDAS column reconstruction timed out while preparing columns", spawned = pendingFuts.len, total = blobCount break # Stop spawning new tasks @@ -191,8 +194,8 @@ proc recover_cells_and_proofs_parallel*( # ---- Sync phase ---- for i in 0 ..< pendingFuts.len: let now = Moment.now() - if (now - startTime) > reconstructionTimeout: - debug "PeerDAS reconstruction timed out", + if (now - startTime).nanoseconds > reconstructionTimeout: + debug "PeerDAS column reconstruction timed out while preparing columns", completed = i, totalSpawned = pendingFuts.len return err("Data column reconstruction timed out") @@ -207,6 +210,11 @@ proc recover_cells_and_proofs_parallel*( ok(res) +proc recover_cells_and_proofs_parallel*( + tp: Taskpool, + dataColumns: seq[ref fulu.DataColumnSidecar]): + Result[seq[CellsAndProofs], cstring] = + recover_cells_and_proofs_parallel(tp, dataColumns, 10000'i64) proc assemble_data_column_sidecars*( signed_beacon_block: fulu.SignedBeaconBlock | gloas.SignedBeaconBlock,