nimbus-eth1/fluffy/tests/beacon_network_tests/test_beacon_light_client.nim

95 lines
3.6 KiB
Nim

# Nimbus - Portal Network
# Copyright (c) 2022-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.
{.push raises: [].}
import
testutils/unittests, chronos,
eth/p2p/discoveryv5/protocol as discv5_protocol,
beacon_chain/spec/forks,
beacon_chain/spec/datatypes/altair,
beacon_chain/spec/helpers,
../../network/wire/[portal_protocol, portal_stream],
../../network/beacon/[beacon_init_loader, beacon_light_client],
"."/[light_client_test_data, beacon_test_helpers]
procSuite "Portal Beacon Light Client":
let rng = newRng()
proc headerCallback(
q: AsyncQueue[ForkedLightClientHeader]): LightClientHeaderCallback =
return (
proc (lightClient: LightClient, finalizedHeader: ForkedLightClientHeader)
{.gcsafe, raises: [].} =
try:
q.putNoWait(finalizedHeader)
except AsyncQueueFullError as exc:
raiseAssert(exc.msg)
)
asyncTest "Start and retrieve bootstrap":
let
finalizedHeaders = newAsyncQueue[ForkedLightClientHeader]()
optimisticHeaders = newAsyncQueue[ForkedLightClientHeader]()
# Test data is retrieved from mainnet
networkData = loadNetworkData("mainnet")
lcNode1 = newLCNode(rng, 20302, networkData)
lcNode2 = newLCNode(rng, 20303, networkData)
altairData = SSZ.decode(bootstrapBytes, altair.LightClientBootstrap)
bootstrap = ForkedLightClientBootstrap(
kind: LightClientDataFork.Altair, altairData: altairData)
bootstrapHeaderHash = hash_tree_root(altairData.header)
check:
lcNode1.portalProtocol().addNode(lcNode2.localNode()) == Added
lcNode2.portalProtocol().addNode(lcNode1.localNode()) == Added
(await lcNode1.portalProtocol().ping(lcNode2.localNode())).isOk()
(await lcNode2.portalProtocol().ping(lcNode1.localNode())).isOk()
let
bootstrapKey = LightClientBootstrapKey(
blockHash: bootstrapHeaderHash
)
bootstrapContentKey = ContentKey(
contentType: lightClientBootstrap,
lightClientBootstrapKey: bootstrapKey
)
bootstrapContentKeyEncoded = encode(bootstrapContentKey)
bootstrapContentId = toContentId(bootstrapContentKeyEncoded)
lcNode2.portalProtocol().storeContent(
bootstrapContentKeyEncoded,
bootstrapContentId,
encodeForkedLightClientObject(bootstrap, networkData.forks.altair)
)
let lc = LightClient.new(
lcNode1.beaconNetwork, rng, networkData,
LightClientFinalizationMode.Optimistic)
lc.onFinalizedHeader = headerCallback(finalizedHeaders)
lc.onOptimisticHeader = headerCallback(optimisticHeaders)
lc.trustedBlockRoot = some bootstrapHeaderHash
# When running start the beacon light client will first try to retrieve the
# bootstrap for given trustedBlockRoot
lc.start()
# Wait until the beacon light client retrieves the bootstrap. Upon receiving
# the bootstrap both onFinalizedHeader and onOptimisticHeader callbacks
# will be called.
let
receivedFinalHeader = await finalizedHeaders.get()
receivedOptimisticHeader = await optimisticHeaders.get()
check:
hash_tree_root(receivedFinalHeader.altairData) == bootstrapHeaderHash
hash_tree_root(receivedOptimisticHeader.altairData) == bootstrapHeaderHash