126 lines
4.0 KiB
Nim
126 lines
4.0 KiB
Nim
|
# Nimbus
|
||
|
# Copyright (c) 2023 Status Research & Development GmbH
|
||
|
# 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.
|
||
|
|
||
|
import
|
||
|
unittest2,
|
||
|
./setup_env,
|
||
|
../../nimbus/sync/beacon/skeleton_main,
|
||
|
../../nimbus/sync/beacon/skeleton_utils
|
||
|
|
||
|
# Tests that a running skeleton sync can be extended with properly linked up
|
||
|
# headers but not with side chains.
|
||
|
|
||
|
type
|
||
|
TestCase = object
|
||
|
name : string
|
||
|
blocks : seq[BlockHeader] # Database content (besides the genesis)
|
||
|
head : BlockHeader # New head header to announce to reorg to
|
||
|
extend : BlockHeader # New head header to announce to extend with
|
||
|
force : bool # To force set head not just to extend
|
||
|
newState: seq[Subchain] # Expected sync state after the reorg
|
||
|
err : Opt[SkeletonStatus] # Whether extension succeeds or not
|
||
|
|
||
|
let testCases = [
|
||
|
# Initialize a sync and try to extend it with a subsequent block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a subsequent block",
|
||
|
head: block49,
|
||
|
extend: block50,
|
||
|
force: true,
|
||
|
newState: @[subchain(50, 49)],
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with the existing head block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with the existing head block",
|
||
|
blocks: @[block49],
|
||
|
head: block49,
|
||
|
extend: block49,
|
||
|
newState: @[subchain(49, 49)],
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with a sibling block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a sibling block",
|
||
|
head: block49,
|
||
|
extend: block49B,
|
||
|
newState: @[subchain(49, 49)],
|
||
|
err: Opt.some ReorgDenied,
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with a number-wise sequential
|
||
|
# header, but a hash wise non-linking one.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a number-wise sequential alternate block",
|
||
|
head: block49B,
|
||
|
extend: block50,
|
||
|
newState: @[subchain(49, 49)],
|
||
|
err: Opt.some ReorgDenied,
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with a non-linking future block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a non-linking future block",
|
||
|
head: block49,
|
||
|
extend: block51,
|
||
|
newState: @[subchain(49, 49)],
|
||
|
err: Opt.some ReorgDenied,
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with a past canonical block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a past canonical block",
|
||
|
head: block50,
|
||
|
extend: block49,
|
||
|
newState: @[subchain(50, 50)],
|
||
|
err: Opt.some ReorgDenied,
|
||
|
),
|
||
|
# Initialize a sync and try to extend it with a past sidechain block.
|
||
|
TestCase(
|
||
|
name: "Initialize a sync and try to extend it with a past sidechain block",
|
||
|
head: block50,
|
||
|
extend: block49B,
|
||
|
newState: @[subchain(50, 50)],
|
||
|
err: Opt.some ReorgDenied,
|
||
|
),
|
||
|
]
|
||
|
|
||
|
proc test2*() =
|
||
|
suite "Tests that a running skeleton sync can be extended":
|
||
|
for z in testCases:
|
||
|
test z.name:
|
||
|
let env = setupEnv()
|
||
|
let skel = SkeletonRef.new(env.chain)
|
||
|
let res = skel.open()
|
||
|
check res.isOk
|
||
|
if res.isErr:
|
||
|
debugEcho res.error
|
||
|
check false
|
||
|
break
|
||
|
|
||
|
let x = skel.initSync(z.head).valueOr:
|
||
|
debugEcho "initSync: ", error
|
||
|
check false
|
||
|
break
|
||
|
|
||
|
check x.status.card == 0
|
||
|
check x.reorg == true
|
||
|
|
||
|
let r = skel.setHead(z.extend, z.force, false, true).valueOr:
|
||
|
debugEcho "setHead: ", error
|
||
|
check false
|
||
|
break
|
||
|
|
||
|
if z.err.isSome:
|
||
|
check r.status.card == 1
|
||
|
check z.err.get in r.status
|
||
|
else:
|
||
|
check r.status.card == 0
|
||
|
|
||
|
check skel.len == z.newState.len
|
||
|
for i, sc in skel:
|
||
|
check sc.head == z.newState[i].head
|
||
|
check sc.tail == z.newState[i].tail
|