mark successfully Pinged nodes as verified

for #29
This commit is contained in:
Trolli Schmittlauch 2020-06-24 22:27:35 +02:00
parent c9783a10cf
commit 5e8cfb0ccd

View file

@ -3,9 +3,10 @@ module Hash2Pub.DHTProtocol
, queryLocalCache , queryLocalCache
, addCacheEntry , addCacheEntry
, addCacheEntryPure , addCacheEntryPure
, addNodeAsVerified
, addNodeAsVerifiedPure
, deleteCacheEntry , deleteCacheEntry
, deserialiseMessage , deserialiseMessage
, markCacheEntryAsVerified
, RemoteCacheEntry(..) , RemoteCacheEntry(..)
, toRemoteCacheEntry , toRemoteCacheEntry
, remoteNode , remoteNode
@ -64,9 +65,10 @@ import Hash2Pub.FediChordTypes (CacheEntry (..),
addRMapEntry, addRMapEntryWith, addRMapEntry, addRMapEntryWith,
cacheGetNodeStateUnvalidated, cacheGetNodeStateUnvalidated,
cacheLookup, cacheLookupPred, cacheLookup, cacheLookupPred,
cacheLookupSucc, getKeyID, cacheLookupSucc, genNodeID,
localCompare, rMapFromList, getKeyID, localCompare,
rMapLookupPred, rMapLookupSucc, rMapFromList, rMapLookupPred,
rMapLookupSucc,
setPredecessors, setSuccessors) setPredecessors, setSuccessors)
import Hash2Pub.ProtocolTypes import Hash2Pub.ProtocolTypes
@ -154,6 +156,26 @@ deleteCacheEntry nid = RingMap . Map.update modifier nid . getRingMap
modifier (ProxyEntry idPointer _) = Just (ProxyEntry idPointer Nothing) modifier (ProxyEntry idPointer _) = Just (ProxyEntry idPointer Nothing)
modifier KeyEntry {} = Nothing modifier KeyEntry {} = Nothing
-- | Add a 'RemoteNodeState' to the node cache marked as verified.
-- If an entry already exists, it is replaced by the new verified one.
addNodeAsVerified :: RemoteNodeState
-> NodeCache
-> IO NodeCache
addNodeAsVerified node cache = do
now <- getPOSIXTime
pure $ addNodeAsVerifiedPure now node cache
-- | Pure variant of 'addNodeAsVerified' with current time explicitly specified as an argument
addNodeAsVerifiedPure :: POSIXTime
-> RemoteNodeState
-> NodeCache
-> NodeCache
addNodeAsVerifiedPure now node = addRMapEntry (CacheEntry True node now)
-- | Mark a cache entry as verified after pinging it, possibly bumping its timestamp. -- | Mark a cache entry as verified after pinging it, possibly bumping its timestamp.
markCacheEntryAsVerified :: Maybe POSIXTime -- ^ the (current) timestamp to be markCacheEntryAsVerified :: Maybe POSIXTime -- ^ the (current) timestamp to be
-- given to the entry, or Nothing -- given to the entry, or Nothing
@ -540,7 +562,9 @@ requestPing :: LocalNodeState -- ^ sending node
-> RemoteNodeState -- ^ node to be PINGed -> RemoteNodeState -- ^ node to be PINGed
-> IO (Either String [RemoteNodeState]) -- ^ all active vServers of the pinged node -> IO (Either String [RemoteNodeState]) -- ^ all active vServers of the pinged node
requestPing ns target = do requestPing ns target = do
responses <- bracket (mkSendSocket (getDomain target) (getDhtPort target)) close (fmap Right . sendRequestTo 5000 3 (\rid -> responses <- bracket (mkSendSocket (getDomain target) (getDhtPort target)) close
(\sock -> do
resp <- sendRequestTo 5000 3 (\rid ->
Request { Request {
requestID = rid requestID = rid
, sender = toRemoteNodeState ns , sender = toRemoteNodeState ns
@ -549,17 +573,27 @@ requestPing ns target = do
, action = Ping , action = Ping
, payload = Just PingRequestPayload , payload = Just PingRequestPayload
} }
) ) sock
(SockAddrInet6 _ _ peerAddr _) <- getPeerName sock
pure $ Right (peerAddr, resp)
) `catch` (\e -> pure . Left $ displayException (e :: IOException)) ) `catch` (\e -> pure . Left $ displayException (e :: IOException))
either either
-- forward IO error messages -- forward IO error messages
(pure . Left) (pure . Left)
(\respSet -> do (\(peerAddr, respSet) -> do
-- fold all reply parts together -- fold all reply parts together
let responseVss = foldr' (\msg acc -> let responseVss = foldr' (\msg acc ->
maybe acc (foldr' (:) acc) (pingNodeStates <$> payload msg) maybe acc (foldr' (:) acc) (pingNodeStates <$> payload msg)
) )
[] respSet [] respSet
-- recompute ID for each received node and mark as verified in cache
now <- getPOSIXTime
forM_ responseVss (\vs ->
let recomputedID = genNodeID peerAddr (getDomain vs) (fromInteger $ getVServerID vs)
in if recomputedID == getNid vs
then atomically $ writeTQueue (cacheWriteQueue ns) $ addNodeAsVerifiedPure now vs
else pure ()
)
pure $ if null responseVss pure $ if null responseVss
then Left "no active vServer IDs returned, ignoring node" then Left "no active vServer IDs returned, ignoring node"
else Right responseVss else Right responseVss