2022-03-15 17:56:56 +00:00
|
|
|
# beacon_chain
|
2024-01-06 14:26:56 +00:00
|
|
|
# Copyright (c) 2020-2024 Status Research & Development GmbH
|
2022-03-15 17:56:56 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2024-02-18 01:16:49 +00:00
|
|
|
{.push raises: [].}
|
2020-04-22 05:53:02 +00:00
|
|
|
{.used.}
|
|
|
|
|
2023-02-11 20:48:35 +00:00
|
|
|
import std/[strutils, sequtils]
|
2021-04-28 16:41:02 +00:00
|
|
|
import unittest2
|
2024-11-22 19:51:18 +00:00
|
|
|
import chronos, chronos/unittest2/asynctests
|
|
|
|
import ../beacon_chain/networking/peer_scores
|
2021-05-28 16:34:00 +00:00
|
|
|
import ../beacon_chain/gossip_processing/block_processor,
|
2021-07-15 19:01:07 +00:00
|
|
|
../beacon_chain/sync/sync_manager,
|
2024-11-22 19:51:18 +00:00
|
|
|
../beacon_chain/sync/sync_queue,
|
2021-08-10 20:46:35 +00:00
|
|
|
../beacon_chain/spec/forks
|
2020-04-20 14:59:18 +00:00
|
|
|
|
2020-05-19 12:08:50 +00:00
|
|
|
type
|
|
|
|
SomeTPeer = ref object
|
2024-11-22 19:51:18 +00:00
|
|
|
id: string
|
2022-09-16 19:45:53 +00:00
|
|
|
score: int
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
func init(t: typedesc[SomeTPeer], id: string, score = 1000): SomeTPeer =
|
|
|
|
SomeTPeer(id: id, score: score)
|
|
|
|
|
2024-03-03 01:04:45 +00:00
|
|
|
func `$`(peer: SomeTPeer): string =
|
2024-11-22 19:51:18 +00:00
|
|
|
"peer#" & peer.id
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2022-03-03 08:05:33 +00:00
|
|
|
template shortLog(peer: SomeTPeer): string =
|
|
|
|
$peer
|
|
|
|
|
2024-03-03 01:04:45 +00:00
|
|
|
func updateScore(peer: SomeTPeer, score: int) =
|
2022-09-16 19:45:53 +00:00
|
|
|
peer[].score += score
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2024-03-03 01:04:45 +00:00
|
|
|
func updateStats(peer: SomeTPeer, index: SyncResponseKind, score: uint64) =
|
2022-09-19 09:37:42 +00:00
|
|
|
discard
|
|
|
|
|
2024-03-03 01:04:45 +00:00
|
|
|
func getStats(peer: SomeTPeer, index: SyncResponseKind): uint64 =
|
2022-09-19 09:37:42 +00:00
|
|
|
0
|
|
|
|
|
2022-03-15 17:56:56 +00:00
|
|
|
func getStaticSlotCb(slot: Slot): GetSlotCallback =
|
|
|
|
proc getSlot(): Slot =
|
|
|
|
slot
|
|
|
|
getSlot
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2021-12-16 14:57:16 +00:00
|
|
|
type
|
|
|
|
BlockEntry = object
|
|
|
|
blck*: ForkedSignedBeaconBlock
|
2022-11-10 17:40:27 +00:00
|
|
|
resfut*: Future[Result[void, VerifierError]]
|
2021-12-16 14:57:16 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
func createChain(slots: Slice[Slot]): seq[ref ForkedSignedBeaconBlock] =
|
|
|
|
var res = newSeqOfCap[ref ForkedSignedBeaconBlock](len(slots))
|
|
|
|
for slot in slots:
|
|
|
|
let item = newClone ForkedSignedBeaconBlock(kind: ConsensusFork.Deneb)
|
|
|
|
item[].denebData.message.slot = slot
|
|
|
|
res.add(item)
|
|
|
|
res
|
|
|
|
|
|
|
|
proc createChain(srange: SyncRange): seq[ref ForkedSignedBeaconBlock] =
|
|
|
|
createChain(srange.slot .. (srange.slot + srange.count - 1))
|
|
|
|
|
|
|
|
func createBlobs(
|
|
|
|
blocks: var seq[ref ForkedSignedBeaconBlock],
|
|
|
|
slots: openArray[Slot]
|
|
|
|
): seq[ref BlobSidecar] =
|
|
|
|
var res = newSeq[ref BlobSidecar](len(slots))
|
|
|
|
for blck in blocks:
|
|
|
|
withBlck(blck[]):
|
|
|
|
when consensusFork >= ConsensusFork.Deneb:
|
|
|
|
template kzgs: untyped = forkyBlck.message.body.blob_kzg_commitments
|
|
|
|
for i, slot in slots:
|
|
|
|
if slot == forkyBlck.message.slot:
|
|
|
|
doAssert kzgs.add default(KzgCommitment)
|
|
|
|
if kzgs.len > 0:
|
|
|
|
forkyBlck.root = hash_tree_root(forkyBlck.message)
|
|
|
|
var
|
|
|
|
kzg_proofs: KzgProofs
|
|
|
|
blobs: Blobs
|
|
|
|
for _ in kzgs:
|
|
|
|
doAssert kzg_proofs.add default(KzgProof)
|
|
|
|
doAssert blobs.add default(Blob)
|
|
|
|
let sidecars = forkyBlck.create_blob_sidecars(kzg_proofs, blobs)
|
|
|
|
var sidecarIdx = 0
|
2024-01-18 14:45:10 +00:00
|
|
|
for i, slot in slots:
|
|
|
|
if slot == forkyBlck.message.slot:
|
2024-11-22 19:51:18 +00:00
|
|
|
res[i] = newClone sidecars[sidecarIdx]
|
|
|
|
inc sidecarIdx
|
|
|
|
res
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
func collector(queue: AsyncQueue[BlockEntry]): BlockVerifier =
|
|
|
|
proc verify(
|
|
|
|
signedBlock: ForkedSignedBeaconBlock,
|
|
|
|
blobs: Opt[BlobSidecars],
|
|
|
|
maybeFinalized: bool
|
|
|
|
): Future[Result[void, VerifierError]] {.
|
|
|
|
async: (raises: [CancelledError], raw: true).} =
|
|
|
|
let fut =
|
|
|
|
Future[Result[void, VerifierError]].Raising([CancelledError]).init()
|
|
|
|
try:
|
|
|
|
queue.addLastNoWait(BlockEntry(blck: signedBlock, resfut: fut))
|
|
|
|
except CatchableError as exc:
|
|
|
|
raiseAssert exc.msg
|
|
|
|
fut
|
|
|
|
verify
|
|
|
|
|
|
|
|
proc setupVerifier(
|
|
|
|
skind: SyncQueueKind,
|
|
|
|
sc: openArray[tuple[slots: Slice[Slot], code: Opt[VerifierError]]]
|
|
|
|
): tuple[collector: BlockVerifier, verifier: Future[void]] =
|
|
|
|
doAssert(len(sc) > 0, "Empty scenarios are not allowed")
|
|
|
|
|
|
|
|
var
|
|
|
|
scenario = @sc
|
|
|
|
aq = newAsyncQueue[BlockEntry]()
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2021-12-16 14:57:16 +00:00
|
|
|
template done(b: BlockEntry) =
|
2022-11-10 17:40:27 +00:00
|
|
|
b.resfut.complete(Result[void, VerifierError].ok())
|
2021-12-16 14:57:16 +00:00
|
|
|
template fail(b: BlockEntry, e: untyped) =
|
2022-11-10 17:40:27 +00:00
|
|
|
b.resfut.complete(Result[void, VerifierError].err(e))
|
2024-11-22 19:51:18 +00:00
|
|
|
template verifyBlock(i, e, s, v: untyped): untyped =
|
|
|
|
let item = await queue.popFirst()
|
|
|
|
if item.blck.slot == s:
|
|
|
|
if e.code.isSome():
|
|
|
|
item.fail(e.code.get())
|
|
|
|
else:
|
|
|
|
item.done()
|
|
|
|
else:
|
|
|
|
raiseAssert "Verifier got block from incorrect slot, " &
|
|
|
|
"expected " & $s & ", got " &
|
|
|
|
$item.blck.slot & ", position [" &
|
|
|
|
$i & ", " & $s & "]"
|
|
|
|
inc(v)
|
|
|
|
|
|
|
|
proc verifier(queue: AsyncQueue[BlockEntry]) {.async: (raises: []).} =
|
|
|
|
var slotsVerified = 0
|
|
|
|
try:
|
|
|
|
for index, entry in scenario.pairs():
|
|
|
|
case skind
|
2021-12-08 21:15:29 +00:00
|
|
|
of SyncQueueKind.Forward:
|
2024-11-22 19:51:18 +00:00
|
|
|
for slot in countup(entry.slots.a, entry.slots.b):
|
|
|
|
verifyBlock(index, entry, slot, slotsVerified)
|
2021-12-08 21:15:29 +00:00
|
|
|
of SyncQueueKind.Backward:
|
2024-11-22 19:51:18 +00:00
|
|
|
for slot in countdown(entry.slots.b, entry.slots.a):
|
|
|
|
verifyBlock(index, entry, slot, slotsVerified)
|
|
|
|
except CancelledError:
|
|
|
|
raiseAssert "Scenario is not completed, " &
|
|
|
|
"number of slots passed " & $slotsVerified
|
2020-08-10 07:15:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
(collector(aq), verifier(aq))
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
suite "SyncManager test suite":
|
|
|
|
for kind in [SyncQueueKind.Forward, SyncQueueKind.Backward]:
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Smoke [single peer] test":
|
|
|
|
# Four ranges was distributed to single peer only.
|
|
|
|
let
|
|
|
|
scenario = [
|
|
|
|
(Slot(0) .. Slot(127), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(127),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(127), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(127)),
|
|
|
|
verifier.collector)
|
|
|
|
peer = SomeTPeer.init("1")
|
|
|
|
r1 = sq.pop(Slot(127), peer)
|
|
|
|
r2 = sq.pop(Slot(127), peer)
|
|
|
|
r3 = sq.pop(Slot(127), peer)
|
|
|
|
d1 = createChain(r1.data)
|
|
|
|
d2 = createChain(r2.data)
|
|
|
|
d3 = createChain(r3.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f1 = sq.push(r1, d1, Opt.none(seq[BlobSidecars]))
|
|
|
|
f2 = sq.push(r2, d2, Opt.none(seq[BlobSidecars]))
|
|
|
|
f3 = sq.push(r3, d3, Opt.none(seq[BlobSidecars]))
|
2021-12-08 21:15:29 +00:00
|
|
|
|
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f1.finished == false
|
|
|
|
f2.finished == false
|
|
|
|
f3.finished == false
|
|
|
|
|
|
|
|
await noCancel f1
|
|
|
|
|
2021-12-08 21:15:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f1.finished == true
|
|
|
|
f2.finished == false
|
|
|
|
f3.finished == false
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f2
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
check:
|
|
|
|
f1.finished == true
|
|
|
|
f2.finished == true
|
|
|
|
f3.finished == false
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f3
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
check:
|
|
|
|
f1.finished == true
|
|
|
|
f2.finished == true
|
|
|
|
f3.finished == true
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r4 = sq.pop(Slot(127), peer)
|
|
|
|
d4 = createChain(r4.data)
|
|
|
|
f4 = sq.push(r4, d4, Opt.none(seq[BlobSidecars]))
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f4
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
check:
|
|
|
|
f1.finished == true
|
|
|
|
f2.finished == true
|
|
|
|
f3.finished == true
|
|
|
|
f4.finished == true
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Smoke [3 peers] test":
|
|
|
|
# Three ranges was distributed between 3 peers, every range is going to
|
|
|
|
# be pushed by all peers.
|
|
|
|
let
|
|
|
|
scenario = [
|
|
|
|
(Slot(0) .. Slot(127), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(127),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(127), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(127)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(127), peer1)
|
|
|
|
r12 = sq.pop(Slot(127), peer2)
|
|
|
|
r13 = sq.pop(Slot(127), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
r21 = sq.pop(Slot(127), peer1)
|
|
|
|
r22 = sq.pop(Slot(127), peer2)
|
|
|
|
r23 = sq.pop(Slot(127), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
r31 = sq.pop(Slot(127), peer1)
|
|
|
|
r32 = sq.pop(Slot(127), peer2)
|
|
|
|
r33 = sq.pop(Slot(127), peer3)
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
check:
|
|
|
|
f11.finished == true
|
|
|
|
# We do not check f12 and f13 here because their state is undefined
|
|
|
|
# at this time.
|
|
|
|
f21.finished == false
|
|
|
|
f22.finished == false
|
|
|
|
f23.finished == false
|
|
|
|
f31.finished == false
|
|
|
|
f32.finished == false
|
|
|
|
f33.finished == false
|
|
|
|
|
|
|
|
await noCancel f22
|
|
|
|
check:
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
# We do not check f21 and f23 here because their state is undefined
|
|
|
|
# at this time.
|
|
|
|
f31.finished == false
|
|
|
|
f32.finished == false
|
|
|
|
f33.finished == false
|
|
|
|
|
|
|
|
await noCancel f33
|
|
|
|
check:
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f23.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
# We do not check f31 and f32 here because their state is undefined
|
|
|
|
# at this time.
|
2022-03-15 17:56:56 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r41 = sq.pop(Slot(127), peer1)
|
|
|
|
d41 = createChain(r41.data)
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel sq.push(r41, d41, Opt.none(seq[BlobSidecars]))
|
2021-12-08 21:15:29 +00:00
|
|
|
|
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f23.finished == true
|
|
|
|
f31.finished == true
|
|
|
|
f32.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Failure request push test":
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
[
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
[
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(63),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(63), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(63)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
|
|
|
|
block:
|
|
|
|
let
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
|
|
|
|
sq.push(r11)
|
|
|
|
sq.push(r12)
|
|
|
|
sq.push(r13)
|
|
|
|
# Next couple of calls should be detected as non relevant
|
|
|
|
sq.push(r11)
|
|
|
|
sq.push(r12)
|
|
|
|
sq.push(r13)
|
|
|
|
|
|
|
|
block:
|
|
|
|
let
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
|
|
|
|
sq.push(r11)
|
|
|
|
await noCancel sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
sq.push(r13)
|
|
|
|
# Next couple of calls should be detected as non relevant
|
|
|
|
sq.push(r11)
|
|
|
|
sq.push(r12)
|
|
|
|
sq.push(r13)
|
|
|
|
|
|
|
|
block:
|
|
|
|
let
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
|
|
|
|
sq.push(r11)
|
|
|
|
sq.push(r12)
|
|
|
|
await noCancel sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
# Next couple of calls should be detected as non relevant
|
|
|
|
sq.push(r11)
|
|
|
|
sq.push(r12)
|
|
|
|
sq.push(r13)
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Invalid block [3 peers] test":
|
|
|
|
# This scenario performs test for 2 cases.
|
|
|
|
# 1. When first error encountered it just drops the the response and
|
|
|
|
# increases `failuresCounter`.
|
|
|
|
# 2. When another error encountered it will reset whole queue to the
|
|
|
|
# last known good/safe point (rewind process).
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
[
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.none(VerifierError)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.Invalid)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.Invalid)),
|
|
|
|
(Slot(0) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.none(VerifierError)),
|
|
|
|
(Slot(42) .. Slot(63), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
[
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.Invalid)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.Invalid)),
|
|
|
|
(Slot(32) .. Slot(63), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.none(VerifierError)),
|
|
|
|
(Slot(0) .. Slot(20), Opt.none(VerifierError)),
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(63),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(63), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(63)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
r21 = sq.pop(Slot(63), peer1)
|
|
|
|
r22 = sq.pop(Slot(63), peer2)
|
|
|
|
r23 = sq.pop(Slot(63), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
check f11.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f21
|
2021-12-08 21:15:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f21.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f22
|
2021-12-08 21:15:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
|
|
|
|
await noCancel f23
|
2021-12-08 21:15:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f23.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
r31 = sq.pop(Slot(63), peer1)
|
|
|
|
r32 = sq.pop(Slot(63), peer2)
|
|
|
|
r33 = sq.pop(Slot(63), peer3)
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
r41 = sq.pop(Slot(63), peer1)
|
|
|
|
r42 = sq.pop(Slot(63), peer2)
|
|
|
|
r43 = sq.pop(Slot(63), peer3)
|
|
|
|
d41 = createChain(r41.data)
|
|
|
|
d42 = createChain(r42.data)
|
|
|
|
d43 = createChain(r43.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
f42 = sq.push(r42, d42, Opt.none(seq[BlobSidecars]))
|
|
|
|
f41 = sq.push(r41, d41, Opt.none(seq[BlobSidecars]))
|
|
|
|
f43 = sq.push(r43, d43, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f31
|
2021-12-08 21:15:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f31.finished == true
|
2020-05-28 05:02:28 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f42
|
|
|
|
check:
|
|
|
|
f31.finished == true
|
|
|
|
f32.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
f42.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f43
|
|
|
|
check:
|
|
|
|
f31.finished == true
|
|
|
|
f32.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
f41.finished == true
|
|
|
|
f42.finished == true
|
|
|
|
f43.finished == true
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Unviable block [3 peers] test":
|
|
|
|
# This scenario performs test for 2 cases.
|
|
|
|
# 1. When first error encountered it just drops the the response and
|
|
|
|
# increases `failuresCounter`.
|
|
|
|
# 2. When another error encountered it will reset whole queue to the
|
|
|
|
# last known good/safe point (rewind process).
|
|
|
|
# Unviable fork blocks processed differently from invalid blocks, all
|
|
|
|
# this blocks should be added to quarantine, so blocks range is not get
|
|
|
|
# failed immediately.
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
[
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.none(VerifierError)),
|
|
|
|
(Slot(41) .. Slot(63), Opt.some(VerifierError.UnviableFork)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(63), Opt.some(VerifierError.UnviableFork)),
|
|
|
|
(Slot(0) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(63), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
[
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(0) .. Slot(21), Opt.some(VerifierError.UnviableFork)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(0) .. Slot(21), Opt.some(VerifierError.UnviableFork)),
|
|
|
|
(Slot(32) .. Slot(63), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(0) .. Slot(21), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(63),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(63), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(63)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
r21 = sq.pop(Slot(63), peer1)
|
|
|
|
r22 = sq.pop(Slot(63), peer2)
|
|
|
|
r23 = sq.pop(Slot(63), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
check f11.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f21
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f22
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f23
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f23.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
r31 = sq.pop(Slot(63), peer1)
|
|
|
|
r32 = sq.pop(Slot(63), peer2)
|
|
|
|
r33 = sq.pop(Slot(63), peer3)
|
|
|
|
|
|
|
|
let
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
r41 = sq.pop(Slot(63), peer1)
|
|
|
|
r42 = sq.pop(Slot(63), peer2)
|
|
|
|
r43 = sq.pop(Slot(63), peer3)
|
|
|
|
d41 = createChain(r41.data)
|
|
|
|
d42 = createChain(r42.data)
|
|
|
|
d43 = createChain(r43.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
f42 = sq.push(r42, d42, Opt.none(seq[BlobSidecars]))
|
|
|
|
f41 = sq.push(r41, d41, Opt.none(seq[BlobSidecars]))
|
|
|
|
f43 = sq.push(r43, d43, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f31
|
|
|
|
check:
|
|
|
|
f31.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f42
|
|
|
|
check:
|
|
|
|
f31.finished == true
|
|
|
|
f32.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
f42.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f43
|
2022-01-26 12:20:08 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
f31.finished == true
|
|
|
|
f32.finished == true
|
|
|
|
f33.finished == true
|
|
|
|
f41.finished == true
|
|
|
|
f42.finished == true
|
|
|
|
f43.finished == true
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue# & " & $kind & "] Combination of missing parent " &
|
|
|
|
"and good blocks [3 peers] test":
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
[
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.none(VerifierError)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(41), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(32) .. Slot(40), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(41) .. Slot(63), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
[
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(21) .. Slot(21), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(22) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(0) .. Slot(21), Opt.none(VerifierError)),
|
|
|
|
]
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq =
|
|
|
|
case kind
|
|
|
|
of SyncQueueKind.Forward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(63),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
of SyncQueueKind.Backward:
|
|
|
|
SyncQueue.init(SomeTPeer, kind, Slot(63), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(63)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(63), peer1)
|
|
|
|
r12 = sq.pop(Slot(63), peer2)
|
|
|
|
r13 = sq.pop(Slot(63), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
r21 = sq.pop(Slot(63), peer1)
|
|
|
|
r22 = sq.pop(Slot(63), peer2)
|
|
|
|
r23 = sq.pop(Slot(63), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
|
|
|
|
let
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
check f11.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f21
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
f11.finished == true
|
2024-11-22 19:51:18 +00:00
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f22
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
await noCancel f23
|
|
|
|
check:
|
|
|
|
f21.finished == true
|
|
|
|
f22.finished == true
|
|
|
|
f23.finished == true
|
|
|
|
f11.finished == true
|
|
|
|
f12.finished == true
|
|
|
|
f13.finished == true
|
|
|
|
|
|
|
|
let
|
|
|
|
r31 = sq.pop(Slot(63), peer1)
|
|
|
|
r32 = sq.pop(Slot(63), peer2)
|
|
|
|
r33 = sq.pop(Slot(63), peer3)
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f31
|
|
|
|
await noCancel f32
|
|
|
|
await noCancel f33
|
|
|
|
|
|
|
|
let
|
|
|
|
r41 = sq.pop(Slot(63), peer1)
|
|
|
|
r42 = sq.pop(Slot(63), peer2)
|
|
|
|
r43 = sq.pop(Slot(63), peer3)
|
|
|
|
d41 = createChain(r41.data)
|
|
|
|
d42 = createChain(r42.data)
|
|
|
|
d43 = createChain(r43.data)
|
|
|
|
f42 = sq.push(r32, d42, Opt.none(seq[BlobSidecars]))
|
|
|
|
f41 = sq.push(r31, d41, Opt.none(seq[BlobSidecars]))
|
|
|
|
f43 = sq.push(r33, d43, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel allFutures(f42, f41, f43)
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue#Forward] Missing parent and exponential rewind " &
|
|
|
|
"[3 peers] test":
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
[
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError)),
|
|
|
|
# .. 3 ranges are empty
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
# 1st rewind should be to (failed_slot - 1 * epoch) = 96
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
# 2nd rewind should be to (failed_slot - 2 * epoch) = 64
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(128), Opt.some(VerifierError.MissingParent)),
|
|
|
|
# 3rd rewind should be to (failed_slot - 4 * epoch) = 0
|
|
|
|
(Slot(0) .. Slot(31), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(64) .. Slot(95), Opt.none(VerifierError)),
|
|
|
|
(Slot(96) .. Slot(127), Opt.none(VerifierError)),
|
|
|
|
(Slot(128) .. Slot(159), Opt.none(VerifierError)),
|
|
|
|
]
|
|
|
|
kind = SyncQueueKind.Forward
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq = SyncQueue.init(SomeTPeer, kind, Slot(0), Slot(159),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(0)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(159), peer1)
|
|
|
|
r12 = sq.pop(Slot(159), peer2)
|
|
|
|
r13 = sq.pop(Slot(159), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
await noCancel f12
|
|
|
|
await noCancel f13
|
|
|
|
|
|
|
|
for i in 0 ..< 3:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2022-01-26 12:20:08 +00:00
|
|
|
|
2021-12-08 21:15:29 +00:00
|
|
|
let
|
2024-11-22 19:51:18 +00:00
|
|
|
r21 = sq.pop(Slot(159), peer1)
|
|
|
|
r22 = sq.pop(Slot(159), peer2)
|
|
|
|
r23 = sq.pop(Slot(159), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f21
|
|
|
|
await noCancel f22
|
|
|
|
await noCancel f23
|
|
|
|
|
|
|
|
for i in 0 ..< 1:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r31 = sq.pop(Slot(159), peer1)
|
|
|
|
r32 = sq.pop(Slot(159), peer2)
|
|
|
|
r33 = sq.pop(Slot(159), peer3)
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f31
|
|
|
|
await noCancel f32
|
|
|
|
await noCancel f33
|
|
|
|
|
|
|
|
for i in 0 ..< 2:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r41 = sq.pop(Slot(159), peer1)
|
|
|
|
r42 = sq.pop(Slot(159), peer2)
|
|
|
|
r43 = sq.pop(Slot(159), peer3)
|
|
|
|
d41 = createChain(r41.data)
|
|
|
|
d42 = createChain(r42.data)
|
|
|
|
d43 = createChain(r43.data)
|
|
|
|
f41 = sq.push(r41, d41, Opt.none(seq[BlobSidecars]))
|
|
|
|
f42 = sq.push(r42, d42, Opt.none(seq[BlobSidecars]))
|
|
|
|
f43 = sq.push(r43, d43, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f41
|
|
|
|
await noCancel f42
|
|
|
|
await noCancel f43
|
|
|
|
|
|
|
|
for i in 0 ..< 5:
|
|
|
|
let
|
|
|
|
rf1 = sq.pop(Slot(159), peer1)
|
|
|
|
rf2 = sq.pop(Slot(159), peer2)
|
|
|
|
rf3 = sq.pop(Slot(159), peer3)
|
|
|
|
df1 = createChain(rf1.data)
|
|
|
|
df2 = createChain(rf2.data)
|
|
|
|
df3 = createChain(rf3.data)
|
|
|
|
ff1 = sq.push(rf1, df1, Opt.none(seq[BlobSidecars]))
|
|
|
|
ff2 = sq.push(rf2, df2, Opt.none(seq[BlobSidecars]))
|
|
|
|
ff3 = sq.push(rf3, df3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel ff1
|
|
|
|
await noCancel ff2
|
|
|
|
await noCancel ff3
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
|
|
|
|
|
|
|
asyncTest "[SyncQueue#Backward] Missing parent and exponential rewind " &
|
|
|
|
"[3 peers] test":
|
|
|
|
let
|
|
|
|
scenario =
|
|
|
|
[
|
|
|
|
(Slot(128) .. Slot(159), Opt.none(VerifierError)),
|
|
|
|
# .. 3 ranges are empty
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(159), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(96) .. Slot(127), Opt.none(VerifierError)),
|
|
|
|
# .. 2 ranges are empty
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(159), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(96) .. Slot(127), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(64) .. Slot(95), Opt.none(VerifierError)),
|
|
|
|
# .. 1 range is empty
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(31) .. Slot(31), Opt.some(VerifierError.MissingParent)),
|
|
|
|
(Slot(128) .. Slot(159), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(96) .. Slot(127), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(64) .. Slot(95), Opt.some(VerifierError.Duplicate)),
|
|
|
|
(Slot(32) .. Slot(63), Opt.none(VerifierError)),
|
|
|
|
(Slot(0) .. Slot(31), Opt.none(VerifierError))
|
|
|
|
]
|
|
|
|
kind = SyncQueueKind.Backward
|
|
|
|
verifier = setupVerifier(kind, scenario)
|
|
|
|
sq = SyncQueue.init(SomeTPeer, kind, Slot(159), Slot(0),
|
|
|
|
32'u64, # 32 slots per request
|
|
|
|
3, # 3 concurrent requests
|
|
|
|
2, # 2 failures allowed
|
|
|
|
getStaticSlotCb(Slot(159)),
|
|
|
|
verifier.collector)
|
|
|
|
peer1 = SomeTPeer.init("1")
|
|
|
|
peer2 = SomeTPeer.init("2")
|
|
|
|
peer3 = SomeTPeer.init("3")
|
|
|
|
r11 = sq.pop(Slot(159), peer1)
|
|
|
|
r12 = sq.pop(Slot(159), peer2)
|
|
|
|
r13 = sq.pop(Slot(159), peer3)
|
|
|
|
d11 = createChain(r11.data)
|
|
|
|
d12 = createChain(r12.data)
|
|
|
|
d13 = createChain(r13.data)
|
|
|
|
f11 = sq.push(r11, d11, Opt.none(seq[BlobSidecars]))
|
|
|
|
f12 = sq.push(r12, d12, Opt.none(seq[BlobSidecars]))
|
|
|
|
f13 = sq.push(r13, d13, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f11
|
|
|
|
await noCancel f12
|
|
|
|
await noCancel f13
|
|
|
|
|
|
|
|
for i in 0 ..< 3:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2021-12-08 21:15:29 +00:00
|
|
|
|
|
|
|
let
|
2024-11-22 19:51:18 +00:00
|
|
|
r21 = sq.pop(Slot(159), peer1)
|
|
|
|
r22 = sq.pop(Slot(159), peer2)
|
|
|
|
r23 = sq.pop(Slot(159), peer3)
|
|
|
|
d21 = createChain(r21.data)
|
|
|
|
d22 = createChain(r22.data)
|
|
|
|
d23 = createChain(r23.data)
|
|
|
|
f21 = sq.push(r21, d21, Opt.none(seq[BlobSidecars]))
|
|
|
|
f22 = sq.push(r22, d22, Opt.none(seq[BlobSidecars]))
|
|
|
|
f23 = sq.push(r23, d23, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f21
|
|
|
|
await noCancel f22
|
|
|
|
await noCancel f23
|
|
|
|
|
|
|
|
for i in 0 ..< 2:
|
|
|
|
let
|
|
|
|
r31 = sq.pop(Slot(159), peer1)
|
|
|
|
r32 = sq.pop(Slot(159), peer2)
|
|
|
|
r33 = sq.pop(Slot(159), peer3)
|
|
|
|
d31 = createChain(r31.data)
|
|
|
|
d32 = createChain(r32.data)
|
|
|
|
d33 = createChain(r33.data)
|
|
|
|
f31 = sq.push(r31, d31, Opt.none(seq[BlobSidecars]))
|
|
|
|
f32 = sq.push(r32, d32, Opt.none(seq[BlobSidecars]))
|
|
|
|
f33 = sq.push(r33, d33, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f31
|
|
|
|
await noCancel f32
|
|
|
|
await noCancel f33
|
|
|
|
|
|
|
|
for i in 0 ..< 2:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r41 = sq.pop(Slot(159), peer1)
|
|
|
|
r42 = sq.pop(Slot(159), peer2)
|
|
|
|
r43 = sq.pop(Slot(159), peer3)
|
|
|
|
d41 = createChain(r41.data)
|
|
|
|
d42 = createChain(r42.data)
|
|
|
|
d43 = createChain(r43.data)
|
|
|
|
f41 = sq.push(r41, d41, Opt.none(seq[BlobSidecars]))
|
|
|
|
f42 = sq.push(r42, d42, Opt.none(seq[BlobSidecars]))
|
|
|
|
f43 = sq.push(r43, d43, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f41
|
|
|
|
await noCancel f42
|
|
|
|
await noCancel f43
|
|
|
|
|
|
|
|
for i in 0 ..< 3:
|
|
|
|
let
|
|
|
|
r51 = sq.pop(Slot(159), peer1)
|
|
|
|
r52 = sq.pop(Slot(159), peer2)
|
|
|
|
r53 = sq.pop(Slot(159), peer3)
|
|
|
|
d51 = createChain(r51.data)
|
|
|
|
d52 = createChain(r52.data)
|
|
|
|
d53 = createChain(r53.data)
|
|
|
|
f51 = sq.push(r51, d51, Opt.none(seq[BlobSidecars]))
|
|
|
|
f52 = sq.push(r52, d52, Opt.none(seq[BlobSidecars]))
|
|
|
|
f53 = sq.push(r53, d53, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f51
|
|
|
|
await noCancel f52
|
|
|
|
await noCancel f53
|
|
|
|
|
|
|
|
for i in 0 ..< 1:
|
|
|
|
let
|
|
|
|
re1 = sq.pop(Slot(159), peer1)
|
|
|
|
re2 = sq.pop(Slot(159), peer2)
|
|
|
|
re3 = sq.pop(Slot(159), peer3)
|
|
|
|
de1 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de2 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
de3 = default(seq[ref ForkedSignedBeaconBlock])
|
|
|
|
fe1 = sq.push(re1, de1, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe2 = sq.push(re2, de2, Opt.none(seq[BlobSidecars]))
|
|
|
|
fe3 = sq.push(re3, de3, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel fe1
|
|
|
|
await noCancel fe2
|
|
|
|
await noCancel fe3
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
r61 = sq.pop(Slot(159), peer1)
|
|
|
|
r62 = sq.pop(Slot(159), peer2)
|
|
|
|
r63 = sq.pop(Slot(159), peer3)
|
|
|
|
d61 = createChain(r61.data)
|
|
|
|
d62 = createChain(r62.data)
|
|
|
|
d63 = createChain(r63.data)
|
|
|
|
f61 = sq.push(r61, d61, Opt.none(seq[BlobSidecars]))
|
|
|
|
f62 = sq.push(r62, d62, Opt.none(seq[BlobSidecars]))
|
|
|
|
f63 = sq.push(r63, d63, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f61
|
|
|
|
await noCancel f62
|
|
|
|
await noCancel f63
|
|
|
|
|
|
|
|
for i in 0 ..< 5:
|
|
|
|
let
|
|
|
|
r71 = sq.pop(Slot(159), peer1)
|
|
|
|
r72 = sq.pop(Slot(159), peer2)
|
|
|
|
r73 = sq.pop(Slot(159), peer3)
|
|
|
|
d71 = createChain(r71.data)
|
|
|
|
d72 = createChain(r72.data)
|
|
|
|
d73 = createChain(r73.data)
|
|
|
|
f71 = sq.push(r71, d71, Opt.none(seq[BlobSidecars]))
|
|
|
|
f72 = sq.push(r72, d72, Opt.none(seq[BlobSidecars]))
|
|
|
|
f73 = sq.push(r73, d73, Opt.none(seq[BlobSidecars]))
|
|
|
|
|
|
|
|
await noCancel f71
|
|
|
|
await noCancel f72
|
|
|
|
await noCancel f73
|
|
|
|
|
|
|
|
await noCancel wait(verifier.verifier, 2.seconds)
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
test "[SyncQueue#Forward] getRewindPoint() test":
|
|
|
|
let aq = newAsyncQueue[BlockEntry]()
|
|
|
|
block:
|
|
|
|
let
|
|
|
|
queue = SyncQueue.init(SomeTPeer, SyncQueueKind.Forward,
|
|
|
|
Slot(0), Slot(0xFFFF_FFFF_FFFF_FFFFF'u64),
|
|
|
|
1'u64, 3, 2, getStaticSlotCb(Slot(0)),
|
|
|
|
collector(aq))
|
|
|
|
finalizedSlot = start_slot(Epoch(0'u64))
|
|
|
|
epochStartSlot = start_slot(Epoch(0'u64)) + 1'u64
|
|
|
|
finishSlot = start_slot(Epoch(2'u64))
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
for i in uint64(epochStartSlot) ..< uint64(finishSlot):
|
|
|
|
check queue.getRewindPoint(Slot(i), finalizedSlot) == finalizedSlot
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
block:
|
|
|
|
let
|
|
|
|
queue = SyncQueue.init(SomeTPeer, SyncQueueKind.Forward,
|
|
|
|
Slot(0), Slot(0xFFFF_FFFF_FFFF_FFFFF'u64),
|
|
|
|
1'u64, 3, 2, getStaticSlotCb(Slot(0)),
|
|
|
|
collector(aq))
|
|
|
|
finalizedSlot = start_slot(Epoch(1'u64))
|
|
|
|
epochStartSlot = start_slot(Epoch(1'u64)) + 1'u64
|
|
|
|
finishSlot = start_slot(Epoch(3'u64))
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
for i in uint64(epochStartSlot) ..< uint64(finishSlot) :
|
|
|
|
check queue.getRewindPoint(Slot(i), finalizedSlot) == finalizedSlot
|
2021-12-08 21:15:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
block:
|
|
|
|
let
|
|
|
|
queue = SyncQueue.init(SomeTPeer, SyncQueueKind.Forward,
|
|
|
|
Slot(0), Slot(0xFFFF_FFFF_FFFF_FFFFF'u64),
|
|
|
|
1'u64, 3, 2, getStaticSlotCb(Slot(0)),
|
|
|
|
collector(aq))
|
|
|
|
finalizedSlot = start_slot(Epoch(0'u64))
|
|
|
|
failSlot = Slot(0xFFFF_FFFF_FFFF_FFFFF'u64)
|
|
|
|
failEpoch = epoch(failSlot)
|
2020-08-10 07:15:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
var counter = 1'u64
|
|
|
|
for i in 0 ..< 64:
|
|
|
|
if counter >= failEpoch:
|
|
|
|
break
|
|
|
|
let rewindEpoch = failEpoch - counter
|
|
|
|
let rewindSlot = start_slot(rewindEpoch)
|
|
|
|
check queue.getRewindPoint(failSlot, finalizedSlot) == rewindSlot
|
|
|
|
counter = counter shl 1
|
2020-05-28 05:02:28 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
block:
|
|
|
|
let
|
|
|
|
queue = SyncQueue.init(SomeTPeer, SyncQueueKind.Forward,
|
|
|
|
Slot(0), Slot(0xFFFF_FFFF_FFFF_FFFFF'u64),
|
|
|
|
1'u64, 3, 2, getStaticSlotCb(Slot(0)),
|
|
|
|
collector(aq))
|
|
|
|
let
|
|
|
|
finalizedSlot = start_slot(Epoch(1'u64))
|
|
|
|
failSlot = Slot(0xFFFF_FFFF_FFFF_FFFFF'u64)
|
|
|
|
failEpoch = epoch(failSlot)
|
2020-05-28 05:02:28 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
var counter = 1'u64
|
|
|
|
for i in 0 ..< 64:
|
|
|
|
if counter >= failEpoch:
|
|
|
|
break
|
|
|
|
let
|
|
|
|
rewindEpoch = failEpoch - counter
|
|
|
|
rewindSlot = start_slot(rewindEpoch)
|
|
|
|
check queue.getRewindPoint(failSlot, finalizedSlot) == rewindSlot
|
|
|
|
counter = counter shl 1
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
test "[SyncQueue#Backward] getRewindPoint() test":
|
|
|
|
let aq = newAsyncQueue[BlockEntry]()
|
|
|
|
block:
|
|
|
|
let
|
|
|
|
getSafeSlot = getStaticSlotCb(Slot(1024))
|
|
|
|
queue = SyncQueue.init(SomeTPeer, SyncQueueKind.Backward,
|
|
|
|
Slot(1024), Slot(0),
|
|
|
|
1'u64, 3, 2, getSafeSlot, collector(aq))
|
|
|
|
safeSlot = getSafeSlot()
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
for i in countdown(1023, 0):
|
|
|
|
check queue.getRewindPoint(Slot(i), safeSlot) == safeSlot
|
2020-05-19 12:08:50 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
test "[SyncQueue] hasEndGap() test":
|
|
|
|
let
|
|
|
|
chain1 = createChain(Slot(1) .. Slot(1))
|
|
|
|
chain2 = newSeq[ref ForkedSignedBeaconBlock]()
|
2020-05-19 12:08:50 +00:00
|
|
|
|
|
|
|
for counter in countdown(32'u64, 2'u64):
|
2024-11-22 19:51:18 +00:00
|
|
|
let
|
|
|
|
srange = SyncRange.init(Slot(1), counter)
|
|
|
|
req = SyncRequest[SomeTPeer](data: srange)
|
|
|
|
check req.hasEndGap(chain1) == true
|
2020-06-03 08:46:29 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
let req = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(1), 1'u64))
|
2020-06-03 08:46:29 +00:00
|
|
|
check:
|
2024-11-22 19:51:18 +00:00
|
|
|
req.hasEndGap(chain1) == false
|
|
|
|
req.hasEndGap(chain2) == true
|
2020-06-03 08:46:29 +00:00
|
|
|
|
|
|
|
test "[SyncQueue] checkResponse() test":
|
2024-10-30 05:38:53 +00:00
|
|
|
let
|
2024-11-22 19:51:18 +00:00
|
|
|
r1 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 1'u64))
|
|
|
|
r2 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 2'u64))
|
|
|
|
r3 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 3'u64))
|
2024-10-30 05:38:53 +00:00
|
|
|
|
2024-11-19 05:35:09 +00:00
|
|
|
check:
|
|
|
|
checkResponse(r1, [Slot(11)]).isOk() == true
|
|
|
|
checkResponse(r1, @[]).isOk() == true
|
|
|
|
checkResponse(r1, @[Slot(11), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r1, [Slot(10)]).isOk() == false
|
|
|
|
checkResponse(r1, [Slot(12)]).isOk() == false
|
|
|
|
|
|
|
|
checkResponse(r2, [Slot(11)]).isOk() == true
|
|
|
|
checkResponse(r2, [Slot(12)]).isOk() == true
|
|
|
|
checkResponse(r2, @[]).isOk() == true
|
|
|
|
checkResponse(r2, [Slot(11), Slot(12)]).isOk() == true
|
|
|
|
checkResponse(r2, [Slot(12)]).isOk() == true
|
|
|
|
checkResponse(r2, [Slot(11), Slot(12), Slot(13)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(10), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(10)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(12), Slot(13)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(13)]).isOk() == false
|
|
|
|
|
|
|
|
checkResponse(r2, [Slot(11), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r2, [Slot(12), Slot(12)]).isOk() == false
|
|
|
|
|
|
|
|
checkResponse(r3, @[Slot(11)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(12)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(13)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(12)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(13)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(13)]).isOk() == true
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(13), Slot(12)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(13), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(13), Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(13), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(13), Slot(12)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(11)]).isOk() == false
|
|
|
|
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(11), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(12), Slot(12)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(13), Slot(13)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(13), Slot(13)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(12), Slot(12)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(13), Slot(13), Slot(13)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(11), Slot(11)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(12), Slot(12)]).isOk() == false
|
|
|
|
checkResponse(r3, @[Slot(13), Slot(13)]).isOk() == false
|
|
|
|
|
|
|
|
test "[SyncQueue] checkBlobsResponse() test":
|
|
|
|
let
|
2024-11-22 19:51:18 +00:00
|
|
|
r1 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 1'u64))
|
|
|
|
r2 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 2'u64))
|
|
|
|
r3 = SyncRequest[SomeTPeer](data: SyncRange.init(Slot(11), 3'u64))
|
2024-11-19 05:35:09 +00:00
|
|
|
|
|
|
|
d1 = Slot(11).repeat(MAX_BLOBS_PER_BLOCK)
|
|
|
|
d2 = Slot(12).repeat(MAX_BLOBS_PER_BLOCK)
|
|
|
|
d3 = Slot(13).repeat(MAX_BLOBS_PER_BLOCK)
|
2020-06-03 08:46:29 +00:00
|
|
|
|
|
|
|
check:
|
2024-11-19 05:35:09 +00:00
|
|
|
checkBlobsResponse(r1, [Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r1, @[]).isOk() == true
|
|
|
|
checkBlobsResponse(r1, [Slot(11), Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r1, [Slot(11), Slot(11), Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r1, d1).isOk() == true
|
|
|
|
checkBlobsResponse(r1, d1 & @[Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r1, [Slot(10)]).isOk() == false
|
|
|
|
checkBlobsResponse(r1, [Slot(12)]).isOk() == false
|
|
|
|
|
|
|
|
checkBlobsResponse(r2, [Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, [Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, @[]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, [Slot(11), Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, [Slot(11), Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, [Slot(12), Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r2, d1).isOk() == true
|
|
|
|
checkBlobsResponse(r2, d2).isOk() == true
|
|
|
|
checkBlobsResponse(r2, d1 & d2).isOk() == true
|
|
|
|
checkBlobsResponse(r2, [Slot(11), Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, [Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d1 & @[Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, @[Slot(11)] & d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d1 & d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d2 & d1).isOk() == false
|
|
|
|
|
|
|
|
checkBlobsResponse(r3, [Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(13)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, @[]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(11), Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(11), Slot(11)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(12), Slot(12)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(11), Slot(13)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(12), Slot(13)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(13), Slot(13)]).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d1).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d2).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d3).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d1 & d2).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d1 & d3).isOk() == true
|
|
|
|
checkBlobsResponse(r3, d2 & d3).isOk() == true
|
|
|
|
checkBlobsResponse(r3, [Slot(11), Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, [Slot(11), Slot(13), Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, [Slot(12), Slot(13), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, [Slot(12), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, [Slot(13), Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, [Slot(13), Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, d1 & @[Slot(11)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, d3 & @[Slot(13)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, @[Slot(11)] & d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, @[Slot(12)] & d3 & @[Slot(13)]).isOk() == false
|
|
|
|
checkBlobsResponse(r3, @[Slot(11)] & d3 & @[Slot(13)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d1 & d2 & @[Slot(12)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d1 & d3 & @[Slot(13)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d2 & d3 & @[Slot(13)]).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d2 & d1).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d3 & d2).isOk() == false
|
|
|
|
checkBlobsResponse(r2, d3 & d1).isOk() == false
|
2024-10-30 05:38:53 +00:00
|
|
|
|
2023-03-07 20:19:17 +00:00
|
|
|
test "[SyncManager] groupBlobs() test":
|
2024-10-30 05:38:53 +00:00
|
|
|
var
|
2024-11-22 19:51:18 +00:00
|
|
|
blocks = createChain(Slot(10) .. Slot(15))
|
2024-10-30 05:38:53 +00:00
|
|
|
blobs = createBlobs(blocks, @[Slot(11), Slot(11), Slot(12), Slot(14)])
|
2023-05-06 08:58:50 +00:00
|
|
|
|
2024-10-30 05:38:53 +00:00
|
|
|
let groupedRes = groupBlobs(blocks, blobs)
|
2023-03-07 20:19:17 +00:00
|
|
|
|
2024-11-22 19:51:18 +00:00
|
|
|
check groupedRes.isOk()
|
2023-03-07 20:19:17 +00:00
|
|
|
|
|
|
|
let grouped = groupedRes.get()
|
|
|
|
|
|
|
|
check:
|
|
|
|
len(grouped) == 6
|
|
|
|
# slot 10
|
|
|
|
len(grouped[0]) == 0
|
|
|
|
# slot 11
|
|
|
|
len(grouped[1]) == 2
|
2023-11-06 06:48:43 +00:00
|
|
|
grouped[1][0].signed_block_header.message.slot == Slot(11)
|
|
|
|
grouped[1][1].signed_block_header.message.slot == Slot(11)
|
2023-03-07 20:19:17 +00:00
|
|
|
# slot 12
|
|
|
|
len(grouped[2]) == 1
|
2023-11-06 06:48:43 +00:00
|
|
|
grouped[2][0].signed_block_header.message.slot == Slot(12)
|
2023-03-07 20:19:17 +00:00
|
|
|
# slot 13
|
|
|
|
len(grouped[3]) == 0
|
|
|
|
# slot 14
|
|
|
|
len(grouped[4]) == 1
|
2023-11-06 06:48:43 +00:00
|
|
|
grouped[4][0].signed_block_header.message.slot == Slot(14)
|
2023-03-07 20:19:17 +00:00
|
|
|
# slot 15
|
|
|
|
len(grouped[5]) == 0
|
|
|
|
|
2023-05-06 08:58:50 +00:00
|
|
|
# Add block with a gap from previous block.
|
2024-01-18 14:45:10 +00:00
|
|
|
let block17 = newClone ForkedSignedBeaconBlock(kind: ConsensusFork.Deneb)
|
|
|
|
block17[].denebData.message.slot = Slot(17)
|
2023-05-06 08:58:50 +00:00
|
|
|
blocks.add(block17)
|
2024-10-30 05:38:53 +00:00
|
|
|
let groupedRes2 = groupBlobs(blocks, blobs)
|
2023-05-06 08:58:50 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
groupedRes2.isOk()
|
|
|
|
let grouped2 = groupedRes2.get()
|
|
|
|
check:
|
|
|
|
len(grouped2) == 7
|
|
|
|
len(grouped2[6]) == 0 # slot 17
|
|
|
|
|
|
|
|
let blob18 = new (ref BlobSidecar)
|
2023-11-06 06:48:43 +00:00
|
|
|
blob18[].signed_block_header.message.slot = Slot(18)
|
2023-05-06 08:58:50 +00:00
|
|
|
blobs.add(blob18)
|
2024-10-30 05:38:53 +00:00
|
|
|
let groupedRes3 = groupBlobs(blocks, blobs)
|
2023-05-06 08:58:50 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
groupedRes3.isErr()
|