mirror of https://github.com/voidlizard/hbs2
112 lines
3.4 KiB
Haskell
112 lines
3.4 KiB
Haskell
{-# Language AllowAmbiguousTypes #-}
|
|
{-# Language TypeOperators #-}
|
|
module Bootstrap where
|
|
|
|
import HBS2.Data.Types.Peer
|
|
import HBS2.Prelude
|
|
import HBS2.Net.Proto.Types
|
|
import HBS2.Peer.Proto.Peer
|
|
import HBS2.Clock
|
|
import HBS2.Net.Proto.Sessions
|
|
import HBS2.Peer.Brains
|
|
|
|
import PeerConfig
|
|
import PeerLogger
|
|
|
|
import Network.DNS
|
|
import Control.Monad.Reader
|
|
import Data.ByteString.Char8 qualified as B8
|
|
import Data.Foldable
|
|
import Data.Maybe
|
|
import Data.Set qualified as Set
|
|
import Data.Set (Set)
|
|
import Data.List qualified as List
|
|
import Control.Monad.Trans.Maybe
|
|
|
|
|
|
data PeerDnsBootStrapKey
|
|
|
|
data PeerKnownPeer
|
|
|
|
instance Monad m => HasCfgKey PeerDnsBootStrapKey (Set String) m where
|
|
key = "bootstrap-dns"
|
|
|
|
instance Monad m => HasCfgKey PeerKnownPeer (Set String) m where
|
|
key = "known-peer"
|
|
|
|
-- FIXME: tcp-addr-support-bootstrap
|
|
bootstrapDnsLoop :: forall e m . ( HasPeer e
|
|
, Request e (PeerHandshake e) m
|
|
, HasNonces (PeerHandshake e) m
|
|
, Nonce (PeerHandshake e) ~ PingNonce
|
|
, Sessions e (PeerHandshake e) m
|
|
, Pretty (Peer e)
|
|
-- , FromSockAddr 'UDP (Peer e)
|
|
, e ~ L4Proto
|
|
, MonadIO m
|
|
)
|
|
=> PeerConfig -> m ()
|
|
|
|
bootstrapDnsLoop (PeerConfig syn) = do
|
|
|
|
pause @'Seconds 2
|
|
|
|
rs <- liftIO $ makeResolvSeed defaultResolvConf
|
|
|
|
forever do
|
|
debug "I'm a bootstrapLoop"
|
|
|
|
dns <- runReaderT(cfgValue @PeerDnsBootStrapKey) syn
|
|
<&> (<> Set.singleton "bootstrap.hbs2.net")
|
|
|
|
-- FIXME: utf8-domains
|
|
for_ (Set.toList dns) $ \dn -> do
|
|
debug $ "bootstrapping from" <+> pretty dn
|
|
answers <- liftIO $ withResolver rs $ \resolver -> lookupTXT resolver (B8.pack dn) <&> either mempty id
|
|
void $ runMaybeT do
|
|
for_ answers $ \answ -> do
|
|
-- FIXME: tcp-addr-support-1
|
|
pa <- MaybeT $ pure $ fromStringMay @(PeerAddr L4Proto) (B8.unpack answ)
|
|
pip <- fromPeerAddr pa
|
|
debug $ "BOOTSTRAP:" <+> pretty pip
|
|
lift $ sendPing @e pip
|
|
|
|
-- FIXME: fix-bootstrapDnsLoop-time-hardcode
|
|
pause @'Seconds 300
|
|
|
|
|
|
-- FIXME: tcp-addr-support-known-peers-loop
|
|
knownPeersPingLoop :: forall e m . ( HasPeer e
|
|
, Request e (PeerHandshake e) m
|
|
, HasNonces (PeerHandshake e) m
|
|
, Nonce (PeerHandshake e) ~ PingNonce
|
|
, Sessions e (PeerHandshake e) m
|
|
, Pretty (Peer e)
|
|
, e ~ L4Proto
|
|
, MonadIO m)
|
|
=> PeerConfig
|
|
-> SomeBrains e
|
|
-> m ()
|
|
knownPeersPingLoop (PeerConfig syn) brains = do
|
|
-- FIXME: add validation and error handling
|
|
-- FIXME: tcp-addr-support-2
|
|
let parseKnownPeers xs = do
|
|
let pa = foldMap (maybeToList . fromStringMay) xs
|
|
mapM fromPeerAddr pa
|
|
|
|
let them = runReader (cfgValue @PeerKnownPeer) syn & Set.toList
|
|
|
|
pex <- listPexInfo @e brains >>= liftIO . mapM fromPeerAddr
|
|
|
|
knownPeers' <- liftIO $ parseKnownPeers them
|
|
|
|
let pips = List.nub (knownPeers' <> pex)
|
|
|
|
forever do
|
|
forM_ pips (sendPing @e)
|
|
pause @'Minutes 10
|
|
|
|
|
|
|
|
|