@@ -64,6 +64,7 @@ impl ToJSON PollEventType where
6464type PollEvent = {id: MessageIdHex, eventType: PollEventType, payload: {encryptedBlob: BlobHex, fromKey: PubkeyHex, timestamp: Timestamp, toKey: PubkeyHex}}
6565
6666data GossipEventType = GossipOnline {} | GossipOffline {} | GossipUnknown {}
67+data ValidGossipType = ValidOnline {} | ValidOffline {}
6768
6869impl ToJSON GossipEventType where
6970 toJson et = toJson (case et of
@@ -78,13 +79,13 @@ impl FromJSON GossipEventType where
7879 else if s == "offline" then GossipOffline {}
7980 else GossipUnknown {}
8081
81−isKnownEvent = \et -> case et of GossipUnknown {} -> False {}; _ -> True {}
82−isOnlineEvent = \et -> case et of GossipOnline {} -> True {}; _ -> False {}
83−isOfflineEvent = \et -> case et of GossipOffline {} -> True {}; _ -> False {}
82+isOnlineEvent = \et -> case et of ValidOnline {} -> True {}; _ -> False {}
83+isOfflineEvent = \et -> case et of ValidOffline {} -> True {}; _ -> False {}
84+toGossipEventType = \et -> case et of ValidOnline {} -> GossipOnline {}; ValidOffline {} -> GossipOffline {}
8485
8586type GossipEvent = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, timestamp: Timestamp, ttl: Int<S>}
8687
87−type ValidGossipEntry = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
88+type ValidGossipEntry = {eventType: ValidGossipType, pubkey: PubkeyHex, server: ServerName, expiresAt: Timestamp, timestamp: Timestamp, ttl: Int<S>}
8889
8990data MessageStatus = MsDelivered {} | MsFederated {} | MsQueued {} | MsUnauthorized {} | MsRejected {}
9091
@@ -514,16 +515,21 @@ capGossipPresence = \args ->
514515countMessagesFor = \messages toKey t ->
515516 count (do m <- messages; where m.toKey == toKey && m.receivedAt >= t - messageMaxAge; yield m)
516517
518+hasMessage = \mid toKey items -> any items (\x -> x.messageId == mid && x.toKey == toKey)
519+
517520
518521validGossipEvents : [GossipEvent] -> Timestamp -> [ValidGossipEntry]
519522validGossipEvents = \events t -> do
520523 e <- events
521− where isKnownEvent e.eventType
524+ validType <- case e.eventType of
525+ GossipOnline {} -> [ValidOnline {}]
526+ GossipOffline {} -> [ValidOffline {}]
527+ _ -> []
522528 where e.server != serverHostN && e.timestamp <= t + clockSkewTolerance
523529 let ttl = clampTtl e.ttl
524530 let expiresAt = e.timestamp + ttl * 1000
525531 where expiresAt > t
526− yield {eventType: e.eventType, pubkey: e.pubkey, server: e.server, expiresAt: expiresAt, timestamp: e.timestamp, ttl: ttl}
532+ yield {eventType: validType, pubkey: e.pubkey, server: e.server, expiresAt: expiresAt, timestamp: e.timestamp, ttl: ttl}
527533
528534sendToEach : [ServerName] -> (ServerName -> (a {})) -> a {}
529535sendToEach = \servers action ->
@@ -659,7 +665,7 @@ sendBatchedAcksToServer = \serverAcks server ->
659665 ackedIds <- *ackedIds
660666 set *ackedIds = do
661667 a <- ackedIds
662− where not (a.originServer == server && any batch (\sa -> sa.messageId == a.messageId && sa.toKey == a.toKey))
668+ where not (a.originServer == server && hasMessage a.messageId a.toKey batch)
663669 yield a))
664670
665671sendAcksAndClean : [{messageId: MessageIdHex, toKey: PubkeyHex, originServer: ServerName, | a}] -> IO {network} {}
@@ -671,7 +677,7 @@ sendAcksAndClean = \pendingAcks ->
671677retryEvictedAcks = \evictedEntries pendingAcks ->
672678 let evictedToRetry = do
673679 a <- evictedEntries
674− where none pendingAcks (\a2 -> a2.messageId == a.messageId && a2.toKey == a.toKey)
680+ where not (hasMessage a.messageId a.toKey pendingAcks)
675681 yield a
676682 in do
677683 let evictedOriginServers = collectPeerServers evictedToRetry (\a -> a.originServer)
@@ -971,7 +977,7 @@ serve = \req -> case req of
971977 let effectiveEvents = do
972978 e <- union filteredOnline filteredOffline
973979 where any gossipResult.appliedKeys (\a -> samePubkeyServer a e)
974− yield {eventType: e.eventType, pubkey: e.pubkey, server: e.server, timestamp: e.timestamp, ttl: e.ttl}
980+ yield {eventType: toGossipEventType e.eventType, pubkey: e.pubkey, server: e.server, timestamp: e.timestamp, ttl: e.ttl}
975981 when (not gossipResult.withinCapacity)
976982 (println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer))
977983 fork (do
@@ -995,8 +1001,7 @@ serve = \req -> case req of
9951001 pr <- maybePrune t
9961002 messages <- *messages
9971003 ackedIds <- *ackedIds
998− if any messages (\m -> m.messageId == messageId && m.toKey == toKey)
999− || any ackedIds (\a -> a.messageId == messageId && a.toKey == toKey)
1004+ if hasMessage messageId toKey messages || hasMessage messageId toKey ackedIds
10001005 then yield {pr: pr, forward: ForwardDuplicate {}}
10011006 else if countMessagesFor messages toKey t >= maxMessagesPerRecipient
10021007 then yield {pr: pr, forward: ForwardFull {}}