{-# LANGUAGE OverloadedStrings #-} module Main where import Control.Monad import Control.Monad.IO.Class import Control.Monad.Trans.Resource import qualified Data.ByteString as B import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Char8 as BC import Data.Default import Data.Functor import Data.List import qualified Data.Map as M import Data.Monoid import qualified Database.LevelDB as LD import System.Exit import Test.Framework import Test.Framework.Providers.HUnit import Test.HUnit import qualified Data.NibbleString as N import Blockchain.Data.RLP import Blockchain.Database.MerklePatricia bigTest= [ ("00000000000000000000000000000000ffffffffffffffff0000000000000000", "90467269656e647320262046616d696c79"), ("00000000000000000000000000000000ffffffffffffffff0000000000000001", "8772656631323334"), ("00000000000000000000000000000000ffffffffffffffff0000000000000002", "04"), ("00000000000000000000000000000000ffffffffffffffff0000000000000003", "84548123a8"), ("0000000000000000000000000000000000000000000000000000000000000000", "974c696162696c69746965733a496e697469616c4c6f616e"), ("0000000000000000000000000000000000000000000000000000000000000001", "a0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7960"), ("0000000000000000000000000000000000000000000000000000000000000002", "83555344"), ("0000000000000000000000000000000000000000000000010000000000000000", "8f4173736574733a436865636b696e67"), ("0000000000000000000000000000000000000000000000010000000000000001", "830186a0"), ("0000000000000000000000000000000000000000000000010000000000000002", "83555344"), ("00000000000000000000000000000002ffffffffffffffff0000000000000003", "84548123a8") ] putKeyVals::MPDB->[(N.NibbleString, B.ByteString)]->ResourceT IO MPDB putKeyVals db [(k,v)] = putKeyVal db k (rlpEncode v) putKeyVals db ((k, v):rest) = do db'<- putKeyVal db k $ rlpEncode v putKeyVals db' rest verifyDBDataIntegrity::MPDB->[(N.NibbleString, B.ByteString)]->ResourceT IO () verifyDBDataIntegrity db valuesIn = do db2 <- putKeyVals db valuesIn --return (db, stateRoot2) valuesOut <- getKeyVals db2 (N.EvenNibbleString B.empty) liftIO $ assertEqual "roundtrip in-out db didn't match" (M.fromList $ fmap rlpEncode <$> valuesIn) (M.fromList valuesOut) return () testShortcutNodeDataInsert::Assertion testShortcutNodeDataInsert = do runResourceT $ do db <- openMPDB "/tmp/tmpDB" verifyDBDataIntegrity db [ (N.EvenNibbleString $ BC.pack "abcd", BC.pack "abcd"), (N.EvenNibbleString $ BC.pack "aefg", BC.pack "aefg") ] testShortcutNodeDataInsert2::Assertion testShortcutNodeDataInsert2 = do runResourceT $ do db <- openMPDB "/tmp/tmpDB" verifyDBDataIntegrity db [ (N.EvenNibbleString $ BC.pack "abcd", BC.pack "abcd"), (N.EvenNibbleString $ BC.pack "bb", BC.pack "bb") ] testFullNodeDataInsert::Assertion testFullNodeDataInsert = do runResourceT $ do db <- openMPDB "/tmp/tmpDB" verifyDBDataIntegrity db [ (N.EvenNibbleString $ BC.pack "abcd", BC.pack "abcd"), (N.EvenNibbleString $ BC.pack "bb", BC.pack "bb"), (N.EvenNibbleString $ BC.pack "aefg", BC.pack "aefg") ] testOther::Assertion testOther = do runResourceT $ do db <- openMPDB "/tmp/tmpDB" verifyDBDataIntegrity db [("", "abcd")] verifyDBDataIntegrity db [("0123", "dog"), ("0123", "cat")] verifyDBDataIntegrity db [("abcd", "abcd"), ("ab12", "bb"), ("ab21", "aefg")] verifyDBDataIntegrity db [("ab", "abcd"), ("bb", "bb"), ("cb", "aefg"), ("bc", "qq")] prefixIfNeeded::B.ByteString->B.ByteString prefixIfNeeded s | odd $ B.length s = "0" `B.append` s prefixIfNeeded s = s testBigTest::Assertion testBigTest = do runResourceT $ do db <- openMPDB "/tmp/tmpDB" verifyDBDataIntegrity db (fmap (fst . B16.decode . prefixIfNeeded) <$> bigTest) main::IO () main = defaultMainWithOpts [ testCase "ShortcutNodeData Insert" testShortcutNodeDataInsert, testCase "ShortcutNodeData2 Insert" testShortcutNodeDataInsert2, testCase "FullNodeData Insert" testFullNodeDataInsert, testCase "other" testOther, testCase "bigTest" testBigTest ] mempty