mirror of https://github.com/waku-org/nwaku.git
428 lines
12 KiB
Nim
428 lines
12 KiB
Nim
{.used.}
|
|
|
|
import
|
|
std/[options, sequtils],
|
|
stew/results,
|
|
testutils/unittests
|
|
import
|
|
../../waku/waku_core,
|
|
../../waku/waku_enr,
|
|
./testlib/wakucore
|
|
|
|
|
|
suite "Waku ENR - Capabilities bitfield":
|
|
test "check capabilities support":
|
|
## Given
|
|
let bitfield: CapabilitiesBitfield = 0b0000_1101u8 # Lightpush, Filter, Relay
|
|
|
|
## Then
|
|
check:
|
|
bitfield.supportsCapability(Capabilities.Relay)
|
|
not bitfield.supportsCapability(Capabilities.Store)
|
|
bitfield.supportsCapability(Capabilities.Filter)
|
|
bitfield.supportsCapability(Capabilities.Lightpush)
|
|
|
|
test "bitfield to capabilities list":
|
|
## Given
|
|
let bitfield = CapabilitiesBitfield.init(
|
|
relay = true,
|
|
store = false,
|
|
lightpush = true,
|
|
filter = true
|
|
)
|
|
|
|
## When
|
|
let caps = bitfield.toCapabilities()
|
|
|
|
## Then
|
|
check:
|
|
caps == @[Capabilities.Relay, Capabilities.Filter, Capabilities.Lightpush]
|
|
|
|
test "encode and decode record with capabilities field (EnrBuilder ext)":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
## When
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
builder.withWakuCapabilities(Capabilities.Relay, Capabilities.Store)
|
|
|
|
let recordRes = builder.build()
|
|
|
|
## Then
|
|
check recordRes.isOk()
|
|
let record = recordRes.tryGet()
|
|
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let bitfieldOpt = typedRecord.value.waku2
|
|
check bitfieldOpt.isSome()
|
|
|
|
let bitfield = bitfieldOpt.get()
|
|
check:
|
|
bitfield.toCapabilities() == @[Capabilities.Relay, Capabilities.Store]
|
|
|
|
test "cannot decode capabilities from record":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let record = EnrBuilder.init(enrPrivKey, enrSeqNum).build().tryGet()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let bitfieldOpt = typedRecord.value.waku2
|
|
|
|
## Then
|
|
check bitfieldOpt.isNone()
|
|
|
|
test "check capabilities on a waku node record":
|
|
## Given
|
|
let wakuRecord = "-Hy4QC73_E3B_FkZhsOakaD4pHe-U--UoGASdG9N0F3SFFUDY_jdQbud8" &
|
|
"EXVyrlOZ5pZ7VYFBDPMRCENwy87Lh74dFIBgmlkgnY0iXNlY3AyNTZrMaECvNt1jIWbWGp" &
|
|
"AWWdlLGYm1E1OjlkQk3ONoxDC5sfw8oOFd2FrdTID"
|
|
|
|
## When
|
|
var record: Record
|
|
require waku_enr.fromBase64(record, wakuRecord)
|
|
|
|
## Then
|
|
let typedRecordRes = record.toTyped()
|
|
require typedRecordRes.isOk()
|
|
|
|
let bitfieldOpt = typedRecordRes.value.waku2
|
|
require bitfieldOpt.isSome()
|
|
|
|
let bitfield = bitfieldOpt.get()
|
|
check:
|
|
bitfield.supportsCapability(Capabilities.Relay) == true
|
|
bitfield.supportsCapability(Capabilities.Store) == true
|
|
bitfield.supportsCapability(Capabilities.Filter) == false
|
|
bitfield.supportsCapability(Capabilities.Lightpush) == false
|
|
bitfield.toCapabilities() == @[Capabilities.Relay, Capabilities.Store]
|
|
|
|
test "check capabilities on a non-waku node record":
|
|
## Given
|
|
# non waku enr, i.e. Ethereum one
|
|
let nonWakuEnr = "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2G" &
|
|
"xb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNl" &
|
|
"Y3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA"
|
|
|
|
## When
|
|
var record: Record
|
|
require waku_enr.fromURI(record, nonWakuEnr)
|
|
|
|
## Then
|
|
let typedRecordRes = record.toTyped()
|
|
require typedRecordRes.isOk()
|
|
|
|
let bitfieldOpt = typedRecordRes.value.waku2
|
|
check bitfieldOpt.isNone()
|
|
|
|
check:
|
|
record.getCapabilities() == []
|
|
record.supportsCapability(Capabilities.Relay) == false
|
|
record.supportsCapability(Capabilities.Store) == false
|
|
record.supportsCapability(Capabilities.Filter) == false
|
|
record.supportsCapability(Capabilities.Lightpush) == false
|
|
|
|
|
|
suite "Waku ENR - Multiaddresses":
|
|
|
|
test "decode record with multiaddrs field":
|
|
## Given
|
|
let enrUri = "enr:-QEnuEBEAyErHEfhiQxAVQoWowGTCuEF9fKZtXSd7H_PymHFhGJA3rGAYDVSH" &
|
|
"KCyJDGRLBGsloNbS8AZF33IVuefjOO6BIJpZIJ2NIJpcIQS39tkim11bHRpYWRkcn" &
|
|
"O4lgAvNihub2RlLTAxLmRvLWFtczMud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BgG" &
|
|
"73gMAODcxbm9kZS0wMS5hYy1jbi1ob25na29uZy1jLndha3V2Mi50ZXN0LnN0YXR1" &
|
|
"c2ltLm5ldAYBu94DACm9A62t7AQL4Ef5ZYZosRpQTzFVAB8jGjf1TER2wH-0zBOe1" &
|
|
"-MDBNLeA4lzZWNwMjU2azGhAzfsxbxyCkgCqq8WwYsVWH7YkpMLnU2Bw5xJSimxKa" &
|
|
"v-g3VkcIIjKA"
|
|
|
|
var record: Record
|
|
require record.fromURI(enrUri)
|
|
|
|
let
|
|
expectedAddr1 = MultiAddress.init("/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss").get()
|
|
expectedAddr2 = MultiAddress.init("/dns6/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss").get()
|
|
expectedAddr3 = MultiAddress.init("/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234/wss").get()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let multiaddrsOpt = typedRecord.value.multiaddrs
|
|
|
|
## Then
|
|
check multiaddrsOpt.isSome()
|
|
|
|
let multiaddrs = multiaddrsOpt.get()
|
|
check:
|
|
multiaddrs.len == 3
|
|
multiaddrs.contains(expectedAddr1)
|
|
multiaddrs.contains(expectedAddr2)
|
|
multiaddrs.contains(expectedAddr3)
|
|
|
|
test "encode and decode record with multiaddrs field (EnrBuilder ext)":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let
|
|
addr1 = MultiAddress.init("/ip4/127.0.0.1/tcp/80/ws").get()
|
|
addr2 = MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss").get()
|
|
|
|
## When
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
builder.withMultiaddrs(addr1, addr2)
|
|
|
|
let recordRes = builder.build()
|
|
|
|
require recordRes.isOk()
|
|
let record = recordRes.tryGet()
|
|
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let multiaddrsOpt = typedRecord.value.multiaddrs
|
|
|
|
## Then
|
|
check multiaddrsOpt.isSome()
|
|
|
|
let multiaddrs = multiaddrsOpt.get()
|
|
check:
|
|
multiaddrs.len == 2
|
|
multiaddrs.contains(addr1)
|
|
multiaddrs.contains(addr2)
|
|
|
|
test "cannot decode multiaddresses from record":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let record = EnrBuilder.init(enrPrivKey, enrSeqNum).build().tryGet()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let fieldOpt = typedRecord.value.multiaddrs
|
|
|
|
## Then
|
|
check fieldOpt.isNone()
|
|
|
|
test "encode and decode record with multiaddresses field - strip peer ID":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let
|
|
addr1 = MultiAddress.init("/ip4/127.0.0.1/tcp/80/ws/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr31iDQpSN5Qa882BCjjwgrD").get()
|
|
addr2 = MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss").get()
|
|
|
|
let expectedAddr1 = MultiAddress.init("/ip4/127.0.0.1/tcp/80/ws").get()
|
|
|
|
## When
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
builder.withMultiaddrs(addr1, addr2)
|
|
|
|
let recordRes = builder.build()
|
|
|
|
require recordRes.isOk()
|
|
let record = recordRes.tryGet()
|
|
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let multiaddrsOpt = typedRecord.value.multiaddrs
|
|
|
|
## Then
|
|
check multiaddrsOpt.isSome()
|
|
|
|
let multiaddrs = multiaddrsOpt.get()
|
|
check:
|
|
multiaddrs.contains(expectedAddr1)
|
|
multiaddrs.contains(addr2)
|
|
|
|
|
|
suite "Waku ENR - Relay static sharding":
|
|
|
|
test "new relay shards field with single invalid index":
|
|
## Given
|
|
let
|
|
shardCluster: uint16 = 22
|
|
shardIndex: uint16 = 1024
|
|
|
|
## When
|
|
let res = RelayShards.init(shardCluster, shardIndex)
|
|
|
|
## Then
|
|
assert res.isErr(), $res.get()
|
|
|
|
test "new relay shards field with single invalid index in list":
|
|
## Given
|
|
let
|
|
shardCluster: uint16 = 22
|
|
shardIndices: seq[uint16] = @[1u16, 1u16, 2u16, 3u16, 5u16, 8u16, 1024u16]
|
|
|
|
## When
|
|
let res = RelayShards.init(shardCluster, shardIndices)
|
|
|
|
## Then
|
|
assert res.isErr(), $res.get()
|
|
|
|
test "new relay shards field with single valid index":
|
|
## Given
|
|
let
|
|
shardCluster: uint16 = 22
|
|
shardIndex: uint16 = 1
|
|
|
|
let topic = NsPubsubTopic.staticSharding(shardCluster, shardIndex)
|
|
|
|
## When
|
|
let shards = RelayShards.init(shardCluster, shardIndex).expect("Valid Shards")
|
|
|
|
## Then
|
|
check:
|
|
shards.cluster == shardCluster
|
|
shards.indices == @[1u16]
|
|
|
|
let topics = shards.topics.mapIt($it)
|
|
check:
|
|
topics == @[$topic]
|
|
|
|
check:
|
|
shards.contains(shardCluster, shardIndex)
|
|
not shards.contains(shardCluster, 33u16)
|
|
not shards.contains(20u16, 33u16)
|
|
|
|
shards.contains(topic)
|
|
shards.contains("/waku/2/rs/22/1")
|
|
|
|
test "new relay shards field with repeated but valid indices":
|
|
## Given
|
|
let
|
|
shardCluster: uint16 = 22
|
|
shardIndices: seq[uint16] = @[1u16, 2u16, 2u16, 3u16, 3u16, 3u16]
|
|
|
|
## When
|
|
let shards = RelayShards.init(shardCluster, shardIndices).expect("Valid Shards")
|
|
|
|
## Then
|
|
check:
|
|
shards.cluster == shardCluster
|
|
shards.indices == @[1u16, 2u16, 3u16]
|
|
|
|
test "cannot decode relay shards from record if not present":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let record = EnrBuilder.init(enrPrivKey, enrSeqNum).build().tryGet()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let fieldOpt = typedRecord.value.relaySharding
|
|
|
|
## Then
|
|
check fieldOpt.isNone()
|
|
|
|
test "encode and decode record with relay shards field (EnrBuilder ext - indices list)":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let
|
|
shardCluster: uint16 = 22
|
|
shardIndices: seq[uint16] = @[1u16, 1u16, 2u16, 3u16, 5u16, 8u16]
|
|
|
|
let shards = RelayShards.init(shardCluster, shardIndices).expect("Valid Shards")
|
|
|
|
## When
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
require builder.withWakuRelaySharding(shards).isOk()
|
|
|
|
let recordRes = builder.build()
|
|
|
|
## Then
|
|
check recordRes.isOk()
|
|
let record = recordRes.tryGet()
|
|
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let shardsOpt = typedRecord.value.relaySharding
|
|
check:
|
|
shardsOpt.isSome()
|
|
shardsOpt.get() == shards
|
|
|
|
test "encode and decode record with relay shards field (EnrBuilder ext - bit vector)":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let shards = RelayShards.init(33, toSeq(0u16 ..< 64u16)).expect("Valid Shards")
|
|
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
require builder.withWakuRelaySharding(shards).isOk()
|
|
|
|
let recordRes = builder.build()
|
|
require recordRes.isOk()
|
|
|
|
let record = recordRes.tryGet()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let shardsOpt = typedRecord.value.relaySharding
|
|
|
|
## Then
|
|
check:
|
|
shardsOpt.isSome()
|
|
shardsOpt.get() == shards
|
|
|
|
test "decode record with relay shards indices list and bit vector fields":
|
|
## Given
|
|
let
|
|
enrSeqNum = 1u64
|
|
enrPrivKey = generatesecp256k1key()
|
|
|
|
let
|
|
shardsIndicesList = RelayShards.init(22, @[1u16, 1u16, 2u16, 3u16, 5u16, 8u16]).expect("Valid Shards")
|
|
shardsBitVector = RelayShards.init(33, @[13u16, 24u16, 37u16, 61u16, 98u16, 159u16]).expect("Valid Shards")
|
|
|
|
|
|
var builder = EnrBuilder.init(enrPrivKey, seqNum = enrSeqNum)
|
|
require builder.withWakuRelayShardingIndicesList(shardsIndicesList).isOk()
|
|
require builder.withWakuRelayShardingBitVector(shardsBitVector).isOk()
|
|
|
|
let recordRes = builder.build()
|
|
require recordRes.isOk()
|
|
|
|
let record = recordRes.tryGet()
|
|
|
|
## When
|
|
let typedRecord = record.toTyped()
|
|
require typedRecord.isOk()
|
|
|
|
let shardsOpt = typedRecord.value.relaySharding
|
|
|
|
## Then
|
|
check:
|
|
shardsOpt.isSome()
|
|
shardsOpt.get() == shardsIndicesList
|