88{.push raises : [], gcsafe .}
99
1010import
11- std/ [sets, sequtils, strutils, lists ],
11+ std/ [lists, sets, tables ],
1212 results, metrics,
13- ../ spec/ [presets, helpers, column_map],
13+ ../ spec/ [presets, column_map],
14+ ../ spec/ datatypes/ [fulu, gloas],
1415 ../ beacon_chain_db_quarantine
1516
16- from ../ spec/ datatypes/ deneb import SignedBeaconBlock
17- from ../ spec/ datatypes/ electra import SignedBeaconBlock
18- from ../ spec/ datatypes/ fulu import SignedBeaconBlock
19- from ../ spec/ datatypes/ gloas import SignedBeaconBlock
17+ from std/ sequtils import mapIt, toSeq
18+ from std/ strutils import join
2019
2120export results
2221
6867 db: QuarantineDB
6968 onSidecarCallback* : B
7069
71- OnBlobSidecarCallback * = proc (
72- data: BlobSidecarInfoObject ) {.gcsafe , raises : [].}
7370 OnDataColumnSidecarCallback * = proc (
7471 data: DataColumnSidecarInfoObject ) {.gcsafe , raises : [].}
7572
76- SomeSidecarRef * = ref BlobSidecar | ref fulu.DataColumnSidecar |
77- ref gloas.DataColumnSidecar
78- SomeSidecarIndex * = fulu.ColumnIndex | BlobIndex
73+ SomeSidecarRef * = ref fulu.DataColumnSidecar | ref gloas.DataColumnSidecar
74+ SomeSidecarIndex * = fulu.ColumnIndex
7975 SomeDataColumnSidecar = fulu.DataColumnSidecar | gloas.DataColumnSidecar
8076
81- BlobQuarantine * =
82- SidecarQuarantine [BlobSidecar , OnBlobSidecarCallback ]
8377 ColumnQuarantine * =
8478 SidecarQuarantine [fulu.DataColumnSidecar , OnDataColumnSidecarCallback ]
8579 GloasColumnQuarantine * =
@@ -103,7 +97,7 @@ func isUnloaded[A](holder: SidecarHolder[A]): bool =
10397func isLoaded [A](holder: SidecarHolder [A]): bool =
10498 holder.kind == SidecarHolderKind .Loaded
10599
106- func maxSidecars * (maxSidecarsPerBlock: uint64 ): int =
100+ func maxSidecars (maxSidecarsPerBlock: uint64 ): int =
107101 # Same limit as `MaxOrphans` in `block_quarantine`;
108102 # blobs may arrive before an orphan is tagged `blobless`
109103 3 * int (SLOTS_PER_EPOCH ) * int (maxSidecarsPerBlock)
@@ -161,21 +155,18 @@ func unload[A](holder: var SidecarHolder[A]): ref A =
161155 )
162156 res
163157
164- func getIndex (quarantine: BlobQuarantine , index: BlobIndex ): int =
165- quarantine.indexMap[int (index)]
166-
167158func getIndex [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
168159 quarantine: SidecarQuarantine [A, B], index: ColumnIndex
169160): int =
170161 quarantine.indexMap[int (index)]
171162
172- template slot * (b: BlobSidecar | fulu.DataColumnSidecar ): Slot =
163+ template slot * (b: fulu.DataColumnSidecar ): Slot =
173164 b.signed_block_header.message.slot
174165
175166template slot * (b: gloas.DataColumnSidecar ): Slot =
176167 b.slot
177168
178- template proposer_index (b: BlobSidecar | fulu.DataColumnSidecar ): uint64 =
169+ template proposer_index (b: fulu.DataColumnSidecar ): uint64 =
179170 b.signed_block_header.message.proposer_index
180171
181172template proposer_index (b: gloas.DataColumnSidecar ): uint64 =
@@ -415,17 +406,6 @@ template hasSidecarImpl(
415406 let index = quarantine.getIndex (sidecarIndex)
416407 (index != - 1 ) and not node[].value.sidecars[index].isEmpty ()
417408
418- func hasSidecar * (
419- quarantine: BlobQuarantine ,
420- blockRoot: Eth2Digest ,
421- slot: Slot ,
422- proposer_index: uint64 ,
423- index: BlobIndex ,
424- ): bool =
425- # # Function returns ``true``if quarantine has blob corresponding to specific
426- # # ``block root``, ``index``, ``slot`` and ``proposer_index``.
427- hasSidecarImpl (blockRoot, slot, proposer_index, index)
428-
429409func hasSidecar * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
430410 quarantine: SidecarQuarantine [A, B],
431411 blockRoot: Eth2Digest ,
@@ -454,26 +434,6 @@ func hasSidecar*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarCallback](
454434): bool =
455435 hasSidecarImpl (blockRoot, index)
456436
457- func hasSidecars * (
458- quarantine: BlobQuarantine ,
459- blockRoot: Eth2Digest ,
460- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock |
461- fulu.SignedBeaconBlock
462- ): bool =
463- # # Function returns ``true`` if quarantine has all the blobs for block
464- # # ``blck`` with block root ``blockRoot``.
465- if len (blck.message.body.blob_kzg_commitments) == 0 :
466- return true
467-
468- let node = quarantine.roots.getOrDefault (blockRoot)
469- if isNil (node):
470- return false
471-
472- if node[].value.count < len (blck.message.body.blob_kzg_commitments):
473- # Quarantine does not hold enough blob sidecars.
474- return false
475- true
476-
477437func hasSidecars * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
478438 quarantine: SidecarQuarantine [A, B],
479439 blockRoot: Eth2Digest ,
@@ -497,15 +457,6 @@ func hasSidecars*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarCallback](
497457 return false
498458 true
499459
500- func hasSidecars * (
501- quarantine: BlobQuarantine ,
502- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock |
503- fulu.SignedBeaconBlock
504- ): bool =
505- # # Function returns ``true`` if quarantine has all the blobs for block
506- # # ``blck`` with block root ``blockRoot``.
507- hasSidecars (quarantine, blck.root, blck)
508-
509460func hasSidecars * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
510461 quarantine: SidecarQuarantine [A, B],
511462 blck: fulu.SignedBeaconBlock ,
@@ -522,49 +473,6 @@ func hasSidecars*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarCallback](
522473 # # ``envelope`` with block root ``blockRoot``.
523474 hasSidecars (quarantine, envelope.message.beacon_block_root)
524475
525- proc popSidecars * (
526- quarantine: var BlobQuarantine ,
527- blockRoot: Eth2Digest ,
528- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock
529- ): Opt [seq [ref BlobSidecar ]] =
530- # # Function returns sequence of blob sidecars for block root ``blockRoot`` and
531- # # block ``blck``.
532- # # If some of the blob sidecars are missing Opt.none() is returned.
533- # # If block do not have any blob sidecars Opt.some([]) is returned.
534-
535- let sidecarsCount = len (blck.message.body.blob_kzg_commitments)
536- if sidecarsCount == 0 :
537- # Block does not have any blob sidecars.
538- quarantine.remove (blockRoot)
539- return Opt .some (default (seq [ref BlobSidecar ]))
540-
541- var node = quarantine.roots.getOrDefault (blockRoot)
542- if isNil (node):
543- return Opt .none (seq [ref BlobSidecar ])
544-
545- if node[].value.count < sidecarsCount:
546- # Quarantine does not hold enough blob sidecars.
547- return Opt .none (seq [ref BlobSidecar ])
548-
549- let databaseCount = node[].value.unloaded
550- if databaseCount > 0 :
551- # Quarantine unloaded some blobs to disk, we should load it back.
552- quarantine.loadRoot (blockRoot, node[].value)
553-
554- var sidecars: seq [ref BlobSidecar ]
555- for bindex in 0 ..< len (blck.message.body.blob_kzg_commitments):
556- let index = quarantine.getIndex (BlobIndex (bindex))
557- doAssert (node[].value.sidecars[index].isLoaded (),
558- " Record should only have loaded values, but it is `" &
559- $ node[].value.sidecars[index].kind & " `" )
560- sidecars.add (node[].value.sidecars[index].data)
561-
562- # popSidecars() should remove all the artifacts from the quarantine in both
563- # memory and disk.
564- quarantine.removeNode (node, databaseCount)
565-
566- Opt .some (sidecars)
567-
568476proc popSidecars * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
569477 quarantine: var SidecarQuarantine [A, B],
570478 blockRoot: Eth2Digest
@@ -626,59 +534,6 @@ proc popSidecars*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarCallback](
626534
627535 Opt .some (sidecars)
628536
629- proc popSidecars * (
630- quarantine: var BlobQuarantine ,
631- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock
632- ): Opt [seq [ref BlobSidecar ]] =
633- # # Alias for `popSidecars()`.
634- popSidecars (quarantine, blck.root, blck)
635-
636- func fetchMissingSidecars * (
637- quarantine: BlobQuarantine ,
638- blockRoot: Eth2Digest ,
639- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock
640- ): seq [BlobIdentifier ] =
641- # # Function returns sequence of BlobIdentifiers for blobs which are missing
642- # # for block root ``blockRoot`` and block ``blck``.
643- var res: seq [BlobIdentifier ]
644- let
645- node = quarantine.roots.getOrDefault (blockRoot)
646- commitmentsCount = len (blck.message.body.blob_kzg_commitments)
647-
648- if commitmentsCount == 0 :
649- return res
650- if not (isNil (node)) and (node[].value.count == commitmentsCount):
651- return res
652-
653- for bindex in 0 ..< commitmentsCount:
654- let index = quarantine.getIndex (BlobIndex (bindex))
655- if isNil (node) or node[].value.sidecars[index].isEmpty ():
656- res.add (BlobIdentifier (block_root: blockRoot, index: BlobIndex (bindex)))
657- res
658-
659- func getMissingSidecarIndices * (
660- quarantine: BlobQuarantine ,
661- blockRoot: Eth2Digest ,
662- blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock
663- ): seq [BlobIndex ] =
664- # # Function returns sequence of BlobIndex for blobs which are missing for
665- # # block root ``blockRoot`` and block ``blck``.
666- var res: seq [BlobIndex ]
667- let
668- node = quarantine.roots.getOrDefault (blockRoot)
669- commitmentsCount = len (blck.message.body.blob_kzg_commitments)
670-
671- if commitmentsCount == 0 :
672- return res
673- if not (isNil (node)) and (node[].value.count == commitmentsCount):
674- return res
675-
676- for bindex in 0 ..< commitmentsCount:
677- let index = quarantine.getIndex (BlobIndex (bindex))
678- if isNil (node) or node[].value.sidecars[index].isEmpty ():
679- res.add (BlobIndex (bindex))
680- res
681-
682537func fetchMissingSidecars * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
683538 quarantine: SidecarQuarantine [A, B],
684539 blockRoot: Eth2Digest ,
@@ -791,34 +646,6 @@ func getMissingSidecarIndices*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarC
791646 res.add (item)
792647 res
793648
794- proc pruneAfterFinalization * (
795- quarantine: var BlobQuarantine ,
796- epoch: Epoch ,
797- backfillNeeded: bool
798- ) =
799- let
800- startEpoch =
801- if backfillNeeded:
802- # Because BlobQuarantine could be used as temporary storage for incoming
803- # blob sidecars, we should not prune blobs which are behind
804- # `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` epoch. Otherwise we will not
805- # be able to backfill blobs.
806- if epoch < quarantine.minEpochsForSidecarsRequests:
807- Epoch (0 )
808- else :
809- epoch - quarantine.minEpochsForSidecarsRequests
810- else :
811- epoch
812- epochSlot = (startEpoch + 1 ).start_slot ()
813-
814- var nodes: seq [DoublyLinkedNode [RootTableRecord [BlobSidecar ]]]
815- for node in quarantine.list.nodes ():
816- if (node[].value.count > 0 ) and (node[].value.slot < epochSlot):
817- nodes.add (node)
818-
819- for node in nodes:
820- quarantine.removeNode (node, 0 )
821-
822649proc pruneAfterFinalization * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
823650 quarantine: var SidecarQuarantine [A, B],
824651 epoch: Epoch ,
@@ -847,51 +674,11 @@ proc pruneAfterFinalization*[A: SomeDataColumnSidecar, B: OnDataColumnSidecarCal
847674 for node in nodes:
848675 quarantine.removeNode (node, 0 )
849676
850- template onBlobSidecarCallback * (
851- quarantine: BlobQuarantine
852- ): OnBlobSidecarCallback =
853- quarantine.onSidecarCallback
854-
855677template onDataColumnSidecarCallback * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
856678 quarantine: SidecarQuarantine [A, B]
857679): OnDataColumnSidecarCallback =
858680 quarantine.onSidecarCallback
859681
860- proc init * (
861- T: typedesc [BlobQuarantine ],
862- cfg: RuntimeConfig ,
863- database: QuarantineDB ,
864- maxDiskSizeMultipler: int ,
865- onBlobSidecarCallback: OnBlobSidecarCallback
866- ): BlobQuarantine =
867- # BlobSidecars maps are trivial, but still useful
868- var indexMap = newSeqUninit [int ](cfg.MAX_BLOBS_PER_BLOCK_ELECTRA )
869- for index in 0 ..< len (indexMap):
870- indexMap[index] = index
871-
872- let size = maxSidecars (cfg.MAX_BLOBS_PER_BLOCK_ELECTRA )
873-
874- blob_quarantine_memory_slots_total.set (int64 (size))
875- blob_quarantine_database_slots_total.set (
876- int64 (size) * int64 (maxDiskSizeMultipler))
877- blob_quarantine_memory_slots_occupied.set (0 'i64 )
878- blob_quarantine_database_slots_occupied.set (0 'i64 )
879-
880- BlobQuarantine (
881- minEpochsForSidecarsRequests:
882- cfg.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS ,
883- maxSidecarsPerBlockCount:
884- int (cfg.MAX_BLOBS_PER_BLOCK_ELECTRA ),
885- maxMemSidecarsCount: size,
886- maxDiskSidecarsCount: size * maxDiskSizeMultipler,
887- memSidecarsCount: 0 ,
888- diskSidecarsCount: 0 ,
889- indexMap: indexMap,
890- onSidecarCallback: onBlobSidecarCallback,
891- list: initDoublyLinkedList [RootTableRecord [BlobSidecar ]](),
892- db: database
893- )
894-
895682proc init * [A: SomeDataColumnSidecar , B: OnDataColumnSidecarCallback ](
896683 T: typedesc [SidecarQuarantine [A, B]],
897684 cfg: RuntimeConfig ,
0 commit comments