diff options
author | joe <joe@jerkface.net> | 2017-11-03 23:23:47 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-11-03 23:23:47 -0400 |
commit | fd7327e8974aa6a79a6be07005223233d107dfb0 (patch) | |
tree | d7f324ae857e40316109654841d83b357ba49ccc /src | |
parent | e8edad1852aa245a994c72d8331474b521042a25 (diff) |
Improved search parameters for tox onion routed queries.
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/Kademlia/Search.hs | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/Network/Kademlia/Search.hs b/src/Network/Kademlia/Search.hs index 58c8fad8..593470c3 100644 --- a/src/Network/Kademlia/Search.hs +++ b/src/Network/Kademlia/Search.hs | |||
@@ -60,7 +60,7 @@ data SearchState nid addr tok ni r = SearchState | |||
60 | searchPendingCount :: TVar Int | 60 | searchPendingCount :: TVar Int |
61 | -- | Nodes scheduled to be queried. | 61 | -- | Nodes scheduled to be queried. |
62 | , searchQueued :: TVar (MinMaxPSQ ni nid) | 62 | , searchQueued :: TVar (MinMaxPSQ ni nid) |
63 | -- | The nearest K nodes that issued a reply. | 63 | -- | The nearest (K - α) nodes that issued a reply. |
64 | , searchInformant :: TVar (MinMaxPSQ' ni nid (Maybe tok)) | 64 | , searchInformant :: TVar (MinMaxPSQ' ni nid (Maybe tok)) |
65 | -- | This tracks already-queried addresses so we avoid bothering them | 65 | -- | This tracks already-queried addresses so we avoid bothering them |
66 | -- again. XXX: We could probably keep only the pending queries in this | 66 | -- again. XXX: We could probably keep only the pending queries in this |
@@ -121,8 +121,17 @@ reset bkts qsearch target st = do | |||
121 | searchAlpha :: Int | 121 | searchAlpha :: Int |
122 | searchAlpha = 8 | 122 | searchAlpha = 8 |
123 | 123 | ||
124 | -- | 'searchK' should be larger than 'searchAlpha'. How much larger depends on | ||
125 | -- how fast the queries are. For Tox's much slower onion-routed queries, we | ||
126 | -- need to ensure that closer non-responding queries don't completely push out | ||
127 | -- farther away queries. | ||
128 | -- | ||
129 | -- For BitTorrent, setting them both 8 was not an issue, but that is no longer | ||
130 | -- supported because now the number of remembered informants is now the | ||
131 | -- difference between these two numbers. So, if searchK = 16 and searchAlpha = | ||
132 | -- 4, then the number of remembered query responses is 12. | ||
124 | searchK :: Int | 133 | searchK :: Int |
125 | searchK = 8 | 134 | searchK = 16 |
126 | 135 | ||
127 | sendQuery :: forall addr nid tok ni r. | 136 | sendQuery :: forall addr nid tok ni r. |
128 | ( Ord addr | 137 | ( Ord addr |
@@ -158,9 +167,10 @@ sendQuery Search{..} searchTarget searchResult sch@SearchState{..} (ni :-> d) = | |||
158 | | otherwise = MM.insertTake k n ( kademliaXor searchSpace searchTarget | 167 | | otherwise = MM.insertTake k n ( kademliaXor searchSpace searchTarget |
159 | $ kademliaLocation searchSpace n ) | 168 | $ kademliaLocation searchSpace n ) |
160 | q | 169 | q |
161 | qsize <- MM.size <$> readTVar searchQueued | 170 | qsize0 <- MM.size <$> readTVar searchQueued |
171 | let qsize = if qsize0 < searchK then searchK else qsize0 | ||
162 | modifyTVar searchQueued $ \q -> foldr (insertFoundNode qsize) q ns | 172 | modifyTVar searchQueued $ \q -> foldr (insertFoundNode qsize) q ns |
163 | modifyTVar searchInformant $ MM.insertTake' searchK ni tok d | 173 | modifyTVar searchInformant $ MM.insertTake' (searchK - searchAlpha) ni tok d |
164 | flip fix rs $ \loop -> \case | 174 | flip fix rs $ \loop -> \case |
165 | r:rs' -> do | 175 | r:rs' -> do |
166 | wanting <- searchResult r | 176 | wanting <- searchResult r |
@@ -178,7 +188,7 @@ searchIsFinished SearchState{ ..} = do | |||
178 | informants <- readTVar searchInformant | 188 | informants <- readTVar searchInformant |
179 | return $ cnt == 0 | 189 | return $ cnt == 0 |
180 | && ( MM.null q | 190 | && ( MM.null q |
181 | || ( MM.size informants >= searchK | 191 | || ( MM.size informants >= (searchK - searchAlpha) |
182 | && ( PSQ.prio (fromJust $ MM.findMax informants) | 192 | && ( PSQ.prio (fromJust $ MM.findMax informants) |
183 | <= PSQ.prio (fromJust $ MM.findMin q)))) | 193 | <= PSQ.prio (fromJust $ MM.findMin q)))) |
184 | 194 | ||
@@ -217,7 +227,7 @@ searchLoop sch@Search{..} target result s@SearchState{..} = do | |||
217 | Just (ni :-> d, q) | 227 | Just (ni :-> d, q) |
218 | | -- If there's fewer than /k/ informants and there's any | 228 | | -- If there's fewer than /k/ informants and there's any |
219 | -- node we haven't yet got a response from. | 229 | -- node we haven't yet got a response from. |
220 | (MM.size informants < searchK) && (cnt > 0 || not (MM.null q)) | 230 | (MM.size informants < searchK - searchAlpha) && (cnt > 0 || not (MM.null q)) |
221 | -- Or there's no informants yet at all. | 231 | -- Or there's no informants yet at all. |
222 | || MM.null informants | 232 | || MM.null informants |
223 | -- Or if the closest scheduled node is nearer than the | 233 | -- Or if the closest scheduled node is nearer than the |