trust-chain 0.1.2.0 → 0.1.3.0
raw patch · 3 files changed
+35/−15 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.TrustChain: claimants :: (Ord k, Ord a) => (a -> k) -> [Claim a] -> Map k (Map a (Set [PublicKey]))
+ Data.TrustChain: instance (GHC.Read.Read e, GHC.Read.Read a) => GHC.Read.Read (Data.TrustChain.Inconsistency e a)
+ Data.TrustChain: instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Data.TrustChain.Inconsistency e a)
+ Data.TrustChain: instance GHC.Read.Read a => GHC.Read.Read (Data.TrustChain.Claim a)
+ Data.TrustChain: instance GHC.Show.Show a => GHC.Show.Show (Data.TrustChain.Claim a)
Files
- src/Data/TrustChain.hs +15/−2
- test/Test.hs +19/−12
- trust-chain.cabal +1/−1
src/Data/TrustChain.hs view
@@ -19,6 +19,7 @@ -- * Claims , Claim (..) , claims+ , claimants -- * Index and Merge , assignments -- * Inconsistencies@@ -109,13 +110,13 @@ -- | -- A path through the trust chain. data Claim a = Claim [PublicKey] a- deriving (Eq, Ord, Typeable, Generic, Binary)+ deriving (Eq, Ord, Show, Read, Typeable, Generic, Binary) -- | -- An inconsistency with the various accounts in the trust chain data Inconsistency e a = IncompatibleClaim e (Claim a) [Claim a]- deriving (Eq, Ord, Typeable, Generic, Binary)+ deriving (Eq, Ord, Show, Read, Typeable, Generic, Binary) -- | -- Extract all of the claims from the trust chain.@@ -123,6 +124,18 @@ claims = \case Trustless a -> [Claim [] a] TrustProxy s -> (\(Claim ps a) -> Claim (signedBy s : ps) a) <$> foldMap claims (signed s)++-- |+-- Index the claimants by what they're claiming, using the given indexing function.+--+-- The mental model here should something like @k = PublicKey@ and @a = Person@. What+-- we're doing is figuring out, for every different 'PublicKey' contained in the @Trustless@+-- node in our 'TrustChain', all of the different variations and series of signatures which lead up to those variations (along with who assented to those accounts).+--+-- There is no 'Merge'ing here, in particular. This is the way to splay out all of the different realities and the sequences of+-- 'PublicKey' which signed that particular variation (at one time or another).+claimants :: (Ord k, Ord a) => (a -> k) -> [Claim a] -> Map k (Map a (Set [PublicKey]))+claimants i cs = Map.fromListWith (Map.unionWith (<>)) [ (k, Map.singleton a (Set.singleton ps)) | Claim ps a <- cs, let k = i a ] -- | -- Extract all of the assignments from the trust chain, unifying information contained
test/Test.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}@@ -21,6 +22,10 @@ requires msg = mapM_ (uncurry go) . zip [1..] where go x y = if y then pure () else putStrLn (msg <> ": " <> show x) >> exitFailure +eq :: (Eq a, Show a) => String -> [(a, a)] -> IO ()+eq msg = mapM_ (uncurry go) . zip [1..] where+ go x (a, b) = if a == b then pure () else putStrLn (msg <> ": " <> show x <> ": " <> show a <> " /= " <> show b) >> exitFailure+ main :: IO () main = do privateKey0 <- generatePrivateKey KeySize256@@ -28,21 +33,23 @@ let trustChain0 :: TrustChain [] String = Trustless "Hello" trustChain1 <- mkTrustProxy privateKey0 [mkTrustless "Hi", trustChain0] trustChain2 <- mkTrustProxy privateKey1 [mkTrustless "Hey", trustChain1]- let roundTrip f g x = x == f (g x)+ let roundTrip f g x = (x, f (g x)) requires "validTrustChain" [ validTrustChain trustChain0 , validTrustChain trustChain1 , validTrustChain trustChain2 ]- requires "claims"- [ claims trustChain0 == [Claim [] "Hello"]- , claims trustChain1 == [Claim [privateToPublic privateKey0] "Hi", Claim [privateToPublic privateKey0] "Hello"]- , claims trustChain2 == [Claim [privateToPublic privateKey1] "Hey", Claim [privateToPublic privateKey1, privateToPublic privateKey0] "Hi", Claim [privateToPublic privateKey1, privateToPublic privateKey0] "Hello"] + eq "claimants"+ [ (claimants id (claims trustChain0), Map.fromList [("Hello", Map.fromList [("Hello", Set.singleton [])])]) ]+ eq "claims"+ [ (claims trustChain0, [Claim [] "Hello"])+ , (claims trustChain1, [Claim [privateToPublic privateKey0] "Hi", Claim [privateToPublic privateKey0] "Hello"])+ , (claims trustChain2, [Claim [privateToPublic privateKey1] "Hey", Claim [privateToPublic privateKey1, privateToPublic privateKey0] "Hi", Claim [privateToPublic privateKey1, privateToPublic privateKey0] "Hello"]) ]- requires "assignments"- [ assignments id (required id .? ["bad id"]) (claims trustChain0) == Right (Map.fromList [("Hello", "Hello")])+ eq "assignments"+ [ (assignments id (required @[String] id .? ["bad id"]) (claims trustChain0), Right (Map.fromList [("Hello", "Hello")])) ]- requires "encode/decode" $ map (roundTrip decode encode) [trustChain0, trustChain1, trustChain2]+ eq "encode/decode" $ map (roundTrip decode encode) [trustChain0, trustChain1, trustChain2] person type Time = Integer@@ -53,7 +60,7 @@ , emails :: Set Text , posts :: Set (Time, Text) }- deriving (Eq, Ord, Binary, Generic)+ deriving (Eq, Ord, Binary, Generic, Show, Read) mergePerson :: Merge [String] Person Person mergePerson =@@ -74,7 +81,7 @@ tc1 <- mkTrustProxy privateKey1 [Trustless myfriend] tc0' <- mkTrustProxy privateKey0 [tc0, tc1] tc1' <- mkTrustProxy privateKey1 [tc0, tc1]- requires "person"- [ assignments pubKey mergePerson (claims tc1') == assignments pubKey mergePerson (claims tc0')- , assignments pubKey mergePerson (claims tc0') == Right (Map.fromList [(privateToPublic privateKey0, myself), (privateToPublic privateKey1, myfriend)])+ eq "person"+ [ (assignments pubKey mergePerson (claims tc1'), assignments pubKey mergePerson (claims tc0'))+ , (assignments pubKey mergePerson (claims tc0'), Right (Map.fromList [(privateToPublic privateKey0, myself), (privateToPublic privateKey1, myfriend)])) ]
trust-chain.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: trust-chain-version: 0.1.2.0+version: 0.1.3.0 category: Cryptography, Crypto synopsis: An implementation of a trust chain license: MIT