on master help sign in
Improve type safety: add ValidGossipType, extract hasMessage predicate
a348d96iko
server.knot+16−11
@@ -64,6 +64,7 @@ impl ToJSON PollEventType where
64type PollEvent = {id: MessageIdHex, eventType: PollEventType, payload: {encryptedBlob: BlobHex, fromKey: PubkeyHex, timestamp: Timestamp, toKey: PubkeyHex}}
64type PollEvent = {id: MessageIdHex, eventType: PollEventType, payload: {encryptedBlob: BlobHex, fromKey: PubkeyHex, timestamp: Timestamp, toKey: PubkeyHex}}
65
65
66data GossipEventType = GossipOnline {} | GossipOffline {} | GossipUnknown {}
66data GossipEventType = GossipOnline {} | GossipOffline {} | GossipUnknown {}
67+data ValidGossipType = ValidOnline {} | ValidOffline {}
67
68
68impl ToJSON GossipEventType where
69impl ToJSON GossipEventType where
69 toJson et = toJson (case et of
70 toJson et = toJson (case et of
@@ -78,13 +79,13 @@ impl FromJSON GossipEventType where
78 else if s == "offline" then GossipOffline {}
79 else if s == "offline" then GossipOffline {}
79 else GossipUnknown {}
80 else GossipUnknown {}
80
81
81−isKnownEvent = \et -> case et of GossipUnknown {} -> False {}; _ -> True {}
82−isOnlineEvent = \et -> case et of GossipOnline {} -> True {}; _ -> False {}
82+isOnlineEvent = \et -> case et of ValidOnline {} -> True {}; _ -> False {}
83−isOfflineEvent = \et -> case et of GossipOffline {} -> True {}; _ -> False {}
83+isOfflineEvent = \et -> case et of ValidOffline {} -> True {}; _ -> False {}
84+toGossipEventType = \et -> case et of ValidOnline {} -> GossipOnline {}; ValidOffline {} -> GossipOffline {}
84
85
85type GossipEvent = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, timestamp: Timestamp, ttl: Int<S>}
86type GossipEvent = {eventType: GossipEventType, pubkey: PubkeyHex, server: ServerName, timestamp: Timestamp, ttl: Int<S>}
86
87
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>}
88
89
89data MessageStatus = MsDelivered {} | MsFederated {} | MsQueued {} | MsUnauthorized {} | MsRejected {}
90data MessageStatus = MsDelivered {} | MsFederated {} | MsQueued {} | MsUnauthorized {} | MsRejected {}
90
91
@@ -514,16 +515,21 @@ capGossipPresence = \args ->
514countMessagesFor = \messages toKey t ->
515countMessagesFor = \messages toKey t ->
515 count (do m <- messages; where m.toKey == toKey && m.receivedAt >= t - messageMaxAge; yield m)
516 count (do m <- messages; where m.toKey == toKey && m.receivedAt >= t - messageMaxAge; yield m)
516
517
518+hasMessage = \mid toKey items -> any items (\x -> x.messageId == mid && x.toKey == toKey)
519+
517
520
518validGossipEvents : [GossipEvent] -> Timestamp -> [ValidGossipEntry]
521validGossipEvents : [GossipEvent] -> Timestamp -> [ValidGossipEntry]
519validGossipEvents = \events t -> do
522validGossipEvents = \events t -> do
520 e <- events
523 e <- events
521− where isKnownEvent e.eventType
524+ validType <- case e.eventType of
525+ GossipOnline {} -> [ValidOnline {}]
526+ GossipOffline {} -> [ValidOffline {}]
527+ _ -> []
522 where e.server != serverHostN && e.timestamp <= t + clockSkewTolerance
528 where e.server != serverHostN && e.timestamp <= t + clockSkewTolerance
523 let ttl = clampTtl e.ttl
529 let ttl = clampTtl e.ttl
524 let expiresAt = e.timestamp + ttl * 1000
530 let expiresAt = e.timestamp + ttl * 1000
525 where expiresAt > t
531 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}
527
533
528sendToEach : [ServerName] -> (ServerName -> (a {})) -> a {}
534sendToEach : [ServerName] -> (ServerName -> (a {})) -> a {}
529sendToEach = \servers action ->
535sendToEach = \servers action ->
@@ -659,7 +665,7 @@ sendBatchedAcksToServer = \serverAcks server ->
659 ackedIds <- *ackedIds
665 ackedIds <- *ackedIds
660 set *ackedIds = do
666 set *ackedIds = do
661 a <- ackedIds
667 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)
663 yield a))
669 yield a))
664
670
665sendAcksAndClean : [{messageId: MessageIdHex, toKey: PubkeyHex, originServer: ServerName, | a}] -> IO {network} {}
671sendAcksAndClean : [{messageId: MessageIdHex, toKey: PubkeyHex, originServer: ServerName, | a}] -> IO {network} {}
@@ -671,7 +677,7 @@ sendAcksAndClean = \pendingAcks ->
671retryEvictedAcks = \evictedEntries pendingAcks ->
677retryEvictedAcks = \evictedEntries pendingAcks ->
672 let evictedToRetry = do
678 let evictedToRetry = do
673 a <- evictedEntries
679 a <- evictedEntries
674− where none pendingAcks (\a2 -> a2.messageId == a.messageId && a2.toKey == a.toKey)
680+ where not (hasMessage a.messageId a.toKey pendingAcks)
675 yield a
681 yield a
676 in do
682 in do
677 let evictedOriginServers = collectPeerServers evictedToRetry (\a -> a.originServer)
683 let evictedOriginServers = collectPeerServers evictedToRetry (\a -> a.originServer)
@@ -971,7 +977,7 @@ serve = \req -> case req of
971 let effectiveEvents = do
977 let effectiveEvents = do
972 e <- union filteredOnline filteredOffline
978 e <- union filteredOnline filteredOffline
973 where any gossipResult.appliedKeys (\a -> samePubkeyServer a e)
979 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}
975 when (not gossipResult.withinCapacity)
981 when (not gossipResult.withinCapacity)
976 (println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer))
982 (println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer))
977 fork (do
983 fork (do
@@ -995,8 +1001,7 @@ serve = \req -> case req of
995 pr <- maybePrune t
1001 pr <- maybePrune t
996 messages <- *messages
1002 messages <- *messages
997 ackedIds <- *ackedIds
1003 ackedIds <- *ackedIds
998− if any messages (\m -> m.messageId == messageId && m.toKey == toKey)
1004+ if hasMessage messageId toKey messages || hasMessage messageId toKey ackedIds
999− || any ackedIds (\a -> a.messageId == messageId && a.toKey == toKey)
1000 then yield {pr: pr, forward: ForwardDuplicate {}}
1005 then yield {pr: pr, forward: ForwardDuplicate {}}
1001 else if countMessagesFor messages toKey t >= maxMessagesPerRecipient
1006 else if countMessagesFor messages toKey t >= maxMessagesPerRecipient
1002 then yield {pr: pr, forward: ForwardFull {}}
1007 then yield {pr: pr, forward: ForwardFull {}}