on master help sign in
Simplify code and improve type safety: add eventType to ValidGossipEntry, eliminate redundant filtering and scans
b86f18aiko
server.knot+31−52
@@ -49,7 +49,7 @@ type GossipEventType = Text where \s -> s == "online" || s == "offline"
49
49
50type GossipEvent = {eventType: GossipEventType, pubkey: Text, server: Text, timestamp: Timestamp, ttl: Int<S>}
50type GossipEvent = {eventType: GossipEventType, pubkey: Text, server: Text, timestamp: Timestamp, ttl: Int<S>}
51
51
52−type ValidGossipEntry = {pubkey: PubkeyHex, server: Text, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
52+type ValidGossipEntry = {eventType: GossipEventType, pubkey: PubkeyHex, server: Text, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
53
53
54type MessageStatus = Text where \s -> s == "unauthorized" || s == "rejected" || s == "delivered" || s == "federated" || s == "queued"
54type MessageStatus = Text where \s -> s == "unauthorized" || s == "rejected" || s == "delivered" || s == "federated" || s == "queued"
55
55
@@ -495,22 +495,20 @@ countMessagesFor = \messages toKey t ->
495 yield m)
495 yield m)
496
496
497
497
498−validGossipEvents : [GossipEvent] -> Bool -> Timestamp -> GossipEventType -> [ValidGossipEntry]
498+validGossipEvents : [GossipEvent] -> Timestamp -> GossipEventType -> [ValidGossipEntry]
499−validGossipEvents = \events validRequest t eventType ->
499+validGossipEvents = \events t eventType -> do
500− if not validRequest then []
501− else do
502− e <- events
500+ e <- events
503− where e.eventType == eventType
501+ where e.eventType == eventType
504− where not (e.server == "")
502+ where not (e.server == "")
505− where not (e.pubkey == "")
503+ where not (e.pubkey == "")
506− where not (tooLong e.pubkey maxPubkeyLen)
504+ where not (tooLong e.pubkey maxPubkeyLen)
507− where not (tooLong e.server maxServerNameLen)
505+ where not (tooLong e.server maxServerNameLen)
508− where not (isBadServerName e.server)
506+ where not (isBadServerName e.server)
509− where isValidHex e.pubkey
507+ where isValidHex e.pubkey
510− where not (normalizeServerName e.server == serverHostN)
508+ where not (normalizeServerName e.server == serverHostN)
511− where e.timestamp <= t + clockSkewTolerance
509+ where e.timestamp <= t + clockSkewTolerance
512− where e.timestamp + (clampTtl e.ttl) * 1000 > t
510+ where e.timestamp + (clampTtl e.ttl) * 1000 > t
513− yield {pubkey: normalizeHex e.pubkey, server: normalizeServerName e.server, expiresAt: e.timestamp + (clampTtl e.ttl) * 1000, timestamp: e.timestamp, ttl: clampTtl e.ttl}
511+ yield {eventType: eventType, pubkey: normalizeHex e.pubkey, server: normalizeServerName e.server, expiresAt: e.timestamp + (clampTtl e.ttl) * 1000, timestamp: e.timestamp, ttl: clampTtl e.ttl}
514
512
515sendToEach : [Text] -> (Text -> (a {})) -> a {}
513sendToEach : [Text] -> (Text -> (a {})) -> a {}
516sendToEach = \servers action ->
514sendToEach = \servers action ->
@@ -660,10 +658,9 @@ pruneAndRetry = \t -> do
660 set *lastPrunedAt = t
658 set *lastPrunedAt = t
661 pr <- pruneExpired t
659 pr <- pruneExpired t
662 forwards <- *forwards
660 forwards <- *forwards
663− let pendingForwards = forwards
664 ackedIds <- *ackedIds
661 ackedIds <- *ackedIds
665 let pendingAcks = do a <- ackedIds; where isFederatedOrigin a.originServer; yield a
662 let pendingAcks = do a <- ackedIds; where isFederatedOrigin a.originServer; yield a
666− yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: pendingForwards, pendingAcks: pendingAcks}
663+ yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: forwards, pendingAcks: pendingAcks}
667 broadcastOfflineGossip t result.peerServers result.expiredLocal
664 broadcastOfflineGossip t result.peerServers result.expiredLocal
668 if federationEnabled && count result.pendingForwards > 0
665 if federationEnabled && count result.pendingForwards > 0
669 then retryPendingForwards result.pendingForwards
666 then retryPendingForwards result.pendingForwards
@@ -836,15 +833,11 @@ serve = \req -> case req of
836 [{messageId: msgId, toKey: to, fromKey: fromKey,
833 [{messageId: msgId, toKey: to, fromKey: fromKey,
837 encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: "", receivedAt: seqTs}]
834 encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: "", receivedAt: seqTs}]
838 else messages
835 else messages
839− let localOnline = authorized && any presence (\p -> p.pubkey == to && p.server == serverHostN && p.expiresAt > t)
840− let remoteServers = if authorized
836+ let toPresence = if authorized
841− then do
842− p <- presence
843− where p.pubkey == to
844− where not (p.server == serverHostN)
845− where p.expiresAt > t
837+ then do p <- presence; where p.pubkey == to; where p.expiresAt > t; yield p
846− yield p.server
847 else []
838 else []
839+ let localOnline = any toPresence (\p -> p.server == serverHostN)
840+ let remoteServers = do p <- toPresence; where not (p.server == serverHostN); yield p.server
848 forwards <- *forwards
841 forwards <- *forwards
849 let forwardsAtCapacity = count forwards >= maxForwardsEntries
842 let forwardsAtCapacity = count forwards >= maxForwardsEntries
850 let status = if not authorized then "unauthorized"
843 let status = if not authorized then "unauthorized"
@@ -904,25 +897,17 @@ serve = \req -> case req of
904 let evictedEntries = if excessCount <= 0 then []
897 let evictedEntries = if excessCount <= 0 then []
905 else diff combinedAckedIds afterEviction
898 else diff combinedAckedIds afterEviction
906 set *ackedIds = afterEviction
899 set *ackedIds = afterEviction
907− yield {ok: auth.authorized, ackedMessages: ackedMessages, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, evictedEntries: evictedEntries}
900+ yield {ok: auth.authorized, pendingAcks: ackedFederated, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, evictedEntries: evictedEntries}
908− let fedMessages = do
909− m <- result.ackedMessages
910− where isFederatedOrigin m.originServer
911− yield m
912− let originServers = collectPeerServers fedMessages (\m -> m.originServer)
901+ let originServers = collectPeerServers result.pendingAcks (\a -> a.originServer)
913 fork (do
902 fork (do
914 if result.ok
903 if result.ok
915 then do
904 then do
916 if count originServers > 0 && federationEnabled
905 if count originServers > 0 && federationEnabled
917− then do
918− let pendingAcks = do
919− m <- fedMessages
920− yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
921− sendAcksAndClean pendingAcks originServers
906+ then sendAcksAndClean result.pendingAcks originServers
922 else yield {}
907 else yield {}
923 let evictedToRetry = do
908 let evictedToRetry = do
924 a <- result.evictedEntries
909 a <- result.evictedEntries
925− where none fedMessages (\m -> m.messageId == a.messageId && m.toKey == a.toKey)
910+ where none result.pendingAcks (\a2 -> a2.messageId == a.messageId && a2.toKey == a.toKey)
926 yield a
911 yield a
927 if count evictedToRetry > 0 && federationEnabled
912 if count evictedToRetry > 0 && federationEnabled
928 then do
913 then do
@@ -982,19 +967,15 @@ serve = \req -> case req of
982 let cappedHops = if hopsRemaining > 5 then 5 else hopsRemaining
967 let cappedHops = if hopsRemaining > 5 then 5 else hopsRemaining
983 let fromServer = normalizeServerName fromServer
968 let fromServer = normalizeServerName fromServer
984 let validRequest = authorized && cappedHops >= 1 && not (fromServer == serverHostN) && count events <= maxGossipEvents
969 let validRequest = authorized && cappedHops >= 1 && not (fromServer == serverHostN) && count events <= maxGossipEvents
985− let onlineEntries = validGossipEvents events validRequest t "online"
970+ let onlineEntries = if validRequest then validGossipEvents events t "online" else []
986− let offlineEntries = validGossipEvents events validRequest t "offline"
971+ let offlineEntries = if validRequest then validGossipEvents events t "offline" else []
987 let filteredOnline = do
972 let filteredOnline = do
988 e <- onlineEntries
973 e <- onlineEntries
989 where none offlineEntries (\o -> o.server == fromServer && samePubkeyServer o e && o.timestamp > e.timestamp)
974 where none offlineEntries (\o -> o.server == fromServer && samePubkeyServer o e && o.timestamp > e.timestamp)
990 yield e
975 yield e
991− let affectedKeys = union
976+ let affectedKeys = do
992− (do
993− e <- onlineEntries
994− yield {pubkey: e.pubkey, server: e.server})
995− (do
996− e <- offlineEntries
977+ e <- union onlineEntries offlineEntries
997− yield {pubkey: e.pubkey, server: e.server})
978+ yield {pubkey: e.pubkey, server: e.server}
998 let deduped = mergeByPubkeyServer [] filteredOnline
979 let deduped = mergeByPubkeyServer [] filteredOnline
999 gossipResult <- atomic do
980 gossipResult <- atomic do
1000 pr <- maybePrune t
981 pr <- maybePrune t
@@ -1065,11 +1046,9 @@ serve = \req -> case req of
1065 where none onlineEntries (\o -> samePubkeyServer o e && o.timestamp > e.timestamp)
1046 where none onlineEntries (\o -> samePubkeyServer o e && o.timestamp > e.timestamp)
1066 yield e
1047 yield e
1067 let effectiveEvents = do
1048 let effectiveEvents = do
1068− e <- union
1049+ e <- union filteredOnline filteredOffline
1069− (do e <- filteredOnline; yield {eventType: "online", pubkey: e.pubkey, server: e.server, timestamp: e.timestamp, ttl: e.ttl})
1070− (do e <- filteredOffline; yield {eventType: "offline", pubkey: e.pubkey, server: e.server, timestamp: e.timestamp, ttl: e.ttl})
1071 where any gossipResult.appliedKeys (\a -> samePubkeyServer a e)
1050 where any gossipResult.appliedKeys (\a -> samePubkeyServer a e)
1072− yield e
1051+ yield {eventType: e.eventType, pubkey: e.pubkey, server: e.server, timestamp: e.timestamp, ttl: e.ttl}
1073 if not gossipResult.withinCapacity
1052 if not gossipResult.withinCapacity
1074 then println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer)
1053 then println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer)
1075 else yield {}
1054 else yield {}