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

200 lines
7.0 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.
import
testutils/unittests, chronos,
eth/p2p/discoveryv5/protocol as discv5_protocol,
beacon_chain/spec/forks,
beacon_chain/spec/datatypes/altair,
../../network/wire/portal_protocol,
../../network/beacon/[beacon_network, beacon_init_loader],
"."/[light_client_test_data, beacon_test_helpers]
procSuite "Beacon Content Network":
let rng = newRng()
asyncTest "Get bootstrap by trusted block hash":
let
networkData = loadNetworkData("mainnet")
lcNode1 = newLCNode(rng, 20302, networkData)
lcNode2 = newLCNode(rng, 20303, networkData)
forkDigests = (newClone networkData.forks)[]
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
altairData = SSZ.decode(bootstrapBytes, altair.LightClientBootstrap)
bootstrap = ForkedLightClientBootstrap(
kind: LightClientDataFork.Altair, altairData: altairData)
bootstrapHeaderHash = hash_tree_root(altairData.header)
bootstrapKey = LightClientBootstrapKey(
blockHash: bootstrapHeaderHash
)
bootstrapContentKey = ContentKey(
contentType: lightClientBootstrap,
lightClientBootstrapKey: bootstrapKey
)
bootstrapContentKeyEncoded = encode(bootstrapContentKey)
bootstrapContentId = toContentId(bootstrapContentKeyEncoded)
lcNode2.portalProtocol().storeContent(
bootstrapContentKeyEncoded,
bootstrapContentId,
encodeForkedLightClientObject(bootstrap, forkDigests.altair)
)
let bootstrapFromNetworkResult =
await lcNode1.beaconNetwork.getLightClientBootstrap(
bootstrapHeaderHash
)
check:
bootstrapFromNetworkResult.isOk()
bootstrapFromNetworkResult.get().altairData == bootstrap.altairData
await lcNode1.stop()
await lcNode2.stop()
asyncTest "Get latest optimistic and finality updates":
let
networkData = loadNetworkData("mainnet")
lcNode1 = newLCNode(rng, 20302, networkData)
lcNode2 = newLCNode(rng, 20303, networkData)
forkDigests = (newClone networkData.forks)[]
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
finalityUpdateData = SSZ.decode(
lightClientFinalityUpdateBytes, altair.LightClientFinalityUpdate)
finalityUpdate = ForkedLightClientFinalityUpdate(
kind: LightClientDataFork.Altair, altairData: finalityUpdateData)
finalizedHeaderSlot = finalityUpdateData.finalized_header.beacon.slot
finalizedOptimisticHeaderSlot =
finalityUpdateData.attested_header.beacon.slot
optimisticUpdateData = SSZ.decode(
lightClientOptimisticUpdateBytes, altair.LightClientOptimisticUpdate)
optimisticUpdate = ForkedLightClientOptimisticUpdate(
kind: LightClientDataFork.Altair, altairData: optimisticUpdateData)
optimisticHeaderSlot = optimisticUpdateData.signature_slot
finalityUpdateKey = finalityUpdateContentKey(
distinctBase(finalizedHeaderSlot)
)
finalityKeyEnc = encode(finalityUpdateKey)
finalityUpdateId = toContentId(finalityKeyEnc)
optimisticUpdateKey = optimisticUpdateContentKey(
distinctBase(optimisticHeaderSlot))
optimisticKeyEnc = encode(optimisticUpdateKey)
optimisticUpdateId = toContentId(optimisticKeyEnc)
# This silently assumes that peer stores only one latest update, under
# the contentId coresponding to latest update content key
lcNode2.portalProtocol().storeContent(
finalityKeyEnc,
finalityUpdateId,
encodeForkedLightClientObject(finalityUpdate, forkDigests.altair)
)
lcNode2.portalProtocol().storeContent(
optimisticKeyEnc,
optimisticUpdateId,
encodeForkedLightClientObject(optimisticUpdate, forkDigests.altair)
)
let
finalityResult =
await lcNode1.beaconNetwork.getLightClientFinalityUpdate(
distinctBase(finalizedHeaderSlot),
)
optimisticResult =
await lcNode1.beaconNetwork.getLightClientOptimisticUpdate(
distinctBase(optimisticHeaderSlot)
)
check:
finalityResult.isOk()
optimisticResult.isOk()
finalityResult.get().altairData == finalityUpdate.altairData
optimisticResult.get().altairData == optimisticUpdate.altairData
await lcNode1.stop()
await lcNode2.stop()
asyncTest "Get range of light client updates":
let
networkData = loadNetworkData("mainnet")
lcNode1 = newLCNode(rng, 20302, networkData)
lcNode2 = newLCNode(rng, 20303, networkData)
forkDigests = (newClone networkData.forks)[]
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
altairData1 = SSZ.decode(lightClientUpdateBytes, altair.LightClientUpdate)
altairData2 = SSZ.decode(lightClientUpdateBytes1, altair.LightClientUpdate)
update1 = ForkedLightClientUpdate(
kind: LightClientDataFork.Altair, altairData: altairData1)
update2 = ForkedLightClientUpdate(
kind: LightClientDataFork.Altair, altairData: altairData2)
updates = @[update1, update2]
content = encodeLightClientUpdatesForked(forkDigests.altair, updates)
startPeriod =
altairData1.attested_header.beacon.slot.sync_committee_period
contentKey = ContentKey(
contentType: lightClientUpdate,
lightClientUpdateKey: LightClientUpdateKey(
startPeriod: startPeriod.uint64,
count: uint64(2)
)
)
contentKeyEncoded = encode(contentKey)
contentId = toContentId(contentKey)
lcNode2.portalProtocol().storeContent(
contentKeyEncoded,
contentId,
content
)
let updatesResult =
await lcNode1.beaconNetwork.getLightClientUpdatesByRange(
startPeriod,
uint64(2)
)
check:
updatesResult.isOk()
let updatesFromPeer = updatesResult.get()
check:
updatesFromPeer.asSeq()[0].altairData == updates[0].altairData
updatesFromPeer.asSeq()[1].altairData == updates[1].altairData
await lcNode1.stop()
await lcNode2.stop()