summaryrefslogtreecommitdiff
path: root/src/Network/Kademlia/CommonAPI.hs
blob: 601be5d84ffd3b95c3cfad14614c9e7efef98f3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{-# LANGUAGE ExistentialQuantification #-}
module Network.Kademlia.CommonAPI where


import Control.Concurrent
import Control.Concurrent.STM
import Data.Aeson                  as J (FromJSON, ToJSON)
import Data.Hashable
import qualified Data.Map          as Map
import Data.Serialize              as S
import qualified Data.Set          as Set
import Data.Time.Clock.POSIX
import Data.Typeable

import Network.Kademlia.Search
import Network.Kademlia.Routing as R
import Crypto.Tox (SecretKey,PublicKey)

data DHT = forall nid ni. ( Show     ni
                          , Read     ni
                          , ToJSON   ni
                          , FromJSON ni
                          , Ord      ni
                          , Hashable ni
                          , Show     nid
                          , Ord      nid
                          , Hashable nid
                          , Typeable ni
                          , S.Serialize nid
                          ) =>
    DHT
    { dhtBuckets       :: TVar (BucketList ni)
    , dhtSecretKey     :: STM (Maybe SecretKey)
    , dhtPing          :: Map.Map String (DHTPing ni)
    , dhtQuery         :: Map.Map String (DHTQuery nid ni)
    , dhtAnnouncables  :: Map.Map String (DHTAnnouncable nid)
    , dhtParseId       :: String -> Either String nid
    , dhtSearches      :: TVar (Map.Map (String,nid) (DHTSearch nid ni))
    , dhtFallbackNodes :: IO [ni]
    , dhtBootstrap     :: [ni] -> [ni] -> IO ()
    }

data DHTQuery nid ni = forall addr r tok.
                        ( Ord addr
                        , Typeable r
                        , Typeable tok
                        , Typeable ni
                        ) => DHTQuery
    { qsearch     :: Search nid addr tok ni r
    , qhandler    :: ni -> nid -> IO ([ni], [r], Maybe tok) -- ^ Invoked on local node, when there is no query destination.
    , qshowR      :: r -> String
    , qshowTok    :: tok -> Maybe String
    }

data DHTAnnouncable nid = forall dta tok ni r.
                        ( Show r
                        , Typeable dta -- information being announced
                        , Typeable tok -- token
                        , Typeable r   -- search result
                        , Typeable ni  -- node
                        ) => DHTAnnouncable
    { announceParseData    :: String -> Either String dta
    , announceParseToken   :: dta -> String -> Either String tok
    , announceParseAddress :: String -> Either String ni
    , announceSendData     :: Either ( String {- search name -}
                                     , String -> Either String r
                                     , PublicKey {- me -} -> dta -> r -> IO ())
                                     (dta -> tok -> Maybe ni -> IO (Maybe r))
    , announceInterval     :: POSIXTime
    , announceTarget       :: dta -> nid
    }

data DHTSearch nid ni = forall addr tok r. DHTSearch
    { searchThread     :: ThreadId
    , searchState      :: SearchState nid addr tok ni r
    , searchShowTok    :: tok -> Maybe String
    , searchResults    :: TVar (Set.Set String)
    }

data DHTPing ni = forall r. DHTPing
    { pingQuery :: [String] -> ni -> IO (Maybe r)
    , pingShowResult :: r -> String
    }