2022-02-15 13:00:39 +00:00
|
|
|
#
|
|
|
|
# Ethereum P2P
|
|
|
|
# (c) Copyright 2018
|
|
|
|
# Status Research & Development GmbH
|
|
|
|
#
|
|
|
|
# See the file "LICENSE", included in this
|
|
|
|
# distribution, for details about the copyright.
|
|
|
|
#
|
|
|
|
|
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
|
|
|
std/sequtils,
|
|
|
|
chronos, stew/byteutils, nimcrypto, testutils/unittests,
|
|
|
|
eth/keys,
|
2022-02-15 14:02:25 +00:00
|
|
|
../../eth/p2p/providers,
|
|
|
|
chronicles,
|
|
|
|
../../eth/p2p/discoveryv5/protocol as discv5_protocol,
|
|
|
|
./discv5_test_helper,
|
2022-02-16 09:17:00 +00:00
|
|
|
libp2p/routing_record,
|
|
|
|
libp2p/multihash,
|
|
|
|
libp2p/multicodec
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-16 09:14:35 +00:00
|
|
|
proc initProvidersNode(
|
2022-02-15 14:02:25 +00:00
|
|
|
rng: ref BrHmacDrbgContext,
|
|
|
|
privKey: keys.PrivateKey,
|
|
|
|
address: Address,
|
|
|
|
bootstrapRecords: openArray[Record] = []):
|
|
|
|
ProvidersProtocol =
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
let d = initDiscoveryNode(rng, privKey, address, bootstrapRecords)
|
2022-02-16 09:14:35 +00:00
|
|
|
newProvidersProtocol(d)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-16 09:17:00 +00:00
|
|
|
proc toPeerRecord(p: ProvidersProtocol) : PeerRecord =
|
|
|
|
## hadle conversion between the two worlds
|
|
|
|
|
|
|
|
#NodeId is a keccak-256 hash created by keccak256.digest and stored as UInt256
|
|
|
|
let discNodeId = p.discovery.localNode.id
|
|
|
|
## get it back to MDigest form
|
|
|
|
var digest: MDigest[256]
|
|
|
|
digest.data = discNodeId.toBytesBE
|
|
|
|
## get into a MultiHash
|
|
|
|
var mh = MultiHash.init(multiCodec("keccak-256"), digest).orError(HashError).get()
|
|
|
|
result = PeerRecord.init(
|
|
|
|
peerId = PeerId.init(mh.data.buffer).get,
|
|
|
|
seqNo = 0,
|
|
|
|
addresses = @[])
|
2022-02-16 09:49:17 +00:00
|
|
|
# trace "IDs", discNodeId, digest, mh, peerId=result.peerId.hex
|
2022-02-16 09:17:00 +00:00
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
proc bootstrapNodes(nodecount: int, bootnodes: openArray[Record], rng = keys.newRng()) : seq[ProvidersProtocol] =
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
for i in 0..<nodecount:
|
2022-02-15 14:02:25 +00:00
|
|
|
let node = initProvidersNode(rng, keys.PrivateKey.random(rng[]), localAddress(20302 + i), bootnodes)
|
2022-02-16 09:14:35 +00:00
|
|
|
node.discovery.start()
|
2022-02-15 13:00:39 +00:00
|
|
|
result.add(node)
|
|
|
|
debug "---- STARTING BOOSTRAPS ---"
|
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
#await allFutures(result.mapIt(it.bootstrap())) # this waits for bootstrap based on bootENode, which includes bonding with all its ping pongs
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
proc bootstrapNetwork(nodecount: int, rng = keys.newRng()) : seq[ProvidersProtocol] =
|
2022-02-15 13:00:39 +00:00
|
|
|
let
|
2022-02-15 14:02:25 +00:00
|
|
|
bootNodeKey = keys.PrivateKey.fromHex(
|
2022-02-15 13:00:39 +00:00
|
|
|
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
|
|
|
bootNodeAddr = localAddress(20301)
|
2022-02-15 14:02:25 +00:00
|
|
|
bootNode = initProvidersNode(rng, bootNodeKey, bootNodeAddr, @[]) # just a shortcut for new and open
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
#waitFor bootNode.bootstrap() # immediate, since no bootnodes are defined above
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-15 14:02:25 +00:00
|
|
|
result = bootstrapNodes(nodecount - 1, @[bootnode.discovery.localNode.record], rng = rng)
|
2022-02-15 13:00:39 +00:00
|
|
|
result.insert(bootNode, 0)
|
|
|
|
|
|
|
|
|
|
|
|
suite "Providers Tests: node alone":
|
|
|
|
|
|
|
|
asyncTest "node alone":
|
|
|
|
let
|
|
|
|
rng = keys.newRng()
|
2022-02-15 14:02:25 +00:00
|
|
|
nodes = bootstrapNetwork(nodecount=1)
|
|
|
|
targetId = toNodeId(keys.PrivateKey.random(rng[]).toPublicKey)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "Node in isolation should store":
|
|
|
|
|
|
|
|
debug "---- ADDING PROVIDERS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
let addedTo = await nodes[0].addProvider(targetId, nodes[0].toPeerRecord)
|
2022-02-15 13:00:39 +00:00
|
|
|
debug "Provider added to: ", addedTo
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
|
|
|
check (addedTo.len == 1)
|
2022-02-16 09:17:33 +00:00
|
|
|
check (addedTo[0].id == nodes[0].discovery.localNode.id)
|
|
|
|
check (nodes[0].getProvidersLocal(targetId)[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "Node in isolation should retrieve":
|
|
|
|
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[0].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len > 0 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "Should not retrieve bogus":
|
|
|
|
|
2022-02-16 09:17:33 +00:00
|
|
|
let bogusId = toNodeId(keys.PrivateKey.random(rng[]).toPublicKey)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[0].getProviders(bogusId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
|
|
|
check (providers.len == 0)
|
|
|
|
|
|
|
|
for n in nodes:
|
2022-02-16 09:17:33 +00:00
|
|
|
await n.discovery.closeWait()
|
2022-02-15 13:00:39 +00:00
|
|
|
await sleepAsync(chronos.seconds(3))
|
|
|
|
|
|
|
|
asyncTest "Providers Tests: two nodes":
|
|
|
|
let
|
|
|
|
rng = keys.newRng()
|
2022-02-15 14:02:25 +00:00
|
|
|
nodes = bootstrapNetwork(nodecount=2)
|
|
|
|
targetId = toNodeId(keys.PrivateKey.random(rng[]).toPublicKey)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "2 nodes, store and retieve from same":
|
|
|
|
|
|
|
|
debug "---- ADDING PROVIDERS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
let addedTo = await nodes[0].addProvider(targetId, nodes[0].toPeerRecord)
|
2022-02-15 13:00:39 +00:00
|
|
|
debug "Provider added to: ", addedTo
|
|
|
|
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[0].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len == 1 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "2 nodes, retieve from other":
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[1].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len == 1 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
for n in nodes:
|
2022-02-16 09:17:33 +00:00
|
|
|
await n.discovery.closeWait()
|
2022-02-15 13:00:39 +00:00
|
|
|
await sleepAsync(chronos.seconds(3))
|
|
|
|
|
|
|
|
asyncTest "Providers Tests: 20 nodes":
|
|
|
|
let
|
|
|
|
rng = keys.newRng()
|
2022-02-16 09:17:33 +00:00
|
|
|
nodes = bootstrapNetwork(nodecount=20)
|
|
|
|
targetId = toNodeId(keys.PrivateKey.random(rng[]).toPublicKey)
|
|
|
|
await sleepAsync(chronos.seconds(5))
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "20 nodes, store and retieve from same":
|
|
|
|
|
|
|
|
debug "---- ADDING PROVIDERS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
let addedTo = await nodes[0].addProvider(targetId, nodes[0].toPeerRecord)
|
2022-02-15 13:00:39 +00:00
|
|
|
debug "Provider added to: ", addedTo
|
|
|
|
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[0].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len == 1 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "20 nodes, retieve from other":
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[^1].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len == 1 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
asyncTest "20 nodes, retieve after bootnode dies":
|
|
|
|
debug "---- KILLING BOOTSTRAP NODE ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
await nodes[0].discovery.closeWait()
|
2022-02-15 13:00:39 +00:00
|
|
|
|
|
|
|
debug "---- STARTING PROVIDERS LOOKUP ---"
|
|
|
|
let providers = await nodes[^2].getProviders(targetId)
|
|
|
|
debug "Providers:", providers
|
|
|
|
|
|
|
|
debug "---- STARTING CHECKS ---"
|
2022-02-16 09:17:33 +00:00
|
|
|
check (providers.len == 1 and providers[0].peerId == nodes[0].toPeerRecord.peerId)
|
2022-02-15 13:00:39 +00:00
|
|
|
|
2022-02-16 09:17:33 +00:00
|
|
|
for n in nodes[1..^1]:
|
|
|
|
await n.discovery.closeWait()
|