mirror of https://github.com/voidlizard/hbs2
wip tcp-pex
This commit is contained in:
parent
35115bc866
commit
382cb2c9fc
|
@ -202,6 +202,8 @@ spawnConnection tp env so sa = liftIO do
|
||||||
let newP = fromSockAddr @'TCP sa
|
let newP = fromSockAddr @'TCP sa
|
||||||
|
|
||||||
theirCookie <- handshake tp env so
|
theirCookie <- handshake tp env so
|
||||||
|
-- TCP address available
|
||||||
|
-- FIXME: how to use this info
|
||||||
|
|
||||||
let connId = connectionId myCookie theirCookie
|
let connId = connectionId myCookie theirCookie
|
||||||
|
|
||||||
|
@ -341,6 +343,7 @@ connectPeerTCP env peer = liftIO do
|
||||||
|
|
||||||
connect (show i) (show p) $ \(sock, remoteAddr) -> do
|
connect (show i) (show p) $ \(sock, remoteAddr) -> do
|
||||||
spawnConnection Client env sock remoteAddr
|
spawnConnection Client env sock remoteAddr
|
||||||
|
-- FIXME: tcp-pex. Где-то здесь добавить этих пиров в пекс ?
|
||||||
shutdown sock ShutdownBoth
|
shutdown sock ShutdownBoth
|
||||||
|
|
||||||
runMessagingTCP :: forall m . MonadIO m => MessagingTCP -> m ()
|
runMessagingTCP :: forall m . MonadIO m => MessagingTCP -> m ()
|
||||||
|
|
|
@ -59,8 +59,9 @@ newtype instance Event e (PeerMetaProto e)
|
||||||
= PeerMetaEvent AnnMetaData
|
= PeerMetaEvent AnnMetaData
|
||||||
deriving stock (Typeable)
|
deriving stock (Typeable)
|
||||||
|
|
||||||
newtype PeerMeta = PeerMeta [(Text, ByteString)]
|
newtype PeerMeta = PeerMeta { unPeerMeta :: [(Text, ByteString)] }
|
||||||
deriving stock (Generic)
|
deriving stock (Generic)
|
||||||
|
deriving newtype (Semigroup, Monoid)
|
||||||
|
|
||||||
instance Serialise PeerMeta
|
instance Serialise PeerMeta
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ import Control.Concurrent.Async
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Maybe
|
import Control.Monad.Trans.Maybe
|
||||||
import Data.ByteString.Lazy (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.ByteString.Lazy qualified as LBS
|
||||||
import Data.Cache qualified as Cache
|
import Data.Cache qualified as Cache
|
||||||
import Data.Foldable hiding (find)
|
import Data.Foldable hiding (find)
|
||||||
import Data.HashMap.Strict qualified as HashMap
|
import Data.HashMap.Strict qualified as HashMap
|
||||||
|
@ -44,6 +45,7 @@ import Data.List qualified as List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
import Data.Text.Encoding qualified as TE
|
import Data.Text.Encoding qualified as TE
|
||||||
|
import Data.Word
|
||||||
import Lens.Micro.Platform
|
import Lens.Micro.Platform
|
||||||
import Network.HTTP.Simple (getResponseBody, httpLbs, parseRequest, getResponseStatus)
|
import Network.HTTP.Simple (getResponseBody, httpLbs, parseRequest, getResponseStatus)
|
||||||
import Network.HTTP.Types.Status
|
import Network.HTTP.Types.Status
|
||||||
|
@ -65,7 +67,7 @@ blockHttpDownloadLoop :: forall e m .
|
||||||
-- FIXME: backlog-do-something-with-that
|
-- FIXME: backlog-do-something-with-that
|
||||||
-- это не ревью, это надо что-то с этим
|
-- это не ревью, это надо что-то с этим
|
||||||
-- сделать, неудачное решение
|
-- сделать, неудачное решение
|
||||||
, Block ByteString ~ ByteString
|
, Block LBS.ByteString ~ LBS.ByteString
|
||||||
)
|
)
|
||||||
=> DownloadEnv e -> m ()
|
=> DownloadEnv e -> m ()
|
||||||
blockHttpDownloadLoop denv = do
|
blockHttpDownloadLoop denv = do
|
||||||
|
@ -138,7 +140,7 @@ blockHttpDownloadLoop denv = do
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
updatePeerHttpAddrs :: forall e m .
|
fillPeerMeta :: forall e m .
|
||||||
( m ~ PeerM e IO
|
( m ~ PeerM e IO
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, HasProtocol e (PeerMetaProto e)
|
, HasProtocol e (PeerMetaProto e)
|
||||||
|
@ -148,24 +150,24 @@ updatePeerHttpAddrs :: forall e m .
|
||||||
, Pretty (Peer e)
|
, Pretty (Peer e)
|
||||||
, Pretty (PeerAddr e)
|
, Pretty (PeerAddr e)
|
||||||
, EventListener e ( PeerMetaProto e) m
|
, EventListener e ( PeerMetaProto e) m
|
||||||
-- , e ~ L4Proto
|
, e ~ L4Proto
|
||||||
)
|
)
|
||||||
=> m ()
|
=> m ()
|
||||||
updatePeerHttpAddrs = do
|
fillPeerMeta = do
|
||||||
debug "I'm updatePeerHttpAddrs"
|
debug "I'm fillPeerMeta"
|
||||||
pl <- getPeerLocator @e
|
pl <- getPeerLocator @e
|
||||||
forever do
|
forever do
|
||||||
|
|
||||||
pause @'Seconds 5
|
pause @'Seconds 5
|
||||||
ps <- knownPeers @e pl
|
ps <- knownPeers @e pl
|
||||||
debug $ "updatePeerHttpAddrs peers:" <+> pretty ps
|
debug $ "fillPeerMeta peers:" <+> pretty ps
|
||||||
npi <- newPeerInfo
|
npi <- newPeerInfo
|
||||||
for_ ps $ \p -> do
|
for_ ps $ \p -> do
|
||||||
|
|
||||||
pinfo <- fetch True npi (PeerInfoKey p) id
|
pinfo <- fetch True npi (PeerInfoKey p) id
|
||||||
mmApiAddr <- liftIO $ readTVarIO (_peerHttpApiAddress pinfo)
|
mmApiAddr <- liftIO $ readTVarIO (_peerHttpApiAddress pinfo)
|
||||||
|
|
||||||
debug $ "Find peer http address" <+> pretty p <+> "current:" <+> viaShow mmApiAddr
|
debug $ "Find peer meta and http address" <+> pretty p <+> "current:" <+> viaShow mmApiAddr
|
||||||
case mmApiAddr of
|
case mmApiAddr of
|
||||||
Left attemptn -> do
|
Left attemptn -> do
|
||||||
|
|
||||||
|
@ -187,16 +189,29 @@ updatePeerHttpAddrs = do
|
||||||
liftIO $ atomically $ writeTVar (_peerHttpApiAddress pinfo) $
|
liftIO $ atomically $ writeTVar (_peerHttpApiAddress pinfo) $
|
||||||
if attemptn < 3 then (Left (attemptn + 1)) else (Right Nothing)
|
if attemptn < 3 then (Left (attemptn + 1)) else (Right Nothing)
|
||||||
Right (Just meta) -> (void . runMaybeT) do
|
Right (Just meta) -> (void . runMaybeT) do
|
||||||
port <- case meta of
|
peerMeta <- case meta of
|
||||||
NoMetaData -> (MaybeT . pure) Nothing
|
NoMetaData -> (MaybeT . pure) Nothing
|
||||||
ShortMetadata t -> do
|
ShortMetadata t -> do
|
||||||
PeerMeta d <- (MaybeT . pure) (parsePeerMeta t)
|
(MaybeT . pure) (parsePeerMeta t)
|
||||||
httpPortBS <- (MaybeT . pure) (lookup "http-port" d)
|
|
||||||
(MaybeT . pure . readMay . Text.unpack . TE.decodeUtf8) httpPortBS
|
|
||||||
AnnHashRef h -> (MaybeT . pure) Nothing
|
AnnHashRef h -> (MaybeT . pure) Nothing
|
||||||
|
liftIO $ atomically $ writeTVar (_peerMeta pinfo) (Just peerMeta)
|
||||||
|
|
||||||
|
-- 3) пробить, что есть tcp
|
||||||
|
forM_ (lookupDecode "listen-tcp" (unPeerMeta peerMeta)) \listenTCPPort -> lift do
|
||||||
|
peerTCPAddrPort <- replacePort p listenTCPPort
|
||||||
|
-- 4) выяснить, можно ли к нему открыть соединение на этот порт
|
||||||
|
-- возможно, с ним уже открыто соединение
|
||||||
|
-- или попробовать открыть или запомнить, что было открыто
|
||||||
|
-- connectPeerTCP ?
|
||||||
|
-- 5) добавить этих пиров в пекс
|
||||||
|
-- p :: Peer e <- fromPeerAddr (L4Address TCP (peerTCPAddrPort :: IPAddrPort L4Proto) :: PeerAddr e)
|
||||||
|
sendPing =<< fromPeerAddr (L4Address TCP peerTCPAddrPort)
|
||||||
|
|
||||||
|
port <- (MaybeT . pure) (lookupDecode "http-port" (unPeerMeta peerMeta))
|
||||||
|
|
||||||
lift do
|
lift do
|
||||||
IPAddrPort (ip,_port) <- fromString @(IPAddrPort e) . show . pretty <$> toPeerAddr p
|
|
||||||
let peerHttpApiAddr = show . pretty $ IPAddrPort (ip,port)
|
peerHttpApiAddr <- show . pretty <$> replacePort p port
|
||||||
|
|
||||||
-- check peerHttpApiAddr
|
-- check peerHttpApiAddr
|
||||||
r <- liftIO $ race ( pause defBlockWaitMax ) do
|
r <- liftIO $ race ( pause defBlockWaitMax ) do
|
||||||
|
@ -213,3 +228,13 @@ updatePeerHttpAddrs = do
|
||||||
liftIO $ atomically $ writeTVar (_peerHttpApiAddress pinfo) $ Right Nothing
|
liftIO $ atomically $ writeTVar (_peerHttpApiAddress pinfo) $ Right Nothing
|
||||||
|
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
|
|
||||||
|
where
|
||||||
|
replacePort :: Peer e -> Word16 -> PeerM e IO (IPAddrPort e)
|
||||||
|
replacePort peer port = do
|
||||||
|
IPAddrPort (ip,_port) <- fromString @(IPAddrPort e) . show . pretty <$> toPeerAddr peer
|
||||||
|
pure $ IPAddrPort (ip,port)
|
||||||
|
|
||||||
|
lookupDecode :: (Eq k, Read v) => k -> [(k, ByteString)] -> Maybe v
|
||||||
|
lookupDecode k d =
|
||||||
|
readMay . Text.unpack . TE.decodeUtf8 =<< lookup k d
|
||||||
|
|
|
@ -54,6 +54,7 @@ import Control.Concurrent.STM
|
||||||
import Control.Exception as Exception
|
import Control.Exception as Exception
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Maybe
|
import Control.Monad.Trans.Maybe
|
||||||
|
import Control.Monad.Trans.Writer.CPS qualified as W
|
||||||
import Crypto.Saltine (sodiumInit)
|
import Crypto.Saltine (sodiumInit)
|
||||||
import Data.ByteString.Lazy (ByteString)
|
import Data.ByteString.Lazy (ByteString)
|
||||||
import Data.ByteString.Lazy qualified as LBS
|
import Data.ByteString.Lazy qualified as LBS
|
||||||
|
@ -712,10 +713,9 @@ runPeer opts = Exception.handle myException $ do
|
||||||
debug "sending first peer announce"
|
debug "sending first peer announce"
|
||||||
request localMulticast (PeerAnnounce @e pnonce)
|
request localMulticast (PeerAnnounce @e pnonce)
|
||||||
|
|
||||||
let wo = fmap L.singleton
|
let peerThread = W.tell . L.singleton <=< liftIO . async . withPeerM env
|
||||||
let peerThread = wo . liftIO . async . withPeerM env
|
|
||||||
|
|
||||||
workers <- do
|
workers <- W.execWriterT do
|
||||||
|
|
||||||
peerThread $ forever $ do
|
peerThread $ forever $ do
|
||||||
pause defPeerAnnounceTime -- FIXME: setting!
|
pause defPeerAnnounceTime -- FIXME: setting!
|
||||||
|
@ -738,13 +738,12 @@ runPeer opts = Exception.handle myException $ do
|
||||||
|
|
||||||
peerThread (blockDownloadLoop denv)
|
peerThread (blockDownloadLoop denv)
|
||||||
|
|
||||||
|
peerThread fillPeerMeta
|
||||||
|
|
||||||
-- FIXME: clumsy-code
|
-- FIXME: clumsy-code
|
||||||
if useHttpDownload
|
-- Is it better now ?
|
||||||
then do
|
when useHttpDownload do
|
||||||
-- FIXME: discarded-async-value-for-updatePeerHttpAddrs
|
peerThread (blockHttpDownloadLoop denv)
|
||||||
peerThread updatePeerHttpAddrs
|
|
||||||
peerThread (blockHttpDownloadLoop denv)
|
|
||||||
else pure mempty
|
|
||||||
|
|
||||||
peerThread (postponedLoop denv)
|
peerThread (postponedLoop denv)
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ data PeerInfo e =
|
||||||
-- Acts like a circular buffer.
|
-- Acts like a circular buffer.
|
||||||
, _peerHttpApiAddress :: TVar (Either Int (Maybe String))
|
, _peerHttpApiAddress :: TVar (Either Int (Maybe String))
|
||||||
, _peerHttpDownloaded :: TVar Int
|
, _peerHttpDownloaded :: TVar Int
|
||||||
|
, _peerMeta :: TVar (Maybe PeerMeta)
|
||||||
}
|
}
|
||||||
deriving stock (Generic,Typeable)
|
deriving stock (Generic,Typeable)
|
||||||
|
|
||||||
|
@ -87,6 +88,7 @@ newPeerInfo = liftIO do
|
||||||
<*> newTVarIO []
|
<*> newTVarIO []
|
||||||
<*> newTVarIO (Left 0)
|
<*> newTVarIO (Left 0)
|
||||||
<*> newTVarIO 0
|
<*> newTVarIO 0
|
||||||
|
<*> newTVarIO Nothing
|
||||||
|
|
||||||
type instance SessionData e (PeerInfo e) = PeerInfo e
|
type instance SessionData e (PeerInfo e) = PeerInfo e
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue