Skip to content

Commit c6d704f

Browse files
authored
Fix blob quarantine updateColumnQuarantine function. (#7759)
* Fix update() function for DataColumnQuarantine. Add tests. Add some helpers to ColumnMap. * Update AllTests. * Remove shortLog printer function.
1 parent 2053090 commit c6d704f

File tree

5 files changed

+338
-15
lines changed

5 files changed

+338
-15
lines changed

AllTests-mainnet.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,18 @@ AllTests-mainnet
172172
```
173173
## ColumnQuarantine data structure test suite [Preset: mainnet]
174174
```diff
175+
+ ColumnQuarantine: update(empty:grow) [node->node] test OK
176+
+ ColumnQuarantine: update(empty:grow) [node->supernode] test OK
177+
+ ColumnQuarantine: update(empty:shrink) [node->node] test OK
178+
+ ColumnQuarantine: update(empty:shrink) [supernode->node] test OK
179+
+ ColumnQuarantine: update(memory+disk:grow) [node->node] test OK
180+
+ ColumnQuarantine: update(memory+disk:grow) [node->supernode] test OK
181+
+ ColumnQuarantine: update(memory+disk:shrink) [node->node] test OK
182+
+ ColumnQuarantine: update(memory+disk:shrink) [supernode->node] test OK
183+
+ ColumnQuarantine: update(memory:grow) [node->node] test OK
184+
+ ColumnQuarantine: update(memory:grow) [node->supernode] test OK
185+
+ ColumnQuarantine: update(memory:shrink) [node->node] test OK
186+
+ ColumnQuarantine: update(memory:shrink) [supernode->node] test OK
175187
+ Empty in-memory scenario test [node] OK
176188
+ Empty in-memory scenario test [supernode] OK
177189
+ Mixed entries scenario test [node] OK

beacon_chain/consensus_object_pools/blob_quarantine.nim

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ type
8282
ColumnQuarantine* =
8383
SidecarQuarantine[fulu.DataColumnSidecar, OnDataColumnSidecarCallback]
8484

85+
ColumnQuarantineNode* =
86+
DoublyLinkedNode[RootTableRecord[fulu.DataColumnSidecar]]
87+
8588
func indexLog*[T: SomeSidecarRef](sidecars: openArray[ref T]): string =
8689
"[" & sidecars.mapIt($uint64(it[].index)).join(",") & "]"
8790

@@ -886,12 +889,13 @@ proc init*(
886889
onDataColumnSidecarCallback: OnDataColumnSidecarCallback
887890
): ColumnQuarantine =
888891
doAssert(len(custodyColumns) <= NUMBER_OF_COLUMNS)
892+
893+
let custodyMap = ColumnMap.init(custodyColumns)
889894
var indexMap = newSeqUninit[int](NUMBER_OF_COLUMNS)
890895
if len(custodyColumns) < NUMBER_OF_COLUMNS:
891896
for i in 0 ..< len(indexMap):
892897
indexMap[i] = -1
893-
for index, item in custodyColumns.pairs():
894-
doAssert(item < uint64(NUMBER_OF_COLUMNS))
898+
for index, item in custodyMap.pairs():
895899
indexMap[int(item)] = index
896900

897901
let size = maxSidecars(NUMBER_OF_COLUMNS)
@@ -911,27 +915,84 @@ proc init*(
911915
memSidecarsCount: 0,
912916
diskSidecarsCount: 0,
913917
indexMap: indexMap,
914-
custodyColumns: @custodyColumns,
915-
custodyMap: ColumnMap.init(custodyColumns),
918+
custodyColumns: toSeq(custodyMap.items),
919+
custodyMap: custodyMap,
916920
list: initDoublyLinkedList[RootTableRecord[fulu.DataColumnSidecar]](),
917921
db: database,
918922
onSidecarCallback: onDataColumnSidecarCallback
919923
)
920924

921-
func updateColumnQuarantine*(
922-
quarantine: ref ColumnQuarantine,
925+
proc update*(
926+
quarantine: var ColumnQuarantine,
923927
cfg: RuntimeConfig,
924-
custodyColumns: openArray[ColumnIndex]) =
928+
custodyColumns: openArray[ColumnIndex]
929+
) =
925930
doAssert(len(custodyColumns) <= NUMBER_OF_COLUMNS)
931+
let
932+
custodyMap = ColumnMap.init(custodyColumns)
933+
maxSidecarsPerBlockCount = len(custodyMap)
934+
926935
var indexMap = newSeqUninit[int](NUMBER_OF_COLUMNS)
927936
if len(custodyColumns) < NUMBER_OF_COLUMNS:
928937
for i in 0 ..< len(indexMap):
929938
indexMap[i] = -1
930-
for index, item in custodyColumns.pairs():
931-
doAssert(item < uint64(NUMBER_OF_COLUMNS))
939+
for index, item in custodyMap.pairs():
932940
indexMap[int(item)] = index
933941

934-
quarantine.maxSidecarsPerBlockCount = len(custodyColumns)
942+
var
943+
memSidecarsCount = 0
944+
diskSidecarsCount = 0
945+
nodesToRemove: seq[ColumnQuarantineNode]
946+
947+
for node in quarantine.list.nodes():
948+
var
949+
sidecars =
950+
newSeq[SidecarHolder[fulu.DataColumnSidecar]](len(custodyMap))
951+
count = 0
952+
unloaded = 0
953+
954+
for cindex in quarantine.custodyMap.items():
955+
let
956+
index = quarantine.getIndex(cindex)
957+
sidecar = node[].value.sidecars[index]
958+
959+
if not(isEmpty(sidecar)):
960+
if cindex in custodyMap:
961+
let dindex = indexMap[int(cindex)]
962+
if dindex >= 0:
963+
sidecars[dindex] = sidecar
964+
inc(count)
965+
if not(sidecar.isLoaded()):
966+
inc(unloaded)
967+
968+
node.value.sidecars.reset()
969+
970+
if count > 0:
971+
node[].value.sidecars = sidecars
972+
node[].value.count = count
973+
node[].value.unloaded = unloaded
974+
# We do account sidecars which are useful in new configuration, but
975+
# its possible that some sidecars will be left on disk which can't be
976+
# used in new configuration, and we can't delete it easily. But this
977+
# sidecars will be deleted as soon as sidecars with same `block_root`
978+
# will be popped out from quarantine.
979+
diskSidecarsCount.inc(unloaded)
980+
memSidecarsCount.inc(count - unloaded)
981+
else:
982+
# If there no useful columns, we will mark this node for deletion.
983+
nodesToRemove.add(node)
984+
985+
for node in nodesToRemove:
986+
quarantine.removeNode(node, 0)
987+
988+
quarantine.diskSidecarsCount = diskSidecarsCount
989+
quarantine.memSidecarsCount = memSidecarsCount
990+
blob_quarantine_memory_slots_occupied.set(
991+
int64(quarantine.memSidecarsCount))
992+
blob_quarantine_database_slots_occupied.set(
993+
int64(quarantine.diskSidecarsCount))
994+
995+
quarantine.maxSidecarsPerBlockCount = maxSidecarsPerBlockCount
935996
quarantine.indexMap = indexMap
936-
quarantine.custodyColumns = @custodyColumns
937-
quarantine.custodyMap = ColumnMap.init(custodyColumns)
997+
quarantine.custodyColumns = toSeq(custodyMap.items)
998+
quarantine.custodyMap = custodyMap

beacon_chain/nimbus_beacon_node.nim

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,8 +2056,7 @@ proc onSlotEnd(node: BeaconNode, slot: Slot) {.async.} =
20562056
node.validatorCustody.newer_column_set.toSeq()
20572057
sort(custodyColumns)
20582058
# update custody columns
2059-
node.dataColumnQuarantine.updateColumnQuarantine(
2060-
node.dag.cfg, custodyColumns)
2059+
node.dataColumnQuarantine[].update(node.dag.cfg, custodyColumns)
20612060

20622061
# Update CGC and metadata with respect to the new detected validator custody
20632062
let new_vcus = CgcCount node.validatorCustody.newer_column_set.lenu64

beacon_chain/spec/column_map.nim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ func `xor`*(a, b: ColumnMap): ColumnMap =
6565
func `not`*(a: ColumnMap): ColumnMap =
6666
ColumnMap(data: [not(a.data[0]), not(a.data[1])])
6767

68+
func `==`*(a, b: ColumnMap): bool =
69+
(a.data[0] == b.data[0]) and (a.data[1] == b.data[1])
70+
6871
func empty*(a: ColumnMap): bool =
6972
(a.data[0] == 0'u64) and (a.data[1] == 0'u64)
7073

@@ -89,6 +92,12 @@ iterator items*(a: ColumnMap): ColumnIndex =
8992
yield ColumnIndex(64 + res - 1)
9093
data1 = data1 xor t
9194

95+
iterator pairs*(a: ColumnMap): (int, ColumnIndex) =
96+
var index = 0
97+
for item in a.items():
98+
yield (index, item)
99+
inc(index)
100+
92101
func len*(a: ColumnMap): int =
93102
# Returns number of columns in map.
94103
countOnes(a.data[0]) + countOnes(a.data[1])

0 commit comments

Comments
 (0)