2022-10-28 07:49:18 +00:00
|
|
|
# Nimbus - Portal Network
|
2023-01-31 12:38:08 +00:00
|
|
|
# Copyright (c) 2022-2023 Status Research & Development GmbH
|
2022-10-28 07:49:18 +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.
|
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
{.push raises: [].}
|
2022-10-28 07:49:18 +00:00
|
|
|
|
|
|
|
import
|
|
|
|
testutils/unittests, chronos,
|
2023-02-26 18:18:03 +00:00
|
|
|
eth/p2p/discoveryv5/protocol as discv5_protocol,
|
2022-10-28 07:49:18 +00:00
|
|
|
beacon_chain/spec/forks,
|
|
|
|
beacon_chain/spec/datatypes/altair,
|
2022-12-09 17:00:45 +00:00
|
|
|
beacon_chain/spec/helpers,
|
2022-10-28 07:49:18 +00:00
|
|
|
../../network/wire/[portal_protocol, portal_stream],
|
2023-10-20 10:06:25 +00:00
|
|
|
../../network/beacon/[beacon_init_loader, beacon_light_client],
|
|
|
|
"."/[light_client_test_data, beacon_test_helpers]
|
2022-10-28 07:49:18 +00:00
|
|
|
|
2023-02-26 18:18:03 +00:00
|
|
|
procSuite "Portal Beacon Light Client":
|
2022-10-28 07:49:18 +00:00
|
|
|
let rng = newRng()
|
|
|
|
|
2023-02-26 18:18:03 +00:00
|
|
|
proc headerCallback(
|
|
|
|
q: AsyncQueue[ForkedLightClientHeader]): LightClientHeaderCallback =
|
2022-10-28 07:49:18 +00:00
|
|
|
return (
|
2023-02-26 18:18:03 +00:00
|
|
|
proc (lightClient: LightClient, finalizedHeader: ForkedLightClientHeader)
|
|
|
|
{.gcsafe, raises: [].} =
|
2022-10-28 07:49:18 +00:00
|
|
|
try:
|
|
|
|
q.putNoWait(finalizedHeader)
|
|
|
|
except AsyncQueueFullError as exc:
|
|
|
|
raiseAssert(exc.msg)
|
|
|
|
)
|
|
|
|
|
|
|
|
asyncTest "Start and retrieve bootstrap":
|
|
|
|
let
|
2023-02-26 18:18:03 +00:00
|
|
|
finalizedHeaders = newAsyncQueue[ForkedLightClientHeader]()
|
|
|
|
optimisticHeaders = newAsyncQueue[ForkedLightClientHeader]()
|
2022-10-28 07:49:18 +00:00
|
|
|
# Test data is retrieved from mainnet
|
2023-09-28 16:16:41 +00:00
|
|
|
networkData = loadNetworkData("mainnet")
|
2023-10-18 14:59:44 +00:00
|
|
|
lcNode1 = newLCNode(rng, 20302, networkData)
|
|
|
|
lcNode2 = newLCNode(rng, 20303, networkData)
|
2023-02-26 18:18:03 +00:00
|
|
|
altairData = SSZ.decode(bootstrapBytes, altair.LightClientBootstrap)
|
|
|
|
bootstrap = ForkedLightClientBootstrap(
|
|
|
|
kind: LightClientDataFork.Altair, altairData: altairData)
|
|
|
|
bootstrapHeaderHash = hash_tree_root(altairData.header)
|
2022-10-28 07:49:18 +00:00
|
|
|
|
|
|
|
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(
|
2022-11-08 17:31:45 +00:00
|
|
|
bootstrapContentKeyEncoded,
|
|
|
|
bootstrapContentId,
|
2023-09-28 16:16:41 +00:00
|
|
|
encodeForkedLightClientObject(bootstrap, networkData.forks.altair)
|
2022-10-28 07:49:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
let lc = LightClient.new(
|
2023-10-20 10:06:25 +00:00
|
|
|
lcNode1.beaconNetwork, rng, networkData,
|
2023-09-28 16:16:41 +00:00
|
|
|
LightClientFinalizationMode.Optimistic)
|
2022-10-28 07:49:18 +00:00
|
|
|
|
2023-02-26 18:18:03 +00:00
|
|
|
lc.onFinalizedHeader = headerCallback(finalizedHeaders)
|
2022-10-28 07:49:18 +00:00
|
|
|
lc.onOptimisticHeader = headerCallback(optimisticHeaders)
|
|
|
|
lc.trustedBlockRoot = some bootstrapHeaderHash
|
|
|
|
|
2023-02-26 18:18:03 +00:00
|
|
|
# When running start the beacon light client will first try to retrieve the
|
|
|
|
# bootstrap for given trustedBlockRoot
|
2022-10-28 07:49:18 +00:00
|
|
|
lc.start()
|
|
|
|
|
2023-09-28 16:16:41 +00:00
|
|
|
# Wait until the beacon light client retrieves the bootstrap. Upon receiving
|
2023-02-26 18:18:03 +00:00
|
|
|
# the bootstrap both onFinalizedHeader and onOptimisticHeader callbacks
|
|
|
|
# will be called.
|
2022-10-28 07:49:18 +00:00
|
|
|
let
|
2023-02-26 18:18:03 +00:00
|
|
|
receivedFinalHeader = await finalizedHeaders.get()
|
2022-10-28 07:49:18 +00:00
|
|
|
receivedOptimisticHeader = await optimisticHeaders.get()
|
|
|
|
|
|
|
|
check:
|
2023-02-26 18:18:03 +00:00
|
|
|
hash_tree_root(receivedFinalHeader.altairData) == bootstrapHeaderHash
|
|
|
|
hash_tree_root(receivedOptimisticHeader.altairData) == bootstrapHeaderHash
|
2022-10-28 07:49:18 +00:00
|
|
|
|