summaryrefslogtreecommitdiff
path: root/Mainline.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Mainline.hs')
-rw-r--r--Mainline.hs87
1 files changed, 5 insertions, 82 deletions
diff --git a/Mainline.hs b/Mainline.hs
index 77c0d5f1..4ce4f4da 100644
--- a/Mainline.hs
+++ b/Mainline.hs
@@ -61,7 +61,7 @@ import Network.BitTorrent.DHT.ContactInfo as Peers
61import Network.BitTorrent.DHT.Search (Search (..)) 61import Network.BitTorrent.DHT.Search (Search (..))
62import Network.BitTorrent.DHT.Token as Token 62import Network.BitTorrent.DHT.Token as Token
63import qualified Network.DHT.Routing as R 63import qualified Network.DHT.Routing as R
64 ;import Network.DHT.Routing (Info, Timestamp, getTimestamp) 64 ;import Network.DHT.Routing (Timestamp, getTimestamp)
65import Network.QueryResponse 65import Network.QueryResponse
66import Network.Socket 66import Network.Socket
67import System.IO 67import System.IO
@@ -79,6 +79,7 @@ import qualified Data.Aeson as JSON
79 ;import Data.Aeson (FromJSON, ToJSON, (.=)) 79 ;import Data.Aeson (FromJSON, ToJSON, (.=))
80import Text.Read 80import Text.Read
81import Global6 81import Global6
82import TriadCommittee
82 83
83newtype NodeId = NodeId ByteString 84newtype NodeId = NodeId ByteString
84 deriving (Eq,Ord,ByteArrayAccess, Bits, Hashable) 85 deriving (Eq,Ord,ByteArrayAccess, Bits, Hashable)
@@ -495,8 +496,6 @@ newSwarmsDatabase = do
495 <*> newTVar toks 496 <*> newTVar toks
496 <*> newTVar def 497 <*> newTVar def
497 498
498type RoutingInfo = Info NodeInfo NodeId
499
500data Routing = Routing 499data Routing = Routing
501 { tentativeId :: NodeInfo 500 { tentativeId :: NodeInfo
502 , sched4 :: !( TVar (Int.PSQ POSIXTime) ) 501 , sched4 :: !( TVar (Int.PSQ POSIXTime) )
@@ -596,7 +595,7 @@ newClient addr = do
596 let var = case flip prefer4or6 Nothing <$> maddr of 595 let var = case flip prefer4or6 Nothing <$> maddr of
597 Just Want_IP6 -> routing6 routing 596 Just Want_IP6 -> routing6 routing
598 _ -> routing4 routing 597 _ -> routing4 routing
599 R.selfNode <$> readTVar var 598 R.thisNode <$> readTVar var
600 , clientResponseId = return 599 , clientResponseId = return
601 } 600 }
602 601
@@ -1027,84 +1026,6 @@ getPeers = mainlineSend (Method "get_peers") unwrapPeers $ flip GetPeers (Just W
1027 1026
1028unwrapPeers (GotPeers ps (NodeFound ns4 ns6) tok) = (ns4++ns6, ps, tok) 1027unwrapPeers (GotPeers ps (NodeFound ns4 ns6) tok) = (ns4++ns6, ps, tok)
1029 1028
1030data TriadSlot = SlotA | SlotB | SlotC
1031 deriving (Eq,Ord,Enum,Show,Read)
1032
1033data TriadCommittee voter a = TriadCommittee
1034 { triadDecider :: TVar TriadSlot
1035 , triadA :: TVar (Maybe (voter,a))
1036 , triadB :: TVar (Maybe (voter,a))
1037 , triadC :: TVar (Maybe (voter,a))
1038 , triadNewDecision :: a -> STM ()
1039 }
1040
1041triadSlot :: TriadSlot -> TriadCommittee voter a -> TVar (Maybe (voter,a))
1042triadSlot SlotA = triadA
1043triadSlot SlotB = triadB
1044triadSlot SlotC = triadC
1045
1046triadDecision :: a -> TriadCommittee voter a -> STM a
1047triadDecision fallback triad = do
1048 slot <- readTVar (triadDecider triad)
1049 maybe fallback snd <$> readTVar (triadSlot slot triad)
1050
1051
1052newTriadCommittee :: (a -> STM ()) -> STM (TriadCommittee voter a)
1053newTriadCommittee onChange =
1054 TriadCommittee <$> newTVar SlotA
1055 <*> newTVar Nothing
1056 <*> newTVar Nothing
1057 <*> newTVar Nothing
1058 <*> pure onChange
1059
1060triadCountVotes :: Eq a => Maybe a -> TriadCommittee voter a -> STM ()
1061triadCountVotes prior triad = do
1062 a <- fmap ((SlotA,) . snd) <$> readTVar (triadA triad)
1063 b <- fmap ((SlotB,) . snd) <$> readTVar (triadB triad)
1064 c <- fmap ((SlotC,) . snd) <$> readTVar (triadC triad)
1065 let (slot,vote) = case catMaybes [a,b,c] of
1066 [ (x,xvote)
1067 , (y,yvote)
1068 , (z,zvote) ] -> if xvote == yvote then (x,Just xvote)
1069 else (z,Just zvote)
1070 [] -> (SlotA,Nothing)
1071 ((slot,vote):_) -> (slot, Just vote)
1072 writeTVar (triadDecider triad) slot
1073 case vote of
1074 Just v | vote /= prior -> triadNewDecision triad v
1075 _ -> return ()
1076
1077
1078addVote :: (Eq voter, Eq a) => TriadCommittee voter a -> voter -> a -> STM ()
1079addVote triad voter vote = do
1080 a <- (SlotA,) . fmap fst <$> readTVar (triadA triad)
1081 b <- (SlotB,) . fmap fst <$> readTVar (triadB triad)
1082 c <- (SlotC,) . fmap fst <$> readTVar (triadC triad)
1083 let avail (_,Nothing) = True
1084 avail (_,Just x ) = (x == voter)
1085 slots = filter avail [a,b,c]
1086 forM_ (take 1 slots) $ \(slot,_) -> do
1087 prior <- do
1088 slotp <- readTVar (triadDecider triad)
1089 fmap snd <$> readTVar (triadSlot slotp triad)
1090 writeTVar (triadSlot slot triad)
1091 (Just (voter,vote))
1092 triadCountVotes prior triad
1093
1094delVote :: (Eq voter, Eq a) => TriadCommittee voter a -> voter -> STM ()
1095delVote triad voter = do
1096 a <- (SlotA,) . fmap fst <$> readTVar (triadA triad)
1097 b <- (SlotB,) . fmap fst <$> readTVar (triadB triad)
1098 c <- (SlotC,) . fmap fst <$> readTVar (triadC triad)
1099 let match (_,Just x ) = (x == voter)
1100 slots = filter match [a,b,c]
1101 forM_ (take 1 slots) $ \(slot,_) -> do
1102 prior <- do
1103 slotp <- readTVar (triadDecider triad)
1104 fmap snd <$> readTVar (triadSlot slotp triad)
1105 writeTVar (triadSlot slot triad) Nothing
1106 triadCountVotes prior triad
1107
1108mainlineSearch qry = Search 1029mainlineSearch qry = Search
1109 { searchSpace = mainlineSpace 1030 { searchSpace = mainlineSpace
1110 , searchNodeAddress = nodeIP &&& nodePort 1031 , searchNodeAddress = nodeIP &&& nodePort
@@ -1154,3 +1075,5 @@ resolve want hostAndPort = do
1154 -- pattern matching never fails. 1075 -- pattern matching never fails.
1155 info : _ <- getAddrInfo (Just hints) (Just host) port 1076 info : _ <- getAddrInfo (Just hints) (Just host) port
1156 return $ addrAddress info 1077 return $ addrAddress info
1078
1079