2022-03-17 22:26:56 +00:00
|
|
|
# beacon_chain
|
2023-01-12 17:11:38 +00:00
|
|
|
# Copyright (c) 2022-2023 Status Research & Development GmbH
|
2022-03-17 22:26: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.
|
|
|
|
|
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
|
|
|
# Status libraries
|
|
|
|
chronos, eth/keys,
|
|
|
|
# Beacon chain internals
|
|
|
|
../beacon_chain/consensus_object_pools/
|
|
|
|
[block_clearance, block_quarantine, blockchain_dag],
|
|
|
|
../beacon_chain/gossip_processing/light_client_processor,
|
|
|
|
../beacon_chain/spec/[beacon_time, light_client_sync, state_transition],
|
|
|
|
# Test utilities
|
|
|
|
./testutil, ./testdbutil
|
|
|
|
|
|
|
|
suite "Light client processor" & preset():
|
|
|
|
let
|
|
|
|
cfg = block:
|
|
|
|
var res = defaultRuntimeConfig
|
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH + 1
|
|
|
|
res
|
|
|
|
|
|
|
|
const numValidators = SLOTS_PER_EPOCH
|
|
|
|
let
|
|
|
|
validatorMonitor = newClone(ValidatorMonitor.init())
|
|
|
|
dag = ChainDAGRef.init(
|
|
|
|
cfg, makeTestDB(numValidators), validatorMonitor, {},
|
2022-06-28 20:52:29 +00:00
|
|
|
lcDataConfig = LightClientDataConfig(
|
|
|
|
serve: true,
|
|
|
|
importMode: LightClientDataImportMode.OnlyNew))
|
2022-03-17 22:26:56 +00:00
|
|
|
quarantine = newClone(Quarantine.init())
|
2022-04-08 16:22:49 +00:00
|
|
|
taskpool = Taskpool.new()
|
2022-03-17 22:26:56 +00:00
|
|
|
var verifier = BatchVerifier(rng: keys.newRng(), taskpool: taskpool)
|
|
|
|
|
|
|
|
var cache: StateCache
|
|
|
|
proc addBlocks(blocks: uint64, syncCommitteeRatio: float) =
|
|
|
|
for blck in makeTestBlocks(dag.headState, cache, blocks.int,
|
|
|
|
attested = true, syncCommitteeRatio, cfg):
|
|
|
|
let added =
|
|
|
|
case blck.kind
|
|
|
|
of BeaconBlockFork.Phase0:
|
|
|
|
const nilCallback = OnPhase0BlockAdded(nil)
|
|
|
|
dag.addHeadBlock(verifier, blck.phase0Data, nilCallback)
|
|
|
|
of BeaconBlockFork.Altair:
|
|
|
|
const nilCallback = OnAltairBlockAdded(nil)
|
|
|
|
dag.addHeadBlock(verifier, blck.altairData, nilCallback)
|
|
|
|
of BeaconBlockFork.Bellatrix:
|
|
|
|
const nilCallback = OnBellatrixBlockAdded(nil)
|
|
|
|
dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback)
|
2022-11-02 16:23:30 +00:00
|
|
|
of BeaconBlockFork.Capella:
|
2022-12-04 07:42:03 +00:00
|
|
|
const nilCallback = OnCapellaBlockAdded(nil)
|
|
|
|
dag.addHeadBlock(verifier, blck.capellaData, nilCallback)
|
2022-12-05 16:29:09 +00:00
|
|
|
of BeaconBlockFork.EIP4844:
|
2022-12-08 16:21:53 +00:00
|
|
|
const nilCallback = OnEIP4844BlockAdded(nil)
|
|
|
|
dag.addHeadBlock(verifier, blck.eip4844Data, nilCallback)
|
2022-03-17 22:26:56 +00:00
|
|
|
doAssert added.isOk()
|
|
|
|
dag.updateHead(added[], quarantine[])
|
|
|
|
|
2022-05-23 12:02:54 +00:00
|
|
|
addBlocks(SLOTS_PER_EPOCH, 0.82)
|
2022-03-17 22:26:56 +00:00
|
|
|
let
|
2022-04-08 16:22:49 +00:00
|
|
|
genesis_validators_root = dag.genesis_validators_root
|
2022-03-17 22:26:56 +00:00
|
|
|
trustedBlockRoot = dag.head.root
|
2022-05-31 10:45:37 +00:00
|
|
|
proc getTrustedBlockRoot(): Option[Eth2Digest] =
|
|
|
|
some trustedBlockRoot
|
2022-03-17 22:26:56 +00:00
|
|
|
|
|
|
|
const
|
|
|
|
lowPeriod = 0.SyncCommitteePeriod
|
|
|
|
lastPeriodWithSupermajority = 3.SyncCommitteePeriod
|
|
|
|
highPeriod = 5.SyncCommitteePeriod
|
|
|
|
for period in lowPeriod .. highPeriod:
|
|
|
|
const numFilledEpochsPerPeriod = 3
|
|
|
|
let slot = ((period + 1).start_epoch - numFilledEpochsPerPeriod).start_slot
|
|
|
|
var info: ForkedEpochInfo
|
|
|
|
doAssert process_slots(cfg, dag.headState, slot,
|
|
|
|
cache, info, flags = {}).isOk()
|
|
|
|
let syncCommitteeRatio =
|
|
|
|
if period > lastPeriodWithSupermajority:
|
2022-05-23 12:02:54 +00:00
|
|
|
0.62
|
2022-03-17 22:26:56 +00:00
|
|
|
else:
|
2022-05-23 12:02:54 +00:00
|
|
|
0.82
|
2022-03-17 22:26:56 +00:00
|
|
|
addBlocks(numFilledEpochsPerPeriod * SLOTS_PER_EPOCH, syncCommitteeRatio)
|
|
|
|
|
2022-07-21 09:16:10 +00:00
|
|
|
for finalizationMode in LightClientFinalizationMode:
|
|
|
|
let testNameSuffix = " (" & $finalizationMode & ")" & preset()
|
|
|
|
|
|
|
|
setup:
|
|
|
|
var time = chronos.seconds(0)
|
|
|
|
proc getBeaconTime(): BeaconTime =
|
|
|
|
BeaconTime(ns_since_genesis: time.nanoseconds)
|
|
|
|
func setTimeToSlot(slot: Slot) =
|
|
|
|
time = chronos.seconds((slot * SECONDS_PER_SLOT).int64)
|
|
|
|
|
|
|
|
var numOnStoreInitializedCalls = 0
|
|
|
|
func onStoreInitialized() = inc numOnStoreInitializedCalls
|
|
|
|
|
2023-01-14 21:19:50 +00:00
|
|
|
const storeDataFork = LightClientProcessor.storeDataFork
|
|
|
|
let store = (ref Option[storeDataFork.LightClientStore])()
|
2022-07-21 09:16:10 +00:00
|
|
|
var
|
|
|
|
processor = LightClientProcessor.new(
|
|
|
|
false, "", "", cfg, genesis_validators_root, finalizationMode,
|
|
|
|
store, getBeaconTime, getTrustedBlockRoot, onStoreInitialized)
|
2022-11-10 17:40:27 +00:00
|
|
|
res: Result[bool, VerifierError]
|
2022-07-21 09:16:10 +00:00
|
|
|
|
|
|
|
test "Sync" & testNameSuffix:
|
|
|
|
let bootstrap = dag.getLightClientBootstrap(trustedBlockRoot)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
bootstrap.kind > LightClientDataFork.None
|
|
|
|
bootstrap.kind <= storeDataFork
|
|
|
|
let upgradedBootstrap = bootstrap.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyBootstrap: untyped = upgradedBootstrap.forky(storeDataFork)
|
2023-01-13 15:46:35 +00:00
|
|
|
setTimeToSlot(forkyBootstrap.header.beacon.slot)
|
2022-03-17 22:26:56 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), bootstrap)
|
2022-03-17 22:26:56 +00:00
|
|
|
check:
|
|
|
|
res.isOk
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 1
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].isSome
|
2022-03-17 22:26:56 +00:00
|
|
|
|
2022-07-21 09:16:10 +00:00
|
|
|
# Reduce stack size by making this a `proc`
|
|
|
|
proc applyPeriodWithSupermajority(period: SyncCommitteePeriod) =
|
|
|
|
let update = dag.getLightClientUpdateForPeriod(period)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
update.kind > LightClientDataFork.None
|
|
|
|
update.kind <= storeDataFork
|
|
|
|
let upgradedUpdate = update.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyUpdate: untyped = upgradedUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyUpdate.signature_slot)
|
2022-03-17 22:26:56 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), update)
|
2022-03-17 22:26:56 +00:00
|
|
|
check:
|
2022-05-23 12:02:54 +00:00
|
|
|
res.isOk
|
2022-03-17 22:26:56 +00:00
|
|
|
store[].isSome
|
2023-01-13 15:46:35 +00:00
|
|
|
if forkyUpdate.finalized_header.beacon.slot >
|
|
|
|
forkyBootstrap.header.beacon.slot:
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.finalized_header == forkyUpdate.finalized_header
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.finalized_header == forkyBootstrap.header
|
|
|
|
store[].get.optimistic_header == forkyUpdate.attested_header
|
2022-03-17 22:26:56 +00:00
|
|
|
|
2022-07-21 09:16:10 +00:00
|
|
|
for period in lowPeriod .. lastPeriodWithSupermajority:
|
|
|
|
applyPeriodWithSupermajority(period)
|
|
|
|
|
|
|
|
# Reduce stack size by making this a `proc`
|
|
|
|
proc applyPeriodWithoutSupermajority(period: SyncCommitteePeriod) =
|
|
|
|
let update = dag.getLightClientUpdateForPeriod(period)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
update.kind > LightClientDataFork.None
|
|
|
|
update.kind <= storeDataFork
|
|
|
|
let upgradedUpdate = update.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyUpdate: untyped = upgradedUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyUpdate.signature_slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
|
|
|
|
for i in 0 ..< 2:
|
2022-05-23 12:02:54 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), update)
|
2022-07-21 09:16:10 +00:00
|
|
|
if finalizationMode == LightClientFinalizationMode.Optimistic or
|
|
|
|
period == lastPeriodWithSupermajority + 1:
|
|
|
|
if finalizationMode == LightClientFinalizationMode.Optimistic or
|
|
|
|
i == 0:
|
|
|
|
check:
|
|
|
|
res.isOk
|
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
not store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
|
|
|
|
proc applyDuplicate() = # Reduce stack size by making this a `proc`
|
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), update)
|
2022-07-21 09:16:10 +00:00
|
|
|
if finalizationMode == LightClientFinalizationMode.Optimistic or
|
|
|
|
period == lastPeriodWithSupermajority + 1:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
not store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
|
2022-05-23 12:02:54 +00:00
|
|
|
applyDuplicate()
|
2022-07-21 09:16:10 +00:00
|
|
|
time += chronos.minutes(15)
|
|
|
|
for _ in 0 ..< 150:
|
|
|
|
applyDuplicate()
|
|
|
|
time += chronos.seconds(5)
|
|
|
|
time += chronos.minutes(15)
|
2022-03-17 22:26:56 +00:00
|
|
|
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), update)
|
2022-07-21 09:16:10 +00:00
|
|
|
if finalizationMode == LightClientFinalizationMode.Optimistic:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isNone
|
2023-01-12 17:11:38 +00:00
|
|
|
if store[].get.finalized_header == forkyUpdate.attested_header:
|
2022-07-21 09:16:10 +00:00
|
|
|
break
|
2023-01-12 17:11:38 +00:00
|
|
|
check store[].get.finalized_header == forkyUpdate.finalized_header
|
2022-07-21 09:16:10 +00:00
|
|
|
elif period == lastPeriodWithSupermajority + 1:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].isSome
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
not store[].get.best_valid_update.get.matches(forkyUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
if finalizationMode == LightClientFinalizationMode.Optimistic:
|
2023-01-12 17:11:38 +00:00
|
|
|
check store[].get.finalized_header == forkyUpdate.attested_header
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
2023-01-12 17:11:38 +00:00
|
|
|
check store[].get.finalized_header != forkyUpdate.attested_header
|
2022-07-21 09:16:10 +00:00
|
|
|
|
|
|
|
for period in lastPeriodWithSupermajority + 1 .. highPeriod:
|
|
|
|
applyPeriodWithoutSupermajority(period)
|
|
|
|
|
|
|
|
let
|
|
|
|
previousFinalized = store[].get.finalized_header
|
|
|
|
finalityUpdate = dag.getLightClientFinalityUpdate()
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
finalityUpdate.kind > LightClientDataFork.None
|
|
|
|
finalityUpdate.kind <= storeDataFork
|
|
|
|
let upgradedFinalityUpdate =
|
|
|
|
finalityUpdate.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyFinalityUpdate: untyped =
|
|
|
|
upgradedFinalityUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyFinalityUpdate.signature_slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), finalityUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
if res.isOk:
|
2022-05-23 12:02:54 +00:00
|
|
|
check:
|
2022-07-21 09:16:10 +00:00
|
|
|
finalizationMode == LightClientFinalizationMode.Optimistic
|
2022-05-23 12:02:54 +00:00
|
|
|
store[].isSome
|
2022-07-21 09:16:10 +00:00
|
|
|
store[].get.finalized_header == previousFinalized
|
|
|
|
store[].get.best_valid_update.isSome
|
2023-01-12 17:11:38 +00:00
|
|
|
store[].get.best_valid_update.get.matches(forkyFinalityUpdate)
|
|
|
|
store[].get.optimistic_header == forkyFinalityUpdate.attested_header
|
2022-07-21 09:16:10 +00:00
|
|
|
elif finalizationMode == LightClientFinalizationMode.Optimistic:
|
2022-11-10 17:40:27 +00:00
|
|
|
check res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
else:
|
2022-11-10 17:40:27 +00:00
|
|
|
check res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
check numOnStoreInitializedCalls == 1
|
|
|
|
|
|
|
|
test "Invalid bootstrap" & testNameSuffix:
|
|
|
|
var bootstrap = dag.getLightClientBootstrap(trustedBlockRoot)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
bootstrap.kind > LightClientDataFork.None
|
|
|
|
bootstrap.kind <= storeDataFork
|
|
|
|
withForkyBootstrap(bootstrap):
|
2023-01-14 21:19:50 +00:00
|
|
|
when lcDataFork > LightClientDataFork.None:
|
2023-01-13 15:46:35 +00:00
|
|
|
forkyBootstrap.header.beacon.slot.inc()
|
2023-01-12 17:11:38 +00:00
|
|
|
let upgradedBootstrap = bootstrap.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyBootstrap: untyped = upgradedBootstrap.forky(storeDataFork)
|
2023-01-13 15:46:35 +00:00
|
|
|
setTimeToSlot(forkyBootstrap.header.beacon.slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), bootstrap)
|
2022-07-21 09:16:10 +00:00
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Invalid
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 0
|
|
|
|
|
|
|
|
test "Duplicate bootstrap" & testNameSuffix:
|
|
|
|
let bootstrap = dag.getLightClientBootstrap(trustedBlockRoot)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
bootstrap.kind > LightClientDataFork.None
|
|
|
|
bootstrap.kind <= storeDataFork
|
|
|
|
let upgradedBootstrap = bootstrap.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyBootstrap: untyped = upgradedBootstrap.forky(storeDataFork)
|
2023-01-13 15:46:35 +00:00
|
|
|
setTimeToSlot(forkyBootstrap.header.beacon.slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), bootstrap)
|
2022-07-21 09:16:10 +00:00
|
|
|
check:
|
|
|
|
res.isOk
|
|
|
|
numOnStoreInitializedCalls == 1
|
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), bootstrap)
|
2022-07-21 09:16:10 +00:00
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.Duplicate
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 1
|
|
|
|
|
|
|
|
test "Missing bootstrap (update)" & testNameSuffix:
|
|
|
|
let update = dag.getLightClientUpdateForPeriod(lowPeriod)
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
update.kind > LightClientDataFork.None
|
|
|
|
update.kind <= storeDataFork
|
|
|
|
let upgradedUpdate = update.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyUpdate: untyped = upgradedUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyUpdate.signature_slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), update)
|
2022-07-21 09:16:10 +00:00
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 0
|
|
|
|
|
|
|
|
test "Missing bootstrap (finality update)" & testNameSuffix:
|
|
|
|
let finalityUpdate = dag.getLightClientFinalityUpdate()
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
finalityUpdate.kind > LightClientDataFork.None
|
|
|
|
finalityUpdate.kind <= storeDataFork
|
|
|
|
let upgradedFinalityUpdate =
|
|
|
|
finalityUpdate.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyFinalityUpdate: untyped =
|
|
|
|
upgradedFinalityUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyFinalityUpdate.signature_slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), finalityUpdate)
|
2022-07-21 09:16:10 +00:00
|
|
|
check:
|
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 0
|
|
|
|
|
|
|
|
test "Missing bootstrap (optimistic update)" & testNameSuffix:
|
|
|
|
let optimisticUpdate = dag.getLightClientOptimisticUpdate()
|
2023-01-12 17:11:38 +00:00
|
|
|
check:
|
|
|
|
optimisticUpdate.kind > LightClientDataFork.None
|
|
|
|
optimisticUpdate.kind <= storeDataFork
|
|
|
|
let upgradedOptimisticUpdate =
|
|
|
|
optimisticUpdate.migratingToDataFork(storeDataFork)
|
|
|
|
template forkyOptimisticUpdate: untyped =
|
|
|
|
upgradedOptimisticUpdate.forky(storeDataFork)
|
|
|
|
setTimeToSlot(forkyOptimisticUpdate.signature_slot)
|
2022-07-21 09:16:10 +00:00
|
|
|
res = processor[].storeObject(
|
2023-01-12 17:11:38 +00:00
|
|
|
MsgSource.gossip, getBeaconTime(), optimisticUpdate)
|
2022-03-17 22:26:56 +00:00
|
|
|
check:
|
2022-07-21 09:16:10 +00:00
|
|
|
res.isErr
|
2022-11-10 17:40:27 +00:00
|
|
|
res.error == VerifierError.MissingParent
|
2022-07-21 09:16:10 +00:00
|
|
|
numOnStoreInitializedCalls == 0
|