mirror of https://github.com/waku-org/nwaku.git
refactor(enr): node capabilities code clean up and reorganization
This commit is contained in:
parent
67db35e29d
commit
7639d8d273
|
@ -269,10 +269,12 @@ proc initNode(conf: WakuNodeConf,
|
|||
else:
|
||||
@[]
|
||||
|
||||
wakuFlags = initWakuFlags(conf.lightpush,
|
||||
conf.filter,
|
||||
conf.store,
|
||||
conf.relay)
|
||||
wakuFlags = CapabilitiesBitfield.init(
|
||||
lightpush = conf.lightpush,
|
||||
filter = conf.filter,
|
||||
store = conf.store,
|
||||
relay = conf.relay
|
||||
)
|
||||
|
||||
var node: WakuNode
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ proc setupAndPublish(rng: ref HmacDrbgContext) {.async.} =
|
|||
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||
ip = ValidIpAddress.init("0.0.0.0")
|
||||
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
|
||||
flags = initWakuFlags(lightpush = false, filter = false, store = false, relay = true)
|
||||
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)
|
||||
|
||||
# assumes behind a firewall, so not care about being discoverable
|
||||
node.wakuDiscv5 = WakuDiscoveryV5.new(
|
||||
|
|
|
@ -32,7 +32,7 @@ proc setupAndSubscribe(rng: ref HmacDrbgContext) {.async.} =
|
|||
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||
ip = ValidIpAddress.init("0.0.0.0")
|
||||
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
|
||||
flags = initWakuFlags(lightpush = false, filter = false, store = false, relay = true)
|
||||
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)
|
||||
|
||||
# assumes behind a firewall, so not care about being discoverable
|
||||
node.wakuDiscv5 = WakuDiscoveryV5.new(
|
||||
|
|
|
@ -38,10 +38,12 @@ procSuite "Waku Discovery v5":
|
|||
nodeUdpPort3 = Port(9004)
|
||||
node3 = WakuNode.new(nodeKey3, bindIp, nodeTcpPort3)
|
||||
|
||||
flags = initWakuFlags(lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true)
|
||||
flags = CapabilitiesBitfield.init(
|
||||
lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true
|
||||
)
|
||||
|
||||
# E2E relay test paramaters
|
||||
pubSubTopic = "/waku/2/default-waku/proto"
|
||||
|
@ -128,10 +130,12 @@ procSuite "Waku Discovery v5":
|
|||
extIp = ValidIpAddress.init("127.0.0.1")
|
||||
expectedMultiAddr = MultiAddress.init("/ip4/200.200.200.200/tcp/9000/wss").tryGet()
|
||||
|
||||
flags = initWakuFlags(lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true)
|
||||
flags = CapabilitiesBitfield.init(
|
||||
lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true
|
||||
)
|
||||
|
||||
nodeTcpPort1 = Port(9010)
|
||||
nodeUdpPort1 = Port(9012)
|
||||
|
|
|
@ -1,14 +1,113 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
std/[options, sequtils],
|
||||
stew/byteutils,
|
||||
std/options,
|
||||
stew/[results, byteutils],
|
||||
testutils/unittests
|
||||
import
|
||||
../../waku/v2/protocol/waku_enr,
|
||||
./testlib/waku2
|
||||
|
||||
suite "Waku ENR":
|
||||
|
||||
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 extract capabilities from record":
|
||||
## Given
|
||||
let enrkey = generatesecp256k1key()
|
||||
let caps = CapabilitiesBitfield.init(Capabilities.Relay, Capabilities.Store)
|
||||
|
||||
let record = Record.init(1, enrkey, wakuFlags=some(caps))
|
||||
|
||||
## When
|
||||
let bitfieldRes = record.getCapabilitiesField()
|
||||
|
||||
## Then
|
||||
check bitfieldRes.isOk()
|
||||
|
||||
let bitfield = bitfieldRes.tryGet()
|
||||
check:
|
||||
bitfield.toCapabilities() == @[Capabilities.Relay, Capabilities.Store]
|
||||
|
||||
test "cannot extract capabilities from record":
|
||||
## Given
|
||||
let enrkey = generatesecp256k1key()
|
||||
let record = Record.init(1, enrkey, wakuFlags=none(CapabilitiesBitfield))
|
||||
|
||||
## When
|
||||
let bitfieldRes = record.getCapabilitiesField()
|
||||
|
||||
## Then
|
||||
check bitfieldRes.isErr()
|
||||
|
||||
let err = bitfieldRes.tryError()
|
||||
check:
|
||||
err == "Key not found in ENR"
|
||||
|
||||
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
|
||||
check:
|
||||
record.supportsCapability(Relay) == true
|
||||
record.supportsCapability(Store) == true
|
||||
record.supportsCapability(Filter) == false
|
||||
record.supportsCapability(Lightpush) == false
|
||||
record.getCapabilities() == @[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 nonWakuEnrRecord: Record
|
||||
require waku_enr.fromURI(nonWakuEnrRecord, nonWakuEnr)
|
||||
|
||||
## Then
|
||||
check:
|
||||
nonWakuEnrRecord.getCapabilities() == []
|
||||
nonWakuEnrRecord.supportsCapability(Relay) == false
|
||||
nonWakuEnrRecord.supportsCapability(Store) == false
|
||||
nonWakuEnrRecord.supportsCapability(Filter) == false
|
||||
nonWakuEnrRecord.supportsCapability(Lightpush) == false
|
||||
|
||||
|
||||
suite "Waku ENR - Multiaddresses":
|
||||
|
||||
test "Parse multiaddr field":
|
||||
let
|
||||
|
@ -45,14 +144,13 @@ suite "Waku ENR":
|
|||
enrIp = ValidIpAddress.init("127.0.0.1")
|
||||
enrTcpPort, enrUdpPort = Port(61101)
|
||||
enrKey = generateSecp256k1Key()
|
||||
wakuFlags = initWakuFlags(false, true, false, true)
|
||||
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[],
|
||||
MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss")[]]
|
||||
|
||||
let
|
||||
record = enr.Record.init(enrKey, some(enrIp),
|
||||
record = enr.Record.init(1, enrKey, some(enrIp),
|
||||
some(enrTcpPort), some(enrUdpPort),
|
||||
some(wakuFlags),
|
||||
none(CapabilitiesBitfield),
|
||||
multiaddrs)
|
||||
typedRecord = record.toTypedRecord.get()
|
||||
|
||||
|
@ -64,11 +162,8 @@ suite "Waku ENR":
|
|||
Port(typedRecord.udp.get()) == enrUdpPort
|
||||
|
||||
# Check Waku ENR fields
|
||||
let
|
||||
decodedFlags = record.get(WAKU_ENR_FIELD, seq[byte])[]
|
||||
decodedAddrs = record.get(MULTIADDR_ENR_FIELD, seq[byte])[].toMultiAddresses()
|
||||
let decodedAddrs = record.get(MultiaddrEnrField, seq[byte]).tryGet().toMultiAddresses()
|
||||
check:
|
||||
decodedFlags == @[wakuFlags.byte]
|
||||
decodedAddrs.contains(MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[])
|
||||
decodedAddrs.contains(MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss")[])
|
||||
|
||||
|
@ -81,9 +176,9 @@ suite "Waku ENR":
|
|||
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr31iDQpSN5Qa882BCjjwgrD")[]]
|
||||
|
||||
let
|
||||
record = enr.Record.init(enrKey, some(enrIp),
|
||||
record = enr.Record.init(1, enrKey, some(enrIp),
|
||||
some(enrTcpPort), some(enrUdpPort),
|
||||
none(WakuEnrBitfield),
|
||||
none(CapabilitiesBitfield),
|
||||
multiaddrs)
|
||||
|
||||
# Check Waku ENR fields
|
||||
|
@ -126,92 +221,3 @@ suite "Waku ENR":
|
|||
for knownMultiaddr in knownMultiaddrs:
|
||||
check decodedAddrs.contains(knownMultiaddr)
|
||||
|
||||
test "Supports specific capabilities encoded in the ENR":
|
||||
let
|
||||
enrIp = ValidIpAddress.init("127.0.0.1")
|
||||
enrTcpPort, enrUdpPort = Port(60000)
|
||||
enrKey = generateSecp256k1Key()
|
||||
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[]]
|
||||
|
||||
# TODO: Refactor enr.Record.init, provide enums as inputs enr.Record.init(capabilites=[Store,Filter])
|
||||
# TODO: safer than a util function and directly using the bits
|
||||
# test all flag combinations 2^4 = 16 (b0000-b1111)
|
||||
records = toSeq(0b0000_0000'u8..0b0000_1111'u8)
|
||||
.mapIt(enr.Record.init(enrKey,
|
||||
some(enrIp),
|
||||
some(enrTcpPort),
|
||||
some(enrUdpPort),
|
||||
some(uint8(it)),
|
||||
multiaddrs))
|
||||
|
||||
# same order: lightpush | filter| store | relay
|
||||
expectedCapabilities = @[[false, false, false, false],
|
||||
[false, false, false, true],
|
||||
[false, false, true, false],
|
||||
[false, false, true, true],
|
||||
[false, true, false, false],
|
||||
[false, true, false, true],
|
||||
[false, true, true, false],
|
||||
[false, true, true, true],
|
||||
[true, false, false, false],
|
||||
[true, false, false, true],
|
||||
[true, false, true, false],
|
||||
[true, false, true, true],
|
||||
[true, true, false, false],
|
||||
[true, true, false, true],
|
||||
[true, true, true, false],
|
||||
[true, true, true, true]]
|
||||
|
||||
for i, record in records:
|
||||
for j, capability in @[Lightpush, Filter, Store, Relay]:
|
||||
check expectedCapabilities[i][j] == record.supportsCapability(capability)
|
||||
|
||||
test "Get all supported capabilities encoded in the ENR":
|
||||
let
|
||||
enrIp = ValidIpAddress.init("127.0.0.1")
|
||||
enrTcpPort, enrUdpPort = Port(60000)
|
||||
enrKey = generateSecp256k1Key()
|
||||
multiaddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/442/ws")[]]
|
||||
|
||||
records = @[0b0000_0000'u8,
|
||||
0b0000_1111'u8,
|
||||
0b0000_1001'u8,
|
||||
0b0000_1110'u8,
|
||||
0b0000_1000'u8,]
|
||||
.mapIt(enr.Record.init(enrKey,
|
||||
some(enrIp),
|
||||
some(enrTcpPort),
|
||||
some(enrUdpPort),
|
||||
some(uint8(it)),
|
||||
multiaddrs))
|
||||
|
||||
# expected capabilities, ordered LSB to MSB
|
||||
expectedCapabilities: seq[seq[Capabilities]] = @[
|
||||
#[0b0000_0000]# @[],
|
||||
#[0b0000_1111]# @[Relay, Store, Filter, Lightpush],
|
||||
#[0b0000_1001]# @[Relay, Lightpush],
|
||||
#[0b0000_1110]# @[Store, Filter, Lightpush],
|
||||
#[0b0000_1000]# @[Lightpush]]
|
||||
|
||||
for i, actualExpetedTuple in zip(records, expectedCapabilities):
|
||||
check actualExpetedTuple[0].getCapabilities() == actualExpetedTuple[1]
|
||||
|
||||
test "Get supported capabilities of a non waku node":
|
||||
|
||||
# non waku enr, i.e. Ethereum one
|
||||
let nonWakuEnr = "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2G"&
|
||||
"xb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNl"&
|
||||
"Y3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA"
|
||||
|
||||
var nonWakuEnrRecord: Record
|
||||
|
||||
check:
|
||||
nonWakuEnrRecord.fromURI(nonWakuEnr)
|
||||
|
||||
# check that it doesn't support any capability and it doesnt't break
|
||||
check:
|
||||
nonWakuEnrRecord.getCapabilities() == []
|
||||
nonWakuEnrRecord.supportsCapability(Relay) == false
|
||||
nonWakuEnrRecord.supportsCapability(Store) == false
|
||||
nonWakuEnrRecord.supportsCapability(Filter) == false
|
||||
nonWakuEnrRecord.supportsCapability(Lightpush) == false
|
||||
|
|
|
@ -89,10 +89,12 @@ procSuite "Waku Peer Exchange":
|
|||
node3 = WakuNode.new(nodeKey3, bindIp, nodeTcpPort3)
|
||||
|
||||
# todo: px flag
|
||||
flags = initWakuFlags(lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true)
|
||||
flags = CapabilitiesBitfield.init(
|
||||
lightpush = false,
|
||||
filter = false,
|
||||
store = false,
|
||||
relay = true
|
||||
)
|
||||
|
||||
# Mount discv5
|
||||
node1.wakuDiscv5 = WakuDiscoveryV5.new(
|
||||
|
|
|
@ -224,7 +224,7 @@ proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] =
|
|||
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||
nodeTcpPort = Port(60000)
|
||||
nodeUdpPort = Port(9000)
|
||||
flags = initWakuFlags(lightpush = false, filter = false, store = false, relay = true)
|
||||
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)
|
||||
|
||||
try:
|
||||
let
|
||||
|
|
|
@ -135,7 +135,7 @@ type NetConfig* = object
|
|||
enrIp*: Option[ValidIpAddress]
|
||||
enrPort*: Option[Port]
|
||||
discv5UdpPort*: Option[Port]
|
||||
wakuFlags*: Option[WakuEnrBitfield]
|
||||
wakuFlags*: Option[CapabilitiesBitfield]
|
||||
bindIp*: ValidIpAddress
|
||||
bindPort*: Port
|
||||
|
||||
|
@ -151,7 +151,7 @@ proc init*(
|
|||
wssEnabled: bool = false,
|
||||
dns4DomainName = none(string),
|
||||
discv5UdpPort = none(Port),
|
||||
wakuFlags = none(WakuEnrBitfield)
|
||||
wakuFlags = none(CapabilitiesBitfield)
|
||||
): T {.raises: [LPError]} =
|
||||
## Initialize addresses
|
||||
let
|
||||
|
@ -230,7 +230,7 @@ proc getEnr*(netConfig: NetConfig,
|
|||
if wakuDiscV5.isSome():
|
||||
return wakuDiscV5.get().protocol.getRecord()
|
||||
|
||||
return enr.Record.init(nodekey,
|
||||
return enr.Record.init(1, nodekey,
|
||||
netConfig.enrIp,
|
||||
netConfig.enrPort,
|
||||
netConfig.discv5UdpPort,
|
||||
|
@ -275,7 +275,7 @@ proc new*(T: type WakuNode,
|
|||
wssEnabled: bool = false,
|
||||
secureKey: string = "",
|
||||
secureCert: string = "",
|
||||
wakuFlags = none(WakuEnrBitfield),
|
||||
wakuFlags = none(CapabilitiesBitfield),
|
||||
nameResolver: NameResolver = nil,
|
||||
sendSignedPeerRecord = false,
|
||||
dns4DomainName = none(string),
|
||||
|
|
|
@ -72,10 +72,10 @@ proc addBootstrapNode*(bootstrapAddr: string,
|
|||
bootstrapAddr, reason = enrRes.error
|
||||
|
||||
proc isWakuNode(node: Node): bool =
|
||||
let wakuField = node.record.tryGet(WAKU_ENR_FIELD, uint8)
|
||||
let wakuField = node.record.tryGet(CapabilitiesEnrField, uint8)
|
||||
|
||||
if wakuField.isSome():
|
||||
return wakuField.get().WakuEnrBitfield != 0x00 # True if any flag set to true
|
||||
return wakuField.get() != 0x00 # True if any flag set to true
|
||||
|
||||
return false
|
||||
|
||||
|
@ -116,14 +116,14 @@ proc new*(T: type WakuDiscoveryV5,
|
|||
bootstrapEnrs = newSeq[enr.Record](),
|
||||
enrAutoUpdate = false,
|
||||
privateKey: keys.PrivateKey,
|
||||
flags: WakuEnrBitfield,
|
||||
flags: CapabilitiesBitfield,
|
||||
multiaddrs = newSeq[MultiAddress](),
|
||||
rng: ref HmacDrbgContext,
|
||||
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
||||
## TODO: consider loading from a configurable bootstrap file
|
||||
|
||||
## We always add the waku field as specified
|
||||
var enrInitFields = @[(WAKU_ENR_FIELD, @[flags.byte])]
|
||||
var enrInitFields = @[(CapabilitiesEnrField, @[flags.byte])]
|
||||
|
||||
## Add multiaddresses to ENR
|
||||
if multiaddrs.len > 0:
|
||||
|
@ -151,7 +151,7 @@ proc new*(T: type WakuDiscoveryV5,
|
|||
bootstrapNodes: seq[string],
|
||||
enrAutoUpdate = false,
|
||||
privateKey: keys.PrivateKey,
|
||||
flags: WakuEnrBitfield,
|
||||
flags: CapabilitiesBitfield,
|
||||
multiaddrs = newSeq[MultiAddress](),
|
||||
rng: ref HmacDrbgContext,
|
||||
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
||||
|
|
|
@ -19,14 +19,17 @@ import
|
|||
export enr, crypto, multiaddress, net
|
||||
|
||||
const
|
||||
MULTIADDR_ENR_FIELD* = "multiaddrs"
|
||||
WAKU_ENR_FIELD* = "waku2"
|
||||
MultiaddrEnrField* = "multiaddrs"
|
||||
CapabilitiesEnrField* = "waku2"
|
||||
|
||||
|
||||
## Capabilities
|
||||
|
||||
type
|
||||
## 8-bit flag field to indicate Waku capabilities.
|
||||
## Only the 4 LSBs are currently defined according
|
||||
## to RFC31 (https://rfc.vac.dev/spec/31/).
|
||||
WakuEnrBitfield* = uint8
|
||||
CapabilitiesBitfield* = distinct uint8
|
||||
|
||||
## See: https://rfc.vac.dev/spec/31/#waku2-enr-key
|
||||
## each enum numbers maps to a bit (where 0 is the LSB)
|
||||
|
@ -34,7 +37,59 @@ type
|
|||
Relay = 0,
|
||||
Store = 1,
|
||||
Filter = 2,
|
||||
Lightpush = 3,
|
||||
Lightpush = 3
|
||||
|
||||
|
||||
func init*(T: type CapabilitiesBitfield, lightpush, filter, store, relay: bool): T =
|
||||
## Creates an waku2 ENR flag bit field according to RFC 31 (https://rfc.vac.dev/spec/31/)
|
||||
var bitfield: uint8
|
||||
if relay: bitfield.setBit(0)
|
||||
if store: bitfield.setBit(1)
|
||||
if filter: bitfield.setBit(2)
|
||||
if lightpush: bitfield.setBit(3)
|
||||
CapabilitiesBitfield(bitfield)
|
||||
|
||||
func init*(T: type CapabilitiesBitfield, caps: varargs[Capabilities]): T =
|
||||
## Creates an waku2 ENR flag bit field according to RFC 31 (https://rfc.vac.dev/spec/31/)
|
||||
var bitfield: uint8
|
||||
for cap in caps:
|
||||
bitfield.setBit(ord(cap))
|
||||
CapabilitiesBitfield(bitfield)
|
||||
|
||||
converter toCapabilitiesBitfield*(field: uint8): CapabilitiesBitfield =
|
||||
CapabilitiesBitfield(field)
|
||||
|
||||
proc supportsCapability*(bitfield: CapabilitiesBitfield, cap: Capabilities): bool =
|
||||
testBit(bitfield.uint8, ord(cap))
|
||||
|
||||
func toCapabilities*(bitfield: CapabilitiesBitfield): seq[Capabilities] =
|
||||
toSeq(Capabilities.low..Capabilities.high).filterIt(supportsCapability(bitfield, it))
|
||||
|
||||
|
||||
func toFieldPair*(caps: CapabilitiesBitfield): FieldPair =
|
||||
toFieldPair(CapabilitiesEnrField, @[caps.uint8])
|
||||
|
||||
proc getCapabilitiesField*(r: Record): EnrResult[CapabilitiesBitfield] =
|
||||
let field = ?r.get(CapabilitiesEnrField, seq[uint8])
|
||||
ok(CapabilitiesBitfield(field[0]))
|
||||
|
||||
|
||||
proc supportsCapability*(r: Record, cap: Capabilities): bool =
|
||||
let bitfield = getCapabilitiesField(r)
|
||||
if bitfield.isErr():
|
||||
return false
|
||||
|
||||
bitfield.value.supportsCapability(cap)
|
||||
|
||||
proc getCapabilities*(r: Record): seq[Capabilities] =
|
||||
let bitfield = getCapabilitiesField(r)
|
||||
if bitfield.isErr():
|
||||
return @[]
|
||||
|
||||
bitfield.value.toCapabilities()
|
||||
|
||||
|
||||
## Multiaddress
|
||||
|
||||
func getRawField*(multiaddrs: seq[MultiAddress]): seq[byte] =
|
||||
var fieldRaw: seq[byte]
|
||||
|
@ -93,28 +148,6 @@ func readBytes(rawBytes: seq[byte], numBytes: int, pos: var int = 0): Result[seq
|
|||
|
||||
return ok(slicedSeq)
|
||||
|
||||
################
|
||||
# Public utils #
|
||||
################
|
||||
|
||||
func initWakuFlags*(lightpush, filter, store, relay: bool): WakuEnrBitfield =
|
||||
## Creates an waku2 ENR flag bit field according to RFC 31 (https://rfc.vac.dev/spec/31/)
|
||||
var v = 0b0000_0000'u8
|
||||
if lightpush: v.setBit(3)
|
||||
if filter: v.setBit(2)
|
||||
if store: v.setBit(1)
|
||||
if relay: v.setBit(0)
|
||||
|
||||
# TODO: With the changes in this PR, this can be refactored? Using the enum?
|
||||
# Perhaps refactor to:
|
||||
# WaKuEnr.enr.Record.init(..., capabilities=[Store, Lightpush])
|
||||
# WaKuEnr.enr.Record.init(..., capabilities=[Store, Lightpush, Relay, Filter])
|
||||
|
||||
# Safer also since we dont inject WakuEnrBitfield, and we let this package
|
||||
# handle the bits according to the capabilities
|
||||
|
||||
return v.WakuEnrBitfield
|
||||
|
||||
func toMultiAddresses*(multiaddrsField: seq[byte]): seq[MultiAddress] =
|
||||
## Parses a `multiaddrs` ENR field according to
|
||||
## https://rfc.vac.dev/spec/31/
|
||||
|
@ -147,11 +180,16 @@ func toMultiAddresses*(multiaddrsField: seq[byte]): seq[MultiAddress] =
|
|||
|
||||
return multiaddrs
|
||||
|
||||
|
||||
## ENR
|
||||
|
||||
func init*(T: type enr.Record,
|
||||
seqNum: uint64,
|
||||
privateKey: crypto.PrivateKey,
|
||||
enrIp: Option[ValidIpAddress],
|
||||
enrTcpPort, enrUdpPort: Option[Port],
|
||||
wakuFlags = none(WakuEnrBitfield),
|
||||
enrIp = none(ValidIpAddress),
|
||||
enrTcpPort = none(Port),
|
||||
enrUdpPort = none(Port),
|
||||
wakuFlags = none(CapabilitiesBitfield),
|
||||
multiaddrs: seq[MultiAddress] = @[]): T =
|
||||
|
||||
assert privateKey.scheme == PKScheme.Secp256k1
|
||||
|
@ -160,27 +198,22 @@ func init*(T: type enr.Record,
|
|||
var wakuEnrFields: seq[FieldPair]
|
||||
|
||||
# `waku2` field
|
||||
if wakuFlags.isSome:
|
||||
wakuEnrFields.add(toFieldPair(WAKU_ENR_FIELD, @[wakuFlags.get().byte]))
|
||||
if wakuFlags.isSome():
|
||||
wakuEnrFields.add(toFieldPair(wakuFlags.get()))
|
||||
|
||||
# `multiaddrs` field
|
||||
if multiaddrs.len > 0:
|
||||
wakuEnrFields.add(multiaddrs.stripPeerIds().toFieldPair)
|
||||
wakuEnrFields.add(multiaddrs.stripPeerIds().toFieldPair())
|
||||
|
||||
let
|
||||
rawPk = privateKey.getRawBytes().expect("Private key is valid")
|
||||
pk = keys.PrivateKey.fromRaw(rawPk).expect("Raw private key is of valid length")
|
||||
enr = enr.Record.init(1, pk,
|
||||
enrIp, enrTcpPort, enrUdpPort,
|
||||
wakuEnrFields).expect("Record within size limits")
|
||||
|
||||
return enr
|
||||
|
||||
proc supportsCapability*(r: Record, capability: Capabilities): bool =
|
||||
let enrCapabilities = r.get(WAKU_ENR_FIELD, seq[byte])
|
||||
if enrCapabilities.isOk():
|
||||
return testBit(enrCapabilities.get()[0], capability.ord)
|
||||
return false
|
||||
|
||||
proc getCapabilities*(r: Record): seq[Capabilities] =
|
||||
return toSeq(Capabilities.low..Capabilities.high).filterIt(r.supportsCapability(it))
|
||||
enr.Record.init(
|
||||
seqNum=seqNum,
|
||||
pk=pk,
|
||||
ip=enrIp,
|
||||
tcpPort=enrTcpPort,
|
||||
udpPort=enrUdpPort,
|
||||
extraFields=wakuEnrFields
|
||||
).expect("Record within size limits")
|
||||
|
|
Loading…
Reference in New Issue