diff options
Diffstat (limited to 'SybilLimit.hs')
-rw-r--r-- | SybilLimit.hs | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/SybilLimit.hs b/SybilLimit.hs index 8324b85..bb0a54f 100644 --- a/SybilLimit.hs +++ b/SybilLimit.hs | |||
@@ -1,16 +1,17 @@ | |||
1 | {-# LANGUAGE StandaloneDeriving #-} | 1 | {-# LANGUAGE StandaloneDeriving #-} |
2 | module SybilLimit where | 2 | module SybilLimit where |
3 | 3 | ||
4 | import Data.List | 4 | import Data.List ( foldl' ) |
5 | import Data.IntMap.Strict ( IntMap, (!) ) | 5 | import Data.IntMap.Strict ( IntMap, (!) ) |
6 | import qualified Data.IntMap.Strict as IntMap | 6 | import qualified Data.IntMap.Strict as IntMap |
7 | import Data.Traversable | 7 | import Data.Traversable ( sequenceA ) |
8 | import Control.Applicative | 8 | import Control.Applicative |
9 | -- import System.Random | 9 | -- import System.Random |
10 | import Stochastic | ||
11 | import Data.Map.Strict ( Map ) | 10 | import Data.Map.Strict ( Map ) |
12 | import qualified Data.Map as Map | 11 | import qualified Data.Map as Map |
13 | 12 | ||
13 | import Stochastic | ||
14 | |||
14 | data NodeId | 15 | data NodeId |
15 | 16 | ||
16 | deriving instance Ord NodeId | 17 | deriving instance Ord NodeId |
@@ -22,7 +23,11 @@ data ThisNode = ThisNode | |||
22 | , friendById :: Map NodeId Int | 23 | , friendById :: Map NodeId Int |
23 | , routeTails :: IntMap (NodeId,NodeId) | 24 | , routeTails :: IntMap (NodeId,NodeId) |
24 | -- ^ Terminal edge by instance number. | 25 | -- ^ Terminal edge by instance number. |
26 | , tailCounters :: IntMap Int | ||
27 | -- ^ verificaiton counter by instance number. | ||
25 | , routeCount :: Int | 28 | , routeCount :: Int |
29 | -- ^ The r parameter of SybilLimit. | ||
30 | , pendingVerifications :: Map NodeId PendingIntersection | ||
26 | } | 31 | } |
27 | 32 | ||
28 | data FriendNode = FriendNode | 33 | data FriendNode = FriendNode |
@@ -37,6 +42,14 @@ data FriendNode = FriendNode | |||
37 | } | 42 | } |
38 | 43 | ||
39 | 44 | ||
45 | -- | When 'iPendingTails' is empty, the intersection condition is passed if and | ||
46 | -- only if 'iVerifiedTails' is not empty. | ||
47 | data PendingIntersection = PendingIntersection | ||
48 | { iSuspect :: NodeId | ||
49 | , iPendingTails :: Map (NodeId,NodeId) () | ||
50 | , iVerifiedTails :: Map (NodeId,NodeId) () | ||
51 | } | ||
52 | |||
40 | data PeerMessage | 53 | data PeerMessage |
41 | = ForwardRRMessage { rrRoute :: Int | 54 | = ForwardRRMessage { rrRoute :: Int |
42 | , rrCount :: Int | 55 | , rrCount :: Int |
@@ -44,8 +57,19 @@ data PeerMessage | |||
44 | | BackwardRRMessage { rrRoute :: Int | 57 | | BackwardRRMessage { rrRoute :: Int |
45 | , rrCount :: Int | 58 | , rrCount :: Int |
46 | , rrTail :: (NodeId,NodeId) } | 59 | , rrTail :: (NodeId,NodeId) } |
60 | | RegistrationQuery { rrSuspect :: NodeId | ||
61 | , rrRegisteredFrom :: NodeId } | ||
62 | | RegistrationResponse { rrSuspect :: NodeId | ||
63 | , rrRegisteredFrom :: NodeId | ||
64 | , rrValidRegistration :: Bool } | ||
65 | |||
66 | {- | ||
67 | | CredMessage SuspectCred | ||
47 | 68 | ||
69 | data SuspectCred = SuspectCred { suspectId :: NodeId | ||
70 | , suspectTails :: IntMap (NodeId,NodeId) } | ||
48 | 71 | ||
72 | -} | ||
49 | 73 | ||
50 | friendNode :: NodeId -> FriendNode | 74 | friendNode :: NodeId -> FriendNode |
51 | friendNode nid = FriendNode nid IntMap.empty IntMap.empty Nothing | 75 | friendNode nid = FriendNode nid IntMap.empty IntMap.empty Nothing |
@@ -105,6 +129,7 @@ updateRoute i (k,j) fs = jfromk $ ktoj fs | |||
105 | setFrom i x f = f { routesFrom = IntMap.insert i x (routesFrom f)} | 129 | setFrom i x f = f { routesFrom = IntMap.insert i x (routesFrom f)} |
106 | 130 | ||
107 | 131 | ||
132 | forwardMessage :: ThisNode -> (FriendNode -> IntMap Int) -> (NodeId,PeerMessage) -> (NodeId, PeerMessage) | ||
108 | forwardMessage me next (srcId,msg) = msg' | 133 | forwardMessage me next (srcId,msg) = msg' |
109 | where msg' = ( dest, msg { rrCount = rrCount msg + 1 } ) | 134 | where msg' = ( dest, msg { rrCount = rrCount msg + 1 } ) |
110 | srcno = friendById me Map.! srcId | 135 | srcno = friendById me Map.! srcId |
@@ -112,6 +137,27 @@ forwardMessage me next (srcId,msg) = msg' | |||
112 | dest = friendId (friends me ! destno) | 137 | dest = friendId (friends me ! destno) |
113 | 138 | ||
114 | reactToMessage :: Int -> (NodeId,PeerMessage) -> ThisNode -> (ThisNode, [(NodeId,PeerMessage)]) | 139 | reactToMessage :: Int -> (NodeId,PeerMessage) -> ThisNode -> (ThisNode, [(NodeId,PeerMessage)]) |
140 | reactToMessage w (srcId, msg@(RegistrationResponse {})) me = (me', []) | ||
141 | where | ||
142 | me' = me { pendingVerifications = vs' } | ||
143 | vs' :: Map NodeId PendingIntersection | ||
144 | vs' = Map.adjust adj (rrSuspect msg) $ pendingVerifications me | ||
145 | adj p = p { iPendingTails = Map.delete (rrRegisteredFrom msg, srcId) | ||
146 | $ iPendingTails p | ||
147 | , iVerifiedTails = | ||
148 | if rrValidRegistration msg then v' else iVerifiedTails p | ||
149 | } | ||
150 | where v' = Map.insert (rrRegisteredFrom msg, srcId) () | ||
151 | $ iVerifiedTails p | ||
152 | |||
153 | reactToMessage w (srcId, msg@(RegistrationQuery {})) me = (me, [(srcId,resp)]) | ||
154 | where | ||
155 | resp = RegistrationResponse { rrSuspect = rrSuspect msg | ||
156 | , rrRegisteredFrom = rrRegisteredFrom msg | ||
157 | , rrValidRegistration = check } | ||
158 | key = friendById me Map.! rrRegisteredFrom msg | ||
159 | check = registeredTerminal (friends me ! key) == Just (rrSuspect msg) | ||
160 | |||
115 | reactToMessage w (srcId, msg) me = | 161 | reactToMessage w (srcId, msg) me = |
116 | if rrCount msg == w then terminate else (me, [forwardMessage me next (srcId,msg)]) | 162 | if rrCount msg == w then terminate else (me, [forwardMessage me next (srcId,msg)]) |
117 | where | 163 | where |
@@ -134,3 +180,12 @@ reactToMessage w (srcId, msg) me = | |||
134 | $ routeTails me | 180 | $ routeTails me |
135 | } | 181 | } |
136 | 182 | ||
183 | {- | ||
184 | intersectionSatisfied :: SuspectCred -> ThisNode -> Bool | ||
185 | intersectionSatisfied suspect me = todo | ||
186 | where | ||
187 | x = IntMap.filter isSuspectTail $ routeTails me | ||
188 | stails = IntMap.elems $ suspectTails suspect | ||
189 | isSuspectTail tl = tl `elem` stails | ||
190 | -} | ||
191 | |||