\chapter{State Format} \begin{code} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StrictData #-} module Network.Tox.SaveData ( SaveData (..) , Section (..) , NospamKeys (..) , Friends (..) ) where \end{code} The reference Tox implementation uses a custom binary format to save the state of a Tox client between restarts. This format is far from perfect and will be replaced eventually. For the sake of maintaining compatibility down the road, it is documented here. The binary encoding of all integer types in the state format is a fixed-width byte sequence with the integer encoded in Little Endian unless stated otherwise. \begin{code} import Control.Arrow (second) import Control.Monad (when) import Data.Binary (Binary (..)) import Data.Binary.Get (Get) import qualified Data.Binary.Get as Get import Data.Binary.Put (Put) import qualified Data.Binary.Put as Put import qualified Data.ByteString.Lazy as LBS import Data.MessagePack (MessagePack) import Data.Word (Word16, Word32, Word8) import GHC.Generics (Generic) import Network.Tox.Crypto.Key (PublicKey, SecretKey) import Network.Tox.Crypto.KeyPair (KeyPair (..)) import qualified Network.Tox.Crypto.KeyPair as KeyPair import Network.Tox.SaveData.Bytes (Bytes) import Network.Tox.SaveData.Conferences (Conferences) import Network.Tox.SaveData.DHT (DHT) import Network.Tox.SaveData.Friend (Friend) import Network.Tox.SaveData.Groups (Groups) import Network.Tox.SaveData.Nodes (Nodes) import qualified Network.Tox.SaveData.Util as Util import Test.QuickCheck.Arbitrary (Arbitrary (..), genericShrink) import qualified Test.QuickCheck.Gen as Gen \end{code} \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{4} & Zeroes \\ \texttt{4} & \texttt{uint32\_t} (0x15ED1B1F) \\ \texttt{?} & List of sections \\ \end{tabular} \begin{code} saveDataMagic :: Word32 saveDataMagic :: Word32 saveDataMagic = Word32 0x15ED1B1F newtype SaveData = SaveData [Section] deriving (SaveData -> SaveData -> Bool (SaveData -> SaveData -> Bool) -> (SaveData -> SaveData -> Bool) -> Eq SaveData forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: SaveData -> SaveData -> Bool $c/= :: SaveData -> SaveData -> Bool == :: SaveData -> SaveData -> Bool $c== :: SaveData -> SaveData -> Bool Eq, Int -> SaveData -> ShowS [SaveData] -> ShowS SaveData -> String (Int -> SaveData -> ShowS) -> (SaveData -> String) -> ([SaveData] -> ShowS) -> Show SaveData forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [SaveData] -> ShowS $cshowList :: [SaveData] -> ShowS show :: SaveData -> String $cshow :: SaveData -> String showsPrec :: Int -> SaveData -> ShowS $cshowsPrec :: Int -> SaveData -> ShowS Show, ReadPrec [SaveData] ReadPrec SaveData Int -> ReadS SaveData ReadS [SaveData] (Int -> ReadS SaveData) -> ReadS [SaveData] -> ReadPrec SaveData -> ReadPrec [SaveData] -> Read SaveData forall a. (Int -> ReadS a) -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a readListPrec :: ReadPrec [SaveData] $creadListPrec :: ReadPrec [SaveData] readPrec :: ReadPrec SaveData $creadPrec :: ReadPrec SaveData readList :: ReadS [SaveData] $creadList :: ReadS [SaveData] readsPrec :: Int -> ReadS SaveData $creadsPrec :: Int -> ReadS SaveData Read, (forall x. SaveData -> Rep SaveData x) -> (forall x. Rep SaveData x -> SaveData) -> Generic SaveData forall x. Rep SaveData x -> SaveData forall x. SaveData -> Rep SaveData x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep SaveData x -> SaveData $cfrom :: forall x. SaveData -> Rep SaveData x Generic) instance MessagePack SaveData instance Binary SaveData where get :: Get SaveData get = do Word32 zeroes <- Get Word32 Get.getWord32le Bool -> Get () -> Get () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (Word32 zeroes Word32 -> Word32 -> Bool forall a. Eq a => a -> a -> Bool /= Word32 0) (Get () -> Get ()) -> Get () -> Get () forall a b. (a -> b) -> a -> b $ String -> Get () forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> Get ()) -> String -> Get () forall a b. (a -> b) -> a -> b $ String "savedata should start with 32 zero-bits, but got " String -> ShowS forall a. [a] -> [a] -> [a] ++ Word32 -> String forall a. Show a => a -> String show Word32 zeroes Word32 magic <- Get Word32 Get.getWord32le Bool -> Get () -> Get () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (Word32 magic Word32 -> Word32 -> Bool forall a. Eq a => a -> a -> Bool /= Word32 saveDataMagic) (Get () -> Get ()) -> Get () -> Get () forall a b. (a -> b) -> a -> b $ String -> Get () forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> Get ()) -> String -> Get () forall a b. (a -> b) -> a -> b $ String "wrong magic number for savedata: " String -> ShowS forall a. [a] -> [a] -> [a] ++ Word32 -> String forall a. Show a => a -> String show Word32 magic String -> ShowS forall a. [a] -> [a] -> [a] ++ String " != " String -> ShowS forall a. [a] -> [a] -> [a] ++ Word32 -> String forall a. Show a => a -> String show Word32 saveDataMagic [Section] -> SaveData SaveData ([Section] -> SaveData) -> Get [Section] -> Get SaveData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Get [Section] getSections put :: SaveData -> Put put (SaveData [Section] sections) = do Word32 -> Put Put.putWord32le Word32 0 Word32 -> Put Put.putWord32le Word32 saveDataMagic [Section] -> Put putSections [Section] sections instance Arbitrary SaveData where arbitrary :: Gen SaveData arbitrary = [Section] -> SaveData SaveData ([Section] -> SaveData) -> ([Section] -> [Section]) -> [Section] -> SaveData forall b c a. (b -> c) -> (a -> b) -> a -> c . ([Section] -> [Section] -> [Section] forall a. [a] -> [a] -> [a] ++ [Section SectionEOF]) ([Section] -> SaveData) -> Gen [Section] -> Gen SaveData forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen [Section] forall a. Arbitrary a => Gen a arbitrary shrink :: SaveData -> [SaveData] shrink = (SaveData -> Bool) -> [SaveData] -> [SaveData] forall a. (a -> Bool) -> [a] -> [a] filter (\(SaveData [Section] ss) -> Section SectionEOF Section -> [Section] -> Bool forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [Section] ss) ([SaveData] -> [SaveData]) -> (SaveData -> [SaveData]) -> SaveData -> [SaveData] forall b c a. (b -> c) -> (a -> b) -> a -> c . SaveData -> [SaveData] forall a. (Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => a -> [a] genericShrink \end{code} \section{Sections} The core of the state format consists of a list of sections. Every section has its type and length specified at the beginning. In some cases, a section only contains one item and thus takes up the entire length of the section. This is denoted with '?'. \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{4} & \texttt{uint32\_t} Length of this section \\ \texttt{2} & \texttt{uint16\_t} Section type \\ \texttt{2} & \texttt{uint16\_t} (0x01CE) \\ \texttt{?} & Section \\ \end{tabular} \begin{code} sectionMagic :: Word16 sectionMagic :: Word16 sectionMagic = Word16 0x01CE \end{code} Section types: \begin{tabular}{l|l} Name & Value \\ \hline NospamKeys & 0x01 \\ DHT & 0x02 \\ Friends & 0x03 \\ Name & 0x04 \\ StatusMessage & 0x05 \\ Status & 0x06 \\ Groups & 0x07 \\ TcpRelays & 0x0A \\ PathNodes & 0x0B \\ Conferences & 0x14 \\ EOF & 0xFF \\ \end{tabular} \begin{code} getSections :: Get [Section] getSections :: Get [Section] getSections = Get [Section] go where go :: Get [Section] go = do (Int len, Word16 ty) <- Word16 -> Get (Int, Word16) Util.getSectionHeader Word16 sectionMagic let load :: (a -> Section) -> Get [Section] load a -> Section f = (:) (Section -> [Section] -> [Section]) -> Get Section -> Get ([Section] -> [Section]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (a -> Section f (a -> Section) -> Get a -> Get Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Int -> Get a -> Get a forall a. Int -> Get a -> Get a Get.isolate (Int -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Int len) Get a forall t. Binary t => Get t get) Get ([Section] -> [Section]) -> Get [Section] -> Get [Section] forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Get [Section] go case Word16 ty of Word16 0x01 -> (NospamKeys -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load NospamKeys -> Section SectionNospamKeys Word16 0x02 -> (DHT -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load DHT -> Section SectionDHT Word16 0x03 -> (Friends -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Friends -> Section SectionFriends Word16 0x04 -> (Bytes -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Bytes -> Section SectionName Word16 0x05 -> (Bytes -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Bytes -> Section SectionStatusMessage Word16 0x06 -> (Word8 -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Word8 -> Section SectionStatus Word16 0x07 -> (Groups -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Groups -> Section SectionGroups Word16 0x0A -> (Nodes -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Nodes -> Section SectionTcpRelays Word16 0x0B -> (Nodes -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Nodes -> Section SectionPathNodes Word16 0x14 -> (Conferences -> Section) -> Get [Section] forall a. Binary a => (a -> Section) -> Get [Section] load Conferences -> Section SectionConferences Word16 0xFF -> [Section] -> Get [Section] forall (m :: * -> *) a. Monad m => a -> m a return [Section SectionEOF] Word16 _ -> String -> Get [Section] forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> Get [Section]) -> String -> Get [Section] forall a b. (a -> b) -> a -> b $ Word16 -> String forall a. Show a => a -> String show Word16 ty putSections :: [Section] -> Put putSections :: [Section] -> Put putSections = (Section -> Put) -> [Section] -> Put forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ Section -> Put go where go :: Section -> Put go Section section = do let (Word16 ty, ByteString bytes) = (Put -> ByteString) -> (Word16, Put) -> (Word16, ByteString) forall (a :: * -> * -> *) b c d. Arrow a => a b c -> a (d, b) (d, c) second Put -> ByteString Put.runPut ((Word16, Put) -> (Word16, ByteString)) -> (Word16, Put) -> (Word16, ByteString) forall a b. (a -> b) -> a -> b $ Section -> (Word16, Put) putSection Section section Word16 -> Word32 -> Word16 -> Put Util.putSectionHeader Word16 sectionMagic (Int64 -> Word32 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int64 -> Word32) -> Int64 -> Word32 forall a b. (a -> b) -> a -> b $ ByteString -> Int64 LBS.length ByteString bytes) Word16 ty ByteString -> Put Put.putLazyByteString ByteString bytes putSection :: Section -> (Word16, Put) putSection = \case SectionNospamKeys NospamKeys x -> (Word16 0x01, NospamKeys -> Put forall t. Binary t => t -> Put put NospamKeys x) SectionDHT DHT x -> (Word16 0x02, DHT -> Put forall t. Binary t => t -> Put put DHT x) SectionFriends Friends x -> (Word16 0x03, Friends -> Put forall t. Binary t => t -> Put put Friends x) SectionName Bytes x -> (Word16 0x04, Bytes -> Put forall t. Binary t => t -> Put put Bytes x) SectionStatusMessage Bytes x -> (Word16 0x05, Bytes -> Put forall t. Binary t => t -> Put put Bytes x) SectionStatus Word8 x -> (Word16 0x06, Word8 -> Put forall t. Binary t => t -> Put put Word8 x) SectionGroups Groups x -> (Word16 0x07, Groups -> Put forall t. Binary t => t -> Put put Groups x) SectionTcpRelays Nodes x -> (Word16 0x0A, Nodes -> Put forall t. Binary t => t -> Put put Nodes x) SectionPathNodes Nodes x -> (Word16 0x0B, Nodes -> Put forall t. Binary t => t -> Put put Nodes x) SectionConferences Conferences x -> (Word16 0x14, Conferences -> Put forall t. Binary t => t -> Put put Conferences x) Section SectionEOF -> (Word16 0xFF, () -> Put forall (m :: * -> *) a. Monad m => a -> m a return ()) \end{code} Not every section listed above is required to be present in order to restore from a state file. Only NospamKeys is required. \subsection{Nospam and Keys (0x01)} \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{4} & \texttt{uint32\_t} Nospam \\ \texttt{32} & Long term public key \\ \texttt{32} & Long term secret key \\ \end{tabular} \input{src/Network/Tox/SaveData/DHT.lhs} \subsection{Friends (0x03)} This section contains a list of friends. A friend can either be a peer we've sent a friend request to or a peer we've accepted a friend request from. \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{?} & List of friends \\ \end{tabular} \input{src/Network/Tox/SaveData/Friend.lhs} \subsection{Name (0x04)} \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{?} & Name as a UTF-8 encoded string \\ \end{tabular} \subsection{Status Message (0x05)} \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{?} & Status message as a UTF-8 encoded string \\ \end{tabular} \subsection{Status (0x06)} \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{1} & \texttt{uint8\_t} User status (see also: \texttt{USERSTATUS}) \\ \end{tabular} \subsection{Tcp Relays (0x0A)} This section contains a list of TCP relays. \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{?} & List of TCP relays \\ \end{tabular} The structure of a TCP relay is the same as \texttt{Node Info}. Note: this means that the integers stored in these nodes are stored in Big Endian as well. \subsection{Path Nodes (0x0B)} This section contains a list of path nodes used for onion routing. \begin{tabular}{l|l} Length & Contents \\ \hline \texttt{?} & List of path nodes \\ \end{tabular} The structure of a path node is the same as \texttt{Node Info}. Note: this means that the integers stored in these nodes are stored in Big Endian as well. \input{src/Network/Tox/SaveData/Conferences.lhs} \subsection{EOF (0xFF)} This section indicates the end of the state file. This section doesn't have any content and thus its length is 0. \begin{code} data Section = SectionNospamKeys NospamKeys | SectionDHT DHT | SectionFriends Friends | SectionName Bytes | SectionStatusMessage Bytes | SectionStatus Word8 | SectionGroups Groups | SectionTcpRelays Nodes | SectionPathNodes Nodes | SectionConferences Conferences | SectionEOF deriving (Section -> Section -> Bool (Section -> Section -> Bool) -> (Section -> Section -> Bool) -> Eq Section forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Section -> Section -> Bool $c/= :: Section -> Section -> Bool == :: Section -> Section -> Bool $c== :: Section -> Section -> Bool Eq, Int -> Section -> ShowS [Section] -> ShowS Section -> String (Int -> Section -> ShowS) -> (Section -> String) -> ([Section] -> ShowS) -> Show Section forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Section] -> ShowS $cshowList :: [Section] -> ShowS show :: Section -> String $cshow :: Section -> String showsPrec :: Int -> Section -> ShowS $cshowsPrec :: Int -> Section -> ShowS Show, ReadPrec [Section] ReadPrec Section Int -> ReadS Section ReadS [Section] (Int -> ReadS Section) -> ReadS [Section] -> ReadPrec Section -> ReadPrec [Section] -> Read Section forall a. (Int -> ReadS a) -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a readListPrec :: ReadPrec [Section] $creadListPrec :: ReadPrec [Section] readPrec :: ReadPrec Section $creadPrec :: ReadPrec Section readList :: ReadS [Section] $creadList :: ReadS [Section] readsPrec :: Int -> ReadS Section $creadsPrec :: Int -> ReadS Section Read, (forall x. Section -> Rep Section x) -> (forall x. Rep Section x -> Section) -> Generic Section forall x. Rep Section x -> Section forall x. Section -> Rep Section x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep Section x -> Section $cfrom :: forall x. Section -> Rep Section x Generic) instance MessagePack Section instance Arbitrary Section where arbitrary :: Gen Section arbitrary = [Gen Section] -> Gen Section forall a. HasCallStack => [Gen a] -> Gen a Gen.oneof [ NospamKeys -> Section SectionNospamKeys (NospamKeys -> Section) -> Gen NospamKeys -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen NospamKeys forall a. Arbitrary a => Gen a arbitrary , DHT -> Section SectionDHT (DHT -> Section) -> Gen DHT -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen DHT forall a. Arbitrary a => Gen a arbitrary , Friends -> Section SectionFriends (Friends -> Section) -> Gen Friends -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Friends forall a. Arbitrary a => Gen a arbitrary , Bytes -> Section SectionName (Bytes -> Section) -> Gen Bytes -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Bytes forall a. Arbitrary a => Gen a arbitrary , Bytes -> Section SectionStatusMessage (Bytes -> Section) -> Gen Bytes -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Bytes forall a. Arbitrary a => Gen a arbitrary , Word8 -> Section SectionStatus (Word8 -> Section) -> Gen Word8 -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Word8 forall a. Arbitrary a => Gen a arbitrary , Groups -> Section SectionGroups (Groups -> Section) -> Gen Groups -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Groups forall a. Arbitrary a => Gen a arbitrary , Nodes -> Section SectionTcpRelays (Nodes -> Section) -> Gen Nodes -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Nodes forall a. Arbitrary a => Gen a arbitrary , Nodes -> Section SectionPathNodes (Nodes -> Section) -> Gen Nodes -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Nodes forall a. Arbitrary a => Gen a arbitrary , Conferences -> Section SectionConferences (Conferences -> Section) -> Gen Conferences -> Gen Section forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Conferences forall a. Arbitrary a => Gen a arbitrary ] shrink :: Section -> [Section] shrink = Section -> [Section] forall a. (Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => a -> [a] genericShrink data NospamKeys = NospamKeys { NospamKeys -> Word32 nospam :: Word32 , NospamKeys -> PublicKey publicKey :: PublicKey , NospamKeys -> SecretKey secretKey :: SecretKey } deriving (NospamKeys -> NospamKeys -> Bool (NospamKeys -> NospamKeys -> Bool) -> (NospamKeys -> NospamKeys -> Bool) -> Eq NospamKeys forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: NospamKeys -> NospamKeys -> Bool $c/= :: NospamKeys -> NospamKeys -> Bool == :: NospamKeys -> NospamKeys -> Bool $c== :: NospamKeys -> NospamKeys -> Bool Eq, Int -> NospamKeys -> ShowS [NospamKeys] -> ShowS NospamKeys -> String (Int -> NospamKeys -> ShowS) -> (NospamKeys -> String) -> ([NospamKeys] -> ShowS) -> Show NospamKeys forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [NospamKeys] -> ShowS $cshowList :: [NospamKeys] -> ShowS show :: NospamKeys -> String $cshow :: NospamKeys -> String showsPrec :: Int -> NospamKeys -> ShowS $cshowsPrec :: Int -> NospamKeys -> ShowS Show, ReadPrec [NospamKeys] ReadPrec NospamKeys Int -> ReadS NospamKeys ReadS [NospamKeys] (Int -> ReadS NospamKeys) -> ReadS [NospamKeys] -> ReadPrec NospamKeys -> ReadPrec [NospamKeys] -> Read NospamKeys forall a. (Int -> ReadS a) -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a readListPrec :: ReadPrec [NospamKeys] $creadListPrec :: ReadPrec [NospamKeys] readPrec :: ReadPrec NospamKeys $creadPrec :: ReadPrec NospamKeys readList :: ReadS [NospamKeys] $creadList :: ReadS [NospamKeys] readsPrec :: Int -> ReadS NospamKeys $creadsPrec :: Int -> ReadS NospamKeys Read, (forall x. NospamKeys -> Rep NospamKeys x) -> (forall x. Rep NospamKeys x -> NospamKeys) -> Generic NospamKeys forall x. Rep NospamKeys x -> NospamKeys forall x. NospamKeys -> Rep NospamKeys x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep NospamKeys x -> NospamKeys $cfrom :: forall x. NospamKeys -> Rep NospamKeys x Generic) instance MessagePack NospamKeys instance Binary NospamKeys where get :: Get NospamKeys get = Word32 -> PublicKey -> SecretKey -> NospamKeys NospamKeys (Word32 -> PublicKey -> SecretKey -> NospamKeys) -> Get Word32 -> Get (PublicKey -> SecretKey -> NospamKeys) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Get Word32 Get.getWord32le Get (PublicKey -> SecretKey -> NospamKeys) -> Get PublicKey -> Get (SecretKey -> NospamKeys) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Get PublicKey forall t. Binary t => Get t get Get (SecretKey -> NospamKeys) -> Get SecretKey -> Get NospamKeys forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Get SecretKey forall t. Binary t => Get t get put :: NospamKeys -> Put put NospamKeys{Word32 SecretKey PublicKey secretKey :: SecretKey publicKey :: PublicKey nospam :: Word32 secretKey :: NospamKeys -> SecretKey publicKey :: NospamKeys -> PublicKey nospam :: NospamKeys -> Word32 ..} = do Word32 -> Put Put.putWord32le Word32 nospam PublicKey -> Put forall t. Binary t => t -> Put put PublicKey publicKey SecretKey -> Put forall t. Binary t => t -> Put put SecretKey secretKey instance Arbitrary NospamKeys where arbitrary :: Gen NospamKeys arbitrary = do KeyPair SecretKey sk PublicKey pk <- SecretKey -> KeyPair KeyPair.fromSecretKey (SecretKey -> KeyPair) -> Gen SecretKey -> Gen KeyPair forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen SecretKey forall a. Arbitrary a => Gen a arbitrary Word32 -> PublicKey -> SecretKey -> NospamKeys NospamKeys (Word32 -> PublicKey -> SecretKey -> NospamKeys) -> Gen Word32 -> Gen (PublicKey -> SecretKey -> NospamKeys) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen Word32 forall a. Arbitrary a => Gen a arbitrary Gen (PublicKey -> SecretKey -> NospamKeys) -> Gen PublicKey -> Gen (SecretKey -> NospamKeys) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> PublicKey -> Gen PublicKey forall (f :: * -> *) a. Applicative f => a -> f a pure PublicKey pk Gen (SecretKey -> NospamKeys) -> Gen SecretKey -> Gen NospamKeys forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> SecretKey -> Gen SecretKey forall (f :: * -> *) a. Applicative f => a -> f a pure SecretKey sk shrink :: NospamKeys -> [NospamKeys] shrink = NospamKeys -> [NospamKeys] forall a. (Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => a -> [a] genericShrink newtype Friends = Friends [Friend] deriving (Friends -> Friends -> Bool (Friends -> Friends -> Bool) -> (Friends -> Friends -> Bool) -> Eq Friends forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Friends -> Friends -> Bool $c/= :: Friends -> Friends -> Bool == :: Friends -> Friends -> Bool $c== :: Friends -> Friends -> Bool Eq, Int -> Friends -> ShowS [Friends] -> ShowS Friends -> String (Int -> Friends -> ShowS) -> (Friends -> String) -> ([Friends] -> ShowS) -> Show Friends forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Friends] -> ShowS $cshowList :: [Friends] -> ShowS show :: Friends -> String $cshow :: Friends -> String showsPrec :: Int -> Friends -> ShowS $cshowsPrec :: Int -> Friends -> ShowS Show, ReadPrec [Friends] ReadPrec Friends Int -> ReadS Friends ReadS [Friends] (Int -> ReadS Friends) -> ReadS [Friends] -> ReadPrec Friends -> ReadPrec [Friends] -> Read Friends forall a. (Int -> ReadS a) -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a readListPrec :: ReadPrec [Friends] $creadListPrec :: ReadPrec [Friends] readPrec :: ReadPrec Friends $creadPrec :: ReadPrec Friends readList :: ReadS [Friends] $creadList :: ReadS [Friends] readsPrec :: Int -> ReadS Friends $creadsPrec :: Int -> ReadS Friends Read, (forall x. Friends -> Rep Friends x) -> (forall x. Rep Friends x -> Friends) -> Generic Friends forall x. Rep Friends x -> Friends forall x. Friends -> Rep Friends x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep Friends x -> Friends $cfrom :: forall x. Friends -> Rep Friends x Generic) instance MessagePack Friends instance Binary Friends where get :: Get Friends get = [Friend] -> Friends Friends ([Friend] -> Friends) -> Get [Friend] -> Get Friends forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Get [Friend] forall a. (Binary a, Show a) => Get [a] Util.getList put :: Friends -> Put put (Friends [Friend] xs) = (Friend -> Put) -> [Friend] -> Put forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ Friend -> Put forall t. Binary t => t -> Put put [Friend] xs instance Arbitrary Friends where arbitrary :: Gen Friends arbitrary = [Friend] -> Friends Friends ([Friend] -> Friends) -> Gen [Friend] -> Gen Friends forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Gen [Friend] forall a. Arbitrary a => Gen a arbitrary shrink :: Friends -> [Friends] shrink = Friends -> [Friends] forall a. (Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => a -> [a] genericShrink \end{code}