mirror of
https://github.com/vacp2p/nim-libp2p.git
synced 2026-01-09 02:38:19 -05:00
test(rendezvous): Registration TTL tests (#1655)
This commit is contained in:
committed by
GitHub
parent
6e5274487e
commit
d2eaf07960
@@ -35,7 +35,10 @@ declareGauge(libp2p_rendezvous_namespaces, "number of registered namespaces")
|
||||
|
||||
const
|
||||
RendezVousCodec* = "/rendezvous/1.0.0"
|
||||
# Default minimum TTL per libp2p spec
|
||||
MinimumDuration* = 2.hours
|
||||
# Lower validation limit to accommodate Waku requirements
|
||||
MinimumAcceptedDuration = 1.minutes
|
||||
MaximumDuration = 72.hours
|
||||
MaximumMessageLen = 1 shl 22 # 4MB
|
||||
MinimumNamespaceLen = 1
|
||||
@@ -69,7 +72,7 @@ type
|
||||
Register = object
|
||||
ns: string
|
||||
signedPeerRecord: seq[byte]
|
||||
ttl: Opt[uint64] # in seconds
|
||||
ttl*: Opt[uint64] # in seconds
|
||||
|
||||
RegisterResponse = object
|
||||
status: ResponseStatus
|
||||
@@ -312,7 +315,7 @@ type
|
||||
RegisteredData = object
|
||||
expiration*: Moment
|
||||
peerId*: PeerId
|
||||
data: Register
|
||||
data*: Register
|
||||
|
||||
RendezVous* = ref object of LPProtocol
|
||||
# Registered needs to be an offsetted sequence
|
||||
@@ -324,7 +327,7 @@ type
|
||||
namespaces*: Table[string, seq[int]]
|
||||
rng: ref HmacDrbgContext
|
||||
salt: string
|
||||
defaultDT: Moment
|
||||
expiredDT: Moment
|
||||
registerDeletionLoop: Future[void]
|
||||
#registerEvent: AsyncEvent # TODO: to raise during the heartbeat
|
||||
# + make the heartbeat sleep duration "smarter"
|
||||
@@ -409,7 +412,7 @@ proc save(
|
||||
if rdv.registered[index].peerId == peerId:
|
||||
if update == false:
|
||||
return
|
||||
rdv.registered[index].expiration = rdv.defaultDT
|
||||
rdv.registered[index].expiration = rdv.expiredDT
|
||||
rdv.registered.add(
|
||||
RegisteredData(
|
||||
peerId: peerId,
|
||||
@@ -446,7 +449,7 @@ proc unregister(rdv: RendezVous, conn: Connection, u: Unregister) =
|
||||
try:
|
||||
for index in rdv.namespaces[nsSalted]:
|
||||
if rdv.registered[index].peerId == conn.peerId:
|
||||
rdv.registered[index].expiration = rdv.defaultDT
|
||||
rdv.registered[index].expiration = rdv.expiredDT
|
||||
libp2p_rendezvous_registered.dec()
|
||||
except KeyError:
|
||||
return
|
||||
@@ -689,7 +692,7 @@ proc unsubscribeLocally*(rdv: RendezVous, ns: string) =
|
||||
try:
|
||||
for index in rdv.namespaces[nsSalted]:
|
||||
if rdv.registered[index].peerId == rdv.switch.peerInfo.peerId:
|
||||
rdv.registered[index].expiration = rdv.defaultDT
|
||||
rdv.registered[index].expiration = rdv.expiredDT
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
@@ -744,10 +747,10 @@ proc new*(
|
||||
minDuration = MinimumDuration,
|
||||
maxDuration = MaximumDuration,
|
||||
): T {.raises: [RendezVousError].} =
|
||||
if minDuration < 1.minutes:
|
||||
if minDuration < MinimumAcceptedDuration:
|
||||
raise newException(RendezVousError, "TTL too short: 1 minute minimum")
|
||||
|
||||
if maxDuration > 72.hours:
|
||||
if maxDuration > MaximumDuration:
|
||||
raise newException(RendezVousError, "TTL too long: 72 hours maximum")
|
||||
|
||||
if minDuration >= maxDuration:
|
||||
@@ -761,7 +764,7 @@ proc new*(
|
||||
rng: rng,
|
||||
salt: string.fromBytes(generateBytes(rng[], 8)),
|
||||
registered: initOffsettedSeq[RegisteredData](),
|
||||
defaultDT: Moment.now() - 1.days,
|
||||
expiredDT: Moment.now() - 1.days,
|
||||
#registerEvent: newAsyncEvent(),
|
||||
sema: newAsyncSemaphore(SemaphoreDefaultSize),
|
||||
minDuration: minDuration,
|
||||
|
||||
@@ -342,6 +342,88 @@ suite "RendezVous":
|
||||
|
||||
check (await peerRdvs[0].request(Opt.some(namespace))).len == 3
|
||||
|
||||
asyncTest "Peer default TTL is saved when advertised":
|
||||
let (rendezvousNode, peerNodes, peerRdvs, rendezvousRdv) =
|
||||
setupRendezvousNodeWithPeerNodes(1)
|
||||
(rendezvousNode & peerNodes).startAndDeferStop()
|
||||
|
||||
await connectNodes(peerNodes[0], rendezvousNode)
|
||||
|
||||
const namespace = "foo"
|
||||
let timeBefore = Moment.now()
|
||||
await peerRdvs[0].advertise(namespace)
|
||||
let timeAfter = Moment.now()
|
||||
|
||||
# expiration within [timeBefore + 2hours, timeAfter + 2hours]
|
||||
check:
|
||||
# Peer Node side
|
||||
peerRdvs[0].registered.s[0].data.ttl.get == MinimumDuration.seconds.uint64
|
||||
peerRdvs[0].registered.s[0].expiration >= timeBefore + MinimumDuration
|
||||
peerRdvs[0].registered.s[0].expiration <= timeAfter + MinimumDuration
|
||||
# Rendezvous Node side
|
||||
rendezvousRdv.registered.s[0].data.ttl.get == MinimumDuration.seconds.uint64
|
||||
rendezvousRdv.registered.s[0].expiration >= timeBefore + MinimumDuration
|
||||
rendezvousRdv.registered.s[0].expiration <= timeAfter + MinimumDuration
|
||||
|
||||
asyncTest "Peer TTL is saved when advertised with TTL":
|
||||
let (rendezvousNode, peerNodes, peerRdvs, rendezvousRdv) =
|
||||
setupRendezvousNodeWithPeerNodes(1)
|
||||
(rendezvousNode & peerNodes).startAndDeferStop()
|
||||
|
||||
await connectNodes(peerNodes[0], rendezvousNode)
|
||||
|
||||
const
|
||||
namespace = "foo"
|
||||
ttl = 3.hours
|
||||
let timeBefore = Moment.now()
|
||||
await peerRdvs[0].advertise(namespace, ttl)
|
||||
let timeAfter = Moment.now()
|
||||
|
||||
# expiration within [timeBefore + ttl, timeAfter + ttl]
|
||||
check:
|
||||
# Peer Node side
|
||||
peerRdvs[0].registered.s[0].data.ttl.get == ttl.seconds.uint64
|
||||
peerRdvs[0].registered.s[0].expiration >= timeBefore + ttl
|
||||
peerRdvs[0].registered.s[0].expiration <= timeAfter + ttl
|
||||
# Rendezvous Node side
|
||||
rendezvousRdv.registered.s[0].data.ttl.get == ttl.seconds.uint64
|
||||
rendezvousRdv.registered.s[0].expiration >= timeBefore + ttl
|
||||
rendezvousRdv.registered.s[0].expiration <= timeAfter + ttl
|
||||
|
||||
asyncTest "Peer can reregister to update its TTL before previous TTL expires":
|
||||
let (rendezvousNode, peerNodes, peerRdvs, rendezvousRdv) =
|
||||
setupRendezvousNodeWithPeerNodes(1)
|
||||
(rendezvousNode & peerNodes).startAndDeferStop()
|
||||
|
||||
await connectNodes(peerNodes[0], rendezvousNode)
|
||||
|
||||
const namespace = "foo"
|
||||
let now = Moment.now()
|
||||
|
||||
await peerRdvs[0].advertise(namespace)
|
||||
check:
|
||||
# Peer Node side
|
||||
peerRdvs[0].registered.s.len == 1
|
||||
peerRdvs[0].registered.s[0].expiration > now
|
||||
# Rendezvous Node side
|
||||
rendezvousRdv.registered.s.len == 1
|
||||
rendezvousRdv.registered.s[0].expiration > now
|
||||
|
||||
await peerRdvs[0].advertise(namespace, 5.hours)
|
||||
check:
|
||||
# Added 2nd registration
|
||||
# Updated expiration of the 1st one to the past
|
||||
# Will be deleted on deletion heartbeat
|
||||
# Peer Node side
|
||||
peerRdvs[0].registered.s.len == 2
|
||||
peerRdvs[0].registered.s[0].expiration < now
|
||||
# Rendezvous Node side
|
||||
rendezvousRdv.registered.s.len == 2
|
||||
rendezvousRdv.registered.s[0].expiration < now
|
||||
|
||||
# Returns only one record
|
||||
check (await peerRdvs[0].request(Opt.some(namespace))).len == 1
|
||||
|
||||
asyncTest "Various local error":
|
||||
let rdv = RendezVous.new(minDuration = 1.minutes, maxDuration = 72.hours)
|
||||
expect AdvertiseError:
|
||||
|
||||
Reference in New Issue
Block a user