on master help sign in
Simplify code and improve type safety: use ServerName for GossipEvent.server, generalize mergeByKey, remove redundant normalization in isBadServerName, remove dead containsColon helper
c0ca8aaiko
server.knot+13−20
@@ -54,7 +54,7 @@ type PollEvent = {id: MessageIdHex, eventType: PollEventType, payload: {encrypte
54
54
55type GossipEventType = Text where \s -> s == "online" || s == "offline"
55type GossipEventType = Text where \s -> s == "online" || s == "offline"
56
56
57−type GossipEvent = {eventType: GossipEventType, pubkey: PubkeyHex, server: Text, timestamp: Timestamp, ttl: Int<S>}
57+type GossipEvent = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, timestamp: Timestamp, ttl: Int<S>}
58
58
59type ValidGossipEntry = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
59type ValidGossipEntry = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
60
60
@@ -64,8 +64,8 @@ type PubkeyHex = Text where \s -> isValidHex s && not (tooLong s maxPubkeyLen) &
64type BlobHex = Text where \s -> isValidHex s && not (tooLong s maxBlobLen) && s == normalizeHex s
64type BlobHex = Text where \s -> isValidHex s && not (tooLong s maxBlobLen) && s == normalizeHex s
65type SignatureHex = Text where \s -> isValidHex s && not (tooLong s maxSignatureLen) && s == normalizeHex s
65type SignatureHex = Text where \s -> isValidHex s && not (tooLong s maxSignatureLen) && s == normalizeHex s
66type MessageIdHex = Text where \s -> isValidHex s && not (tooLong s maxMessageIdLen) && s == normalizeHex s
66type MessageIdHex = Text where \s -> isValidHex s && not (tooLong s maxMessageIdLen) && s == normalizeHex s
67−type ServerName = Text where \s -> not (tooLong s maxServerNameLen) && not (isBadServerName s) && s == normalizeServerName s
67+type ServerName = Text where \s -> not (tooLong s maxServerNameLen) && s == normalizeServerName s && not (isBadServerName s)
68−type OptionalServerName = Text where \s -> s == "" || (not (tooLong s maxServerNameLen) && not (isBadServerName s) && s == normalizeServerName s)
68+type OptionalServerName = Text where \s -> s == "" || (not (tooLong s maxServerNameLen) && s == normalizeServerName s && not (isBadServerName s))
69
69
70type Timestamp = Int<Ms>
70type Timestamp = Int<Ms>
71
71
@@ -224,8 +224,6 @@ isCgnatRange = \s ->
224 then True {}
224 then True {}
225 else False {}
225 else False {}
226
226
227−containsColon = \s -> contains ":" s
228−
229containsMultipleColons = \s -> count (do c <- chars s; where c == ":"; yield c) > 1
227containsMultipleColons = \s -> count (do c <- chars s; where c == ":"; yield c) > 1
230
228
231hasOctalOctet = \s ->
229hasOctalOctet = \s ->
@@ -298,8 +296,7 @@ isHighOctetPrefix = \sn ->
298matchesHostname = \sn name nameLen ->
296matchesHostname = \sn name nameLen ->
299 take nameLen sn == name && (drop nameLen sn == "" || take 1 (drop nameLen sn) == ":")
297 take nameLen sn == name && (drop nameLen sn == "" || take 1 (drop nameLen sn) == ":")
300
298
301−isBadServerName = \s ->
299+isBadServerName = \sn ->
302− let sn = toLower (stripTrailingDot s) in
303 sn == ""
300 sn == ""
304 || take 1 sn == "."
301 || take 1 sn == "."
305 || take 1 sn == ":"
302 || take 1 sn == ":"
@@ -449,15 +446,15 @@ collectPeerServers = \items getServer ->
449
446
450samePubkeyServer = \a b -> a.pubkey == b.pubkey && a.server == b.server
447samePubkeyServer = \a b -> a.pubkey == b.pubkey && a.server == b.server
451
448
452−mergeByKey = \sameKey initial items ->
449+mergeByKey = \sameKey getFreshness initial items ->
453 fold (\acc e ->
450 fold (\acc e ->
454− if any acc (\a -> sameKey a e && a.expiresAt >= e.expiresAt)
451+ if any acc (\a -> sameKey a e && getFreshness a >= getFreshness e)
455 then acc
452 then acc
456 else union
453 else union
457 (do a <- acc; where not (sameKey a e); yield a)
454 (do a <- acc; where not (sameKey a e); yield a)
458 [e]) initial items
455 [e]) initial items
459
456
460−mergeByPubkeyServer = mergeByKey samePubkeyServer
457+mergeByPubkeyServer = mergeByKey samePubkeyServer (\x -> x.expiresAt)
461
458
462removeOffline = \presenceSet offlineOnlyKeys trustedOffline t ->
459removeOffline = \presenceSet offlineOnlyKeys trustedOffline t ->
463 diff presenceSet (do
460 diff presenceSet (do
@@ -476,13 +473,11 @@ countMessagesFor = \messages toKey t ->
476validGossipEvents : [GossipEvent] -> Timestamp -> [ValidGossipEntry]
473validGossipEvents : [GossipEvent] -> Timestamp -> [ValidGossipEntry]
477validGossipEvents = \events t -> do
474validGossipEvents = \events t -> do
478 e <- events
475 e <- events
479− where not (tooLong e.server maxServerNameLen) && not (isBadServerName e.server)
480− let server = normalizeServerName e.server
481− where server != serverHostN && e.timestamp <= t + clockSkewTolerance
476+ where e.server != serverHostN && e.timestamp <= t + clockSkewTolerance
482 let ttl = clampTtl e.ttl
477 let ttl = clampTtl e.ttl
483 let expiresAt = e.timestamp + ttl * 1000
478 let expiresAt = e.timestamp + ttl * 1000
484 where expiresAt > t
479 where expiresAt > t
485− yield {eventType: e.eventType, pubkey: e.pubkey, server: server, expiresAt: expiresAt, timestamp: e.timestamp, ttl: ttl}
480+ yield {eventType: e.eventType, pubkey: e.pubkey, server: e.server, expiresAt: expiresAt, timestamp: e.timestamp, ttl: ttl}
486
481
487sendToEach : [ServerName] -> (ServerName -> (a {})) -> a {}
482sendToEach : [ServerName] -> (ServerName -> (a {})) -> a {}
488sendToEach = \servers action ->
483sendToEach = \servers action ->
@@ -556,12 +551,10 @@ sendBatchedGossip = \peerServers allEvents hops ->
556
551
557broadcastOfflineGossip = \t peerServers expiredLocal ->
552broadcastOfflineGossip = \t peerServers expiredLocal ->
558 when (federationEnabled && count peerServers > 0 && count expiredLocal > 0) (do
553 when (federationEnabled && count peerServers > 0 && count expiredLocal > 0) (do
559− let gossipEvents = do
560− e <- mergeByKey (\a b -> a.pubkey == b.pubkey) [] (do
554+ let gossipEvents = mergeByKey (\a b -> a.pubkey == b.pubkey) (\x -> x.timestamp) [] (do
561− p <- expiredLocal
555+ p <- expiredLocal
562− let ttl = clamp offlineGossipMinTtl maxPresenceTtl ((p.expiresAt - p.timestamp) / 1000)
556+ let ttl = clamp offlineGossipMinTtl maxPresenceTtl ((p.expiresAt - p.timestamp) / 1000)
563− yield {pubkey: p.pubkey, ttl: ttl, expiresAt: p.expiresAt})
564− yield {eventType: "offline", pubkey: e.pubkey, server: serverHostN, timestamp: e.expiresAt, ttl: e.ttl}
557+ yield {eventType: "offline", pubkey: p.pubkey, server: serverHostN, timestamp: p.expiresAt, ttl: ttl})
565 sendBatchedGossip peerServers gossipEvents 2)
558 sendBatchedGossip peerServers gossipEvents 2)
566
559
567forkBroadcastOffline = \t result ->
560forkBroadcastOffline = \t result ->