mirror of https://github.com/voidlizard/hbs2
done oYxxWDF4nX-seems-like-a-bad-idea
This commit is contained in:
parent
4924b5d92d
commit
ed47e18d24
|
@ -75,10 +75,10 @@ class Expires a where
|
||||||
-- | Use coarse clock timer. This timer has 1ms resolution but is much
|
-- | Use coarse clock timer. This timer has 1ms resolution but is much
|
||||||
-- faster comparing to the ordinary one. Is used on Linux, on MacOS
|
-- faster comparing to the ordinary one. Is used on Linux, on MacOS
|
||||||
-- provides ordinary one.
|
-- provides ordinary one.
|
||||||
getTimeCoarse :: IO TimeSpec
|
getTimeCoarse :: MonadIO m => m TimeSpec
|
||||||
#ifdef linux_HOST_OS
|
#ifdef linux_HOST_OS
|
||||||
getTimeCoarse = getTime MonotonicCoarse
|
getTimeCoarse = liftIO $ getTime MonotonicCoarse
|
||||||
#else
|
#else
|
||||||
getTimeCoarse = getTime Monotonic
|
getTimeCoarse = liftIO $ getTime Monotonic
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,7 @@ module PeerInfo where
|
||||||
|
|
||||||
import HBS2.Actors.Peer
|
import HBS2.Actors.Peer
|
||||||
import HBS2.Clock
|
import HBS2.Clock
|
||||||
import HBS2.Defaults
|
|
||||||
import HBS2.Events
|
import HBS2.Events
|
||||||
import HBS2.Net.Messaging.UDP
|
|
||||||
import HBS2.Net.PeerLocator
|
import HBS2.Net.PeerLocator
|
||||||
import HBS2.Net.Proto.Peer
|
import HBS2.Net.Proto.Peer
|
||||||
import HBS2.Net.Proto.PeerExchange
|
import HBS2.Net.Proto.PeerExchange
|
||||||
|
@ -16,13 +14,13 @@ import HBS2.Prelude.Plated
|
||||||
import HBS2.System.Logger.Simple
|
import HBS2.System.Logger.Simple
|
||||||
|
|
||||||
import PeerConfig
|
import PeerConfig
|
||||||
|
import PeerTypes
|
||||||
|
|
||||||
import Control.Concurrent.Async
|
import Control.Concurrent.Async
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Foldable hiding (find)
|
import Data.Foldable hiding (find)
|
||||||
import Data.IntSet (IntSet)
|
|
||||||
import Data.List qualified as List
|
import Data.List qualified as List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Lens.Micro.Platform
|
import Lens.Micro.Platform
|
||||||
|
@ -36,29 +34,6 @@ data PeerPingIntervalKey
|
||||||
instance HasCfgKey PeerPingIntervalKey (Maybe Integer) where
|
instance HasCfgKey PeerPingIntervalKey (Maybe Integer) where
|
||||||
key = "ping-interval"
|
key = "ping-interval"
|
||||||
|
|
||||||
data PeerInfo e =
|
|
||||||
PeerInfo
|
|
||||||
{ _peerBurst :: TVar Int
|
|
||||||
, _peerBurstMax :: TVar (Maybe Int)
|
|
||||||
, _peerBurstSet :: TVar IntSet
|
|
||||||
, _peerErrors :: TVar Int
|
|
||||||
, _peerErrorsLast :: TVar Int
|
|
||||||
, _peerErrorsPerSec :: TVar Int
|
|
||||||
, _peerLastWatched :: TVar TimeSpec
|
|
||||||
, _peerDownloaded :: TVar Int
|
|
||||||
, _peerDownloadedLast :: TVar Int
|
|
||||||
, _peerPingFailed :: TVar Int
|
|
||||||
, _peerDownloadedBlk :: TVar Int
|
|
||||||
, _peerDownloadFail :: TVar Int
|
|
||||||
, _peerDownloadMiss :: TVar Int
|
|
||||||
, _peerUsefulness :: TVar Double
|
|
||||||
, _peerRTTBuffer :: TVar [Integer] -- ^ Contains a list of the last few round-trip time (RTT) values, measured in nanoseconds.
|
|
||||||
-- Acts like a circular buffer.
|
|
||||||
, _peerHttpApiAddress :: TVar (Either Int (Maybe String))
|
|
||||||
}
|
|
||||||
deriving stock (Generic,Typeable)
|
|
||||||
|
|
||||||
makeLenses 'PeerInfo
|
|
||||||
|
|
||||||
-- | Compute the median of a list
|
-- | Compute the median of a list
|
||||||
median :: (Ord a, Integral a) => [a] -> Maybe a
|
median :: (Ord a, Integral a) => [a] -> Maybe a
|
||||||
|
@ -91,37 +66,6 @@ insertRTT x rttList = do
|
||||||
else x:init xs
|
else x:init xs
|
||||||
)
|
)
|
||||||
|
|
||||||
newPeerInfo :: MonadIO m => m (PeerInfo e)
|
|
||||||
newPeerInfo = liftIO do
|
|
||||||
PeerInfo <$> newTVarIO defBurst
|
|
||||||
<*> newTVarIO Nothing
|
|
||||||
<*> newTVarIO mempty
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO 0
|
|
||||||
<*> newTVarIO []
|
|
||||||
<*> newTVarIO (Left 0)
|
|
||||||
|
|
||||||
type instance SessionData e (PeerInfo e) = PeerInfo e
|
|
||||||
|
|
||||||
newtype instance SessionKey e (PeerInfo e) =
|
|
||||||
PeerInfoKey (Peer e)
|
|
||||||
|
|
||||||
deriving newtype instance Hashable (SessionKey L4Proto (PeerInfo L4Proto))
|
|
||||||
deriving stock instance Eq (SessionKey L4Proto (PeerInfo L4Proto))
|
|
||||||
|
|
||||||
-- FIXME: this?
|
|
||||||
instance Expires (SessionKey L4Proto (PeerInfo L4Proto)) where
|
|
||||||
expiresIn = const (Just defCookieTimeoutSec)
|
|
||||||
|
|
||||||
pexLoop :: forall e m . ( HasPeerLocator e m
|
pexLoop :: forall e m . ( HasPeerLocator e m
|
||||||
, HasPeer e
|
, HasPeer e
|
||||||
, Sessions e (KnownPeer e) m
|
, Sessions e (KnownPeer e) m
|
||||||
|
@ -195,6 +139,8 @@ peerPingLoop cfg = do
|
||||||
|
|
||||||
npi <- newPeerInfo
|
npi <- newPeerInfo
|
||||||
|
|
||||||
|
now <- getTimeCoarse
|
||||||
|
|
||||||
debug $ "known peers" <+> pretty pee
|
debug $ "known peers" <+> pretty pee
|
||||||
|
|
||||||
for_ pee $ \p -> do
|
for_ pee $ \p -> do
|
||||||
|
@ -206,8 +152,11 @@ peerPingLoop cfg = do
|
||||||
downMiss <- liftIO $ readTVarIO (view peerDownloadMiss pinfo)
|
downMiss <- liftIO $ readTVarIO (view peerDownloadMiss pinfo)
|
||||||
down <- liftIO $ readTVarIO (view peerDownloadedBlk pinfo)
|
down <- liftIO $ readTVarIO (view peerDownloadedBlk pinfo)
|
||||||
rtt <- liftIO $ medianPeerRTT pinfo <&> fmap realToFrac
|
rtt <- liftIO $ medianPeerRTT pinfo <&> fmap realToFrac
|
||||||
|
seen <- liftIO $ readTVarIO (view peerLastWatched pinfo)
|
||||||
|
let l = realToFrac (toNanoSecs $ now - seen) / 1e9
|
||||||
|
|
||||||
let rttMs = (/1e6) <$> rtt <&> (\x -> showGFloat (Just 2) x "") <&> (<> "ms")
|
let rttMs = (/1e6) <$> rtt <&> (\x -> showGFloat (Just 2) x "") <&> (<> "ms")
|
||||||
|
let ls = showGFloat (Just 2) l "" <> "s"
|
||||||
|
|
||||||
notice $ "peer" <+> pretty p <+> "burst:" <+> pretty burst
|
notice $ "peer" <+> pretty p <+> "burst:" <+> pretty burst
|
||||||
<+> "burst-max:" <+> pretty buM
|
<+> "burst-max:" <+> pretty buM
|
||||||
|
@ -215,9 +164,27 @@ peerPingLoop cfg = do
|
||||||
<+> "down:" <+> pretty down
|
<+> "down:" <+> pretty down
|
||||||
<+> "miss:" <+> pretty downMiss
|
<+> "miss:" <+> pretty downMiss
|
||||||
<+> "rtt:" <+> pretty rttMs
|
<+> "rtt:" <+> pretty rttMs
|
||||||
|
<+> "seen" <+> pretty ls
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
|
||||||
|
watch <- liftIO $ async $ forever $ withPeerM e $ do
|
||||||
|
pause @'Seconds 120
|
||||||
|
pips <- getKnownPeers @e
|
||||||
|
now <- getTimeCoarse
|
||||||
|
for_ pips $ \p -> do
|
||||||
|
pinfo' <- find (PeerInfoKey p) id
|
||||||
|
maybe1 pinfo' none $ \pinfo -> do
|
||||||
|
seen <- liftIO $ readTVarIO (view peerLastWatched pinfo)
|
||||||
|
-- FIXME: do-something-with-this-nanosec-boilerplate-everywhere
|
||||||
|
let l = realToFrac (toNanoSecs $ now - seen) / 1e9
|
||||||
|
-- FIXME: time-hardcode
|
||||||
|
when ( l > 300 ) do
|
||||||
|
delPeers pl [p]
|
||||||
|
expire (PeerInfoKey p)
|
||||||
|
expire (KnownPeerKey p)
|
||||||
|
|
||||||
|
liftIO $ link watch
|
||||||
|
|
||||||
forever do
|
forever do
|
||||||
|
|
||||||
|
@ -236,27 +203,7 @@ peerPingLoop cfg = do
|
||||||
pips <- knownPeers @e pl <&> (<> sas) <&> List.nub
|
pips <- knownPeers @e pl <&> (<> sas) <&> List.nub
|
||||||
|
|
||||||
for_ pips $ \p -> do
|
for_ pips $ \p -> do
|
||||||
npi <- newPeerInfo
|
trace $ "SEND PING TO" <+> pretty p
|
||||||
|
|
||||||
here <- find @e (KnownPeerKey p) id
|
|
||||||
|
|
||||||
pinfo <- fetch True npi (PeerInfoKey p) id
|
|
||||||
let pfails = view peerPingFailed pinfo
|
|
||||||
let pdownfails = view peerDownloadFail pinfo
|
|
||||||
|
|
||||||
-- FIXME: seems-like-a-bad-idea
|
|
||||||
-- Кажется, вызывает гонки
|
|
||||||
liftIO $ atomically $ modifyTVar pfails succ
|
|
||||||
|
|
||||||
sendPing @e p
|
sendPing @e p
|
||||||
|
|
||||||
fnum <- liftIO $ readTVarIO pfails
|
|
||||||
fdown <- liftIO $ readTVarIO pdownfails
|
|
||||||
|
|
||||||
when (fnum > 4) do -- FIXME: hardcode!
|
|
||||||
warn $ "removing peer" <+> pretty p <+> "for not responding to our pings"
|
|
||||||
delPeers pl [p]
|
|
||||||
expire (PeerInfoKey p)
|
|
||||||
expire (KnownPeerKey p)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -623,6 +623,12 @@ runPeer opts = Exception.handle myException $ do
|
||||||
|
|
||||||
let thatNonce = view peerOwnNonce d
|
let thatNonce = view peerOwnNonce d
|
||||||
|
|
||||||
|
now <- liftIO getTimeCoarse
|
||||||
|
pinfo' <- find (PeerInfoKey p) id -- (view peerPingFailed)
|
||||||
|
maybe1 pinfo' none $ \pinfo -> do
|
||||||
|
liftIO $ atomically $ writeTVar (view peerPingFailed pinfo) 0
|
||||||
|
liftIO $ atomically $ writeTVar (view peerLastWatched pinfo) now
|
||||||
|
|
||||||
banned <- peerBanned p d
|
banned <- peerBanned p d
|
||||||
|
|
||||||
let doAddPeer p = do
|
let doAddPeer p = do
|
||||||
|
@ -633,13 +639,7 @@ runPeer opts = Exception.handle myException $ do
|
||||||
|
|
||||||
here <- find @e (KnownPeerKey p) id <&> isJust
|
here <- find @e (KnownPeerKey p) id <&> isJust
|
||||||
|
|
||||||
pfails <- fetch True npi (PeerInfoKey p) (view peerPingFailed)
|
|
||||||
liftIO $ atomically $ writeTVar pfails 0
|
|
||||||
-- pdownfails <- fetch True npi (PeerInfoKey p) (view peerDownloadFail)
|
|
||||||
|
|
||||||
unless here do
|
unless here do
|
||||||
-- liftIO $ atomically $ writeTVar pdownfails 0
|
|
||||||
|
|
||||||
debug $ "Got authorized peer!" <+> pretty p
|
debug $ "Got authorized peer!" <+> pretty p
|
||||||
<+> pretty (AsBase58 (view peerSignKey d))
|
<+> pretty (AsBase58 (view peerSignKey d))
|
||||||
|
|
||||||
|
@ -743,9 +743,11 @@ runPeer opts = Exception.handle myException $ do
|
||||||
|
|
||||||
peerThread (blockDownloadLoop denv)
|
peerThread (blockDownloadLoop denv)
|
||||||
|
|
||||||
|
-- FIXME: clumsy-code
|
||||||
if useHttpDownload
|
if useHttpDownload
|
||||||
then do
|
then do
|
||||||
peerThread (updatePeerHttpAddrs)
|
-- FIXME: discarded-async-value-for-updatePeerHttpAddrs
|
||||||
|
peerThread updatePeerHttpAddrs
|
||||||
peerThread (blockHttpDownloadLoop denv)
|
peerThread (blockHttpDownloadLoop denv)
|
||||||
else pure mempty
|
else pure mempty
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import HBS2.Storage
|
||||||
import HBS2.Net.PeerLocator
|
import HBS2.Net.PeerLocator
|
||||||
import HBS2.System.Logger.Simple
|
import HBS2.System.Logger.Simple
|
||||||
|
|
||||||
import PeerInfo
|
-- import PeerInfo
|
||||||
import Brains
|
import Brains
|
||||||
|
|
||||||
import Data.Foldable (for_)
|
import Data.Foldable (for_)
|
||||||
|
@ -37,6 +37,62 @@ import Lens.Micro.Platform
|
||||||
import Data.Hashable
|
import Data.Hashable
|
||||||
import Type.Reflection
|
import Type.Reflection
|
||||||
import Data.IntMap (IntMap)
|
import Data.IntMap (IntMap)
|
||||||
|
import Data.IntSet (IntSet)
|
||||||
|
|
||||||
|
|
||||||
|
data PeerInfo e =
|
||||||
|
PeerInfo
|
||||||
|
{ _peerBurst :: TVar Int
|
||||||
|
, _peerBurstMax :: TVar (Maybe Int)
|
||||||
|
, _peerBurstSet :: TVar IntSet
|
||||||
|
, _peerErrors :: TVar Int
|
||||||
|
, _peerErrorsLast :: TVar Int
|
||||||
|
, _peerErrorsPerSec :: TVar Int
|
||||||
|
, _peerLastWatched :: TVar TimeSpec
|
||||||
|
, _peerDownloaded :: TVar Int
|
||||||
|
, _peerDownloadedLast :: TVar Int
|
||||||
|
, _peerPingFailed :: TVar Int
|
||||||
|
, _peerDownloadedBlk :: TVar Int
|
||||||
|
, _peerDownloadFail :: TVar Int
|
||||||
|
, _peerDownloadMiss :: TVar Int
|
||||||
|
, _peerRTTBuffer :: TVar [Integer] -- ^ Contains a list of the last few round-trip time (RTT) values, measured in nanoseconds.
|
||||||
|
-- Acts like a circular buffer.
|
||||||
|
, _peerHttpApiAddress :: TVar (Either Int (Maybe String))
|
||||||
|
}
|
||||||
|
deriving stock (Generic,Typeable)
|
||||||
|
|
||||||
|
makeLenses 'PeerInfo
|
||||||
|
|
||||||
|
newPeerInfo :: MonadIO m => m (PeerInfo e)
|
||||||
|
newPeerInfo = liftIO do
|
||||||
|
PeerInfo <$> newTVarIO defBurst
|
||||||
|
<*> newTVarIO Nothing
|
||||||
|
<*> newTVarIO mempty
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO []
|
||||||
|
<*> newTVarIO (Left 0)
|
||||||
|
|
||||||
|
type instance SessionData e (PeerInfo e) = PeerInfo e
|
||||||
|
|
||||||
|
newtype instance SessionKey e (PeerInfo e) =
|
||||||
|
PeerInfoKey (Peer e)
|
||||||
|
|
||||||
|
deriving newtype instance Hashable (SessionKey L4Proto (PeerInfo L4Proto))
|
||||||
|
deriving stock instance Eq (SessionKey L4Proto (PeerInfo L4Proto))
|
||||||
|
|
||||||
|
-- FIXME: this?
|
||||||
|
instance Expires (SessionKey L4Proto (PeerInfo L4Proto)) where
|
||||||
|
expiresIn = const (Just defCookieTimeoutSec)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type MyPeer e = ( Eq (Peer e)
|
type MyPeer e = ( Eq (Peer e)
|
||||||
|
|
|
@ -172,7 +172,8 @@ reflogWorker conf adapter = do
|
||||||
reflogDownload adapter h
|
reflogDownload adapter h
|
||||||
fix \next -> do
|
fix \next -> do
|
||||||
missed <- missedEntries sto h
|
missed <- missedEntries sto h
|
||||||
if missed /= 0 then do
|
if not (null missed) then do
|
||||||
|
for_ missed $ reflogDownload adapter
|
||||||
pause @'Seconds 1
|
pause @'Seconds 1
|
||||||
trace $ "reflogWorker: missed refs for" <+> pretty h <+> pretty missed
|
trace $ "reflogWorker: missed refs for" <+> pretty h <+> pretty missed
|
||||||
next
|
next
|
||||||
|
@ -284,10 +285,11 @@ reflogWorker conf adapter = do
|
||||||
pure $ mconcat re
|
pure $ mconcat re
|
||||||
|
|
||||||
missedEntries sto h = do
|
missedEntries sto h = do
|
||||||
missed <- liftIO $ newTVarIO 0
|
missed <- liftIO $ newTVarIO mempty
|
||||||
walkMerkle h (getBlock sto) $ \hr -> do
|
walkMerkle h (getBlock sto) $ \hr -> do
|
||||||
case hr of
|
case hr of
|
||||||
Left{} -> atomically $ modifyTVar missed succ
|
Left ha -> do
|
||||||
|
atomically $ modifyTVar missed (ha:)
|
||||||
Right (_ :: [HashRef]) -> pure ()
|
Right (_ :: [HashRef]) -> pure ()
|
||||||
liftIO $ readTVarIO missed
|
liftIO $ readTVarIO missed
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue