Skip to content
This repository was archived by the owner on Mar 1, 2019. It is now read-only.

Commit e2b5ea0

Browse files
Merge pull request input-output-hk/cardano-sl#3628 from input-output-hk/kderme/CBR-436
[CBR-436][CBR-435] Adds --wallet-rebuild-db option and cleans some tests
2 parents 0db447b + 7de9747 commit e2b5ea0

File tree

4 files changed

+76
-83
lines changed

4 files changed

+76
-83
lines changed

src/Cardano/Wallet/Action.hs

+7-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import Cardano.Wallet.Kernel.Migration (migrateLegacyDataLayer)
2626
import qualified Cardano.Wallet.Kernel.Mode as Kernel.Mode
2727
import qualified Cardano.Wallet.Kernel.NodeStateAdaptor as NodeStateAdaptor
2828
import Cardano.Wallet.Server.CLI (NewWalletBackendParams,
29-
getFullMigrationFlag, getWalletDbOptions, walletDbPath)
29+
getFullMigrationFlag, getWalletDbOptions, walletDbPath,
30+
walletRebuildDb)
3031
import Cardano.Wallet.Server.Middlewares (throttleMiddleware,
3132
withDefaultHeader)
3233
import qualified Cardano.Wallet.Server.Plugins as Plugins
@@ -55,10 +56,13 @@ actionWithWallet params genesisConfig walletConfig txpConfig ntpConfig nodeParam
5556
nodeRes
5657
ntpStatus
5758
liftIO $ Keystore.bracketLegacyKeystore userSecret $ \keystore -> do
58-
let dbPath = walletDbPath (getWalletDbOptions params)
59-
let dbMode = Kernel.UseFilePath (Kernel.DatabasePaths {
59+
let dbOptions = getWalletDbOptions params
60+
let dbPath = walletDbPath dbOptions
61+
let rebuildDB = walletRebuildDb dbOptions
62+
let dbMode = Kernel.UseFilePath (Kernel.DatabaseOptions {
6063
Kernel.dbPathAcidState = dbPath <> "-acid"
6164
, Kernel.dbPathMetadata = dbPath <> "-sqlite.sqlite3"
65+
, Kernel.dbRebuild = rebuildDB
6266
})
6367
WalletLayer.Kernel.bracketPassiveWallet dbMode logMessage' keystore nodeState $ \walletLayer passiveWallet -> do
6468
migrateLegacyDataLayer passiveWallet dbPath (getFullMigrationFlag params)

src/Cardano/Wallet/Kernel.hs

+17-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module Cardano.Wallet.Kernel (
1010
, bracketPassiveWallet
1111
-- * Configuration
1212
, DatabaseMode(..)
13-
, DatabasePaths(..)
13+
, DatabaseOptions(..)
1414
, useDefaultPaths
1515
, defaultAcidStatePath
1616
, defaultSqlitePath
@@ -32,6 +32,7 @@ import Data.Acid (AcidState, createArchive, createCheckpoint,
3232
openLocalStateFrom)
3333
import Data.Acid.Memory (openMemoryState)
3434
import qualified Data.Map.Strict as Map
35+
import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
3536

3637
import Pos.Chain.Txp (TxAux (..))
3738
import Pos.Crypto (ProtocolMagic)
@@ -60,23 +61,25 @@ data DatabaseMode
6061
-- ^ This constructor is used when you want to run the database in memory.
6162
-- This is useful for testing as it does not require a disk. The database
6263
-- will start out with the fresh, default, uninitialized state.
63-
| UseFilePath DatabasePaths
64+
| UseFilePath DatabaseOptions
6465
-- ^ Load the databases from the given paths.
6566

6667
-- | A configuration type for specifying where to load the databases from.
67-
data DatabasePaths
68-
= DatabasePaths
68+
data DatabaseOptions
69+
= DatabaseOptions
6970
{ dbPathAcidState :: FilePath
7071
-- ^ The path for the @acid-state@ database.
7172
, dbPathMetadata :: FilePath
7273
-- ^ This path is used for the SQLite database that contains the transaction
7374
-- metadata.
75+
, dbRebuild :: Bool
76+
-- ^ Whether we want to rebuild the db in case it exists.
7477
} deriving (Eq, Show)
7578

76-
-- | Use the default paths on disk. See 'DatabasePaths' for more details.
79+
-- | Use the default paths on disk. See 'DatabaseOptions' for more details.
7780
useDefaultPaths :: DatabaseMode
7881
useDefaultPaths =
79-
UseFilePath $ DatabasePaths defaultAcidStatePath defaultSqlitePath
82+
UseFilePath $ DatabaseOptions defaultAcidStatePath defaultSqlitePath False
8083

8184
defaultAcidStatePath :: FilePath
8285
defaultAcidStatePath = "wallet-db-acid"
@@ -119,8 +122,14 @@ handlesOpen mode =
119122
metadb <- openMetaDB ":memory:"
120123
migrateMetaDB metadb
121124
return $ Handles db metadb
122-
UseFilePath (DatabasePaths acidDb sqliteDb) -> do
125+
UseFilePath (DatabaseOptions acidDb sqliteDb rebuildDB) -> do
126+
let deleteMaybe fp = do
127+
when rebuildDB $ do
128+
itsHere <- doesDirectoryExist fp
129+
when itsHere $ removeDirectoryRecursive fp
130+
deleteMaybe acidDb
123131
db <- openLocalStateFrom acidDb defDB
132+
deleteMaybe sqliteDb
124133
metadb <- openMetaDB sqliteDb
125134
migrateMetaDB metadb
126135
return $ Handles db metadb
@@ -131,7 +140,7 @@ handlesClose dbMode (Handles acidDb meta) = do
131140
case dbMode of
132141
UseInMemory ->
133142
pure ()
134-
UseFilePath (DatabasePaths _ _) -> do
143+
UseFilePath DatabaseOptions{} -> do
135144
createCheckpoint acidDb
136145
createArchive acidDb
137146

src/Cardano/Wallet/Server/Plugins/AcidState.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import System.FilePath ((</>))
1616

1717
import Pos.Util.Wlog (logError, logInfo)
1818

19-
import Cardano.Wallet.Kernel (DatabaseMode (..), DatabasePaths (..))
19+
import Cardano.Wallet.Kernel (DatabaseMode (..), DatabaseOptions (..))
2020
import qualified Cardano.Wallet.Kernel.Mode as Kernel
2121

2222

test/unit/Test/Spec/Addresses.hs

+51-71
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ import Pos.Crypto (EncryptedSecretKey, emptyPassphrase, firstHardened,
2424
import Cardano.Wallet.API.Request (RequestParams (..))
2525
import Cardano.Wallet.API.Request.Pagination (Page (..),
2626
PaginationParams (..), PerPage (..))
27-
import Cardano.Wallet.API.Response (SliceOf (..),
28-
WalletResponse (wrData))
27+
import Cardano.Wallet.API.Response (SliceOf (..), WalletResponse (..))
2928
import Cardano.Wallet.API.V1.Handlers.Addresses as Handlers
3029
import qualified Cardano.Wallet.API.V1.Types as V1
3130
import qualified Cardano.Wallet.Kernel.Addresses as Kernel
@@ -126,11 +125,14 @@ prepareAddressFixture n = do
126125
let SliceOf{..} = Addresses.getAddresses (RequestParams pp) db'
127126
return . map AddressFixture $ paginatedSlice
128127

128+
newtype DesiredNewAccounts = DesiredNewAccs Int
129+
newtype DesiredNewAddresses = DesiredNewAddrs Int
130+
129131
prepareAddressesFixture
130-
:: Int -- ^ Number of Accounts to create.
131-
-> Int -- ^ Number of 'Address per account to create.
132-
-> Fixture.GenPassiveWalletFixture (M.Map V1.AccountIndex [V1.WalletAddress])
133-
prepareAddressesFixture acn adn = do
132+
:: DesiredNewAccounts -- ^ Number of Accounts to create.
133+
-> DesiredNewAddresses -- ^ Number of Address per account to create.
134+
-> Fixture.GenPassiveWalletFixture (M.Map V1.AccountIndex [V1.WalletAddress], Int)
135+
prepareAddressesFixture (DesiredNewAccs acn) (DesiredNewAddrs adn) = do
134136
spendingPassword <- Fixture.genSpendingPassword
135137
newWalletRq <- WalletLayer.CreateWallet <$> Wallets.genNewWalletRq spendingPassword
136138
return $ \pw -> do
@@ -152,11 +154,9 @@ prepareAddressesFixture acn adn = do
152154
Left e -> error (show e)
153155
Right addr -> return (accId, addr)
154156
res <- mapM insertAddresses accounts
155-
return $ M.fromList res
156-
157-
expectedNumber :: Int -> Int -> Int
158-
expectedNumber acc adr = (acc + 1)*(adr + 1) - acc
159-
157+
-- This takes into account that each wallet creates by default one account, which has
158+
-- one address.
159+
return $ (M.fromList res, (acn + 1)*(adn + 1) - acn)
160160

161161
withFixture :: ( Keystore.Keystore
162162
-> PassiveWalletLayer IO
@@ -180,11 +180,13 @@ withAddressFixtures n =
180180
Fixture.withPassiveWalletFixture $ do
181181
prepareAddressFixture n
182182

183-
withAddressesFixtures :: Int -> Int ->
184-
( Keystore.Keystore
183+
withAddressesFixtures
184+
:: DesiredNewAccounts
185+
-> DesiredNewAddresses
186+
-> ( Keystore.Keystore
185187
-> PassiveWalletLayer IO
186188
-> PassiveWallet
187-
-> M.Map V1.AccountIndex [V1.WalletAddress]
189+
-> (M.Map V1.AccountIndex [V1.WalletAddress], Int)
188190
-> IO a
189191
)
190192
-> PropertyM IO a
@@ -396,9 +398,10 @@ spec = describe "Addresses" $ do
396398
pure (toBeCheckedAddresses === correctAddresses)
397399

398400
describe "Address listing with multiple Accounts (Servant)" $ do
401+
let rootId = addrRoot . V1.unV1 . V1.addrId
399402
prop "page 0, per page 0" $ withMaxSuccess 20 $ do
400403
monadicIO $
401-
withAddressesFixtures 4 4 $ \_ layer _ _ -> do
404+
withAddressesFixtures (DesiredNewAccs 4) (DesiredNewAddrs 4) $ \_ layer _ _ -> do
402405
let pp = PaginationParams (Page 0) (PerPage 0)
403406
res <- runExceptT $ runHandler' $ do
404407
Handlers.listAddresses layer (RequestParams pp)
@@ -408,55 +411,34 @@ spec = describe "Addresses" $ do
408411

409412
prop "it yields the correct number of results" $ withMaxSuccess 20 $ do
410413
monadicIO $
411-
withAddressesFixtures 3 4 $ \_ layer _ _ -> do
414+
withAddressesFixtures (DesiredNewAccs 3) (DesiredNewAddrs 4) $ \_ layer _ (_, total) -> do
412415
let pp = PaginationParams (Page 1) (PerPage 40)
413416
res <- runExceptT $ runHandler' $ do
414417
Handlers.listAddresses layer (RequestParams pp)
415418
case res of
416419
Right wr -> do
417-
-- this takes into account that there is an initial account
418-
-- and each account has an initial address (but not the initial
419-
-- account thus the -1)
420-
length (wrData wr) `shouldBe` expectedNumber 3 4
420+
length (wrData wr) `shouldBe` min 40 total
421421
_ -> fail ("Got " ++ show res)
422422

423423
prop "is deterministic" $ withMaxSuccess 20 $ do
424424
monadicIO $
425-
withAddressesFixtures 3 8 $ \_ layer _ _ -> do
426-
let (expectedTotal :: Int) = expectedNumber 3 8
427-
let pp = PaginationParams (Page 1) (PerPage 40)
428-
let pp1 = PaginationParams (Page 1) (PerPage (quot expectedTotal 3 + 1))
429-
let pp2 = PaginationParams (Page 2) (PerPage (quot expectedTotal 3 + 1))
430-
let pp3 = PaginationParams (Page 3) (PerPage (quot expectedTotal 3 + 1))
431-
res <- runExceptT $ runHandler' $ do
432-
Handlers.listAddresses layer (RequestParams pp)
433-
res' <- runExceptT $ runHandler' $ do
434-
Handlers.listAddresses layer (RequestParams pp)
435-
res1 <- runExceptT $ runHandler' $ do
436-
Handlers.listAddresses layer (RequestParams pp1)
437-
res1' <- runExceptT $ runHandler' $ do
438-
Handlers.listAddresses layer (RequestParams pp1)
439-
res2 <- runExceptT $ runHandler' $ do
440-
Handlers.listAddresses layer (RequestParams pp2)
441-
res2' <- runExceptT $ runHandler' $ do
442-
Handlers.listAddresses layer (RequestParams pp2)
443-
res3 <- runExceptT $ runHandler' $ do
444-
Handlers.listAddresses layer (RequestParams pp3)
445-
res3' <- runExceptT $ runHandler' $ do
446-
Handlers.listAddresses layer (RequestParams pp3)
447-
res `shouldBe` res'
448-
res1 `shouldBe` res1'
449-
res2 `shouldBe` res2'
450-
res3 `shouldBe` res3'
425+
withAddressesFixtures (DesiredNewAccs 3) (DesiredNewAddrs 8) $ \_ layer _ (_, expectedTotal) -> do
426+
let ppSplit = quot expectedTotal 3 + 1
427+
mkRequest mypp = Handlers.listAddresses layer (RequestParams mypp)
428+
forM_ [(1,40), (1, ppSplit), (2, ppSplit), (3, ppSplit)] $ \(page, perPage) -> do
429+
let pp = PaginationParams (Page page) (PerPage perPage)
430+
Right (r1, r2) <- runExceptT $ runHandler' $ do
431+
(,) <$> mkRequest pp <*> mkRequest pp
432+
r1 `shouldBe` r2
451433

452434
prop "yields the correct set of resutls" $ withMaxSuccess 20 $ do
453435
monadicIO $
454-
withAddressesFixtures 4 8 $ \_ layer _ _ -> do
455-
let (expectedTotal :: Int) = expectedNumber 4 8
456-
let pp = PaginationParams (Page 1) (PerPage 50)
457-
let pp1 = PaginationParams (Page 1) (PerPage (quot expectedTotal 3 + 1))
458-
let pp2 = PaginationParams (Page 2) (PerPage (quot expectedTotal 3 + 1))
459-
let pp3 = PaginationParams (Page 3) (PerPage (quot expectedTotal 3 + 1))
436+
withAddressesFixtures (DesiredNewAccs 4) (DesiredNewAddrs 8) $ \_ layer _ (_, expectedTotal) -> do
437+
let ppSplit = quot expectedTotal 3 + 1
438+
pp = PaginationParams (Page 1) (PerPage 50)
439+
pp1 = PaginationParams (Page 1) (PerPage ppSplit)
440+
pp2 = PaginationParams (Page 2) (PerPage ppSplit)
441+
pp3 = PaginationParams (Page 3) (PerPage ppSplit)
460442
res <- runExceptT $ runHandler' $ do
461443
Handlers.listAddresses layer (RequestParams pp)
462444
res1 <- runExceptT $ runHandler' $ do
@@ -467,22 +449,21 @@ spec = describe "Addresses" $ do
467449
Handlers.listAddresses layer (RequestParams pp3)
468450
case (res, res1, res2, res3) of
469451
(Right wr, Right wr1, Right wr2, Right wr3) -> do
470-
length (wrData wr) `shouldBe` expectedTotal
471452
let con = wrData wr1 <> wrData wr2 <> wrData wr3
453+
length (wrData wr) `shouldBe` expectedTotal
472454
length con `shouldBe` expectedTotal
473455
S.fromList con `shouldBe` S.fromList (wrData wr)
474-
(addrRoot . V1.unV1 . V1.addrId <$> con)
475-
`shouldBe` (addrRoot . V1.unV1 . V1.addrId <$> wrData wr)
456+
(rootId <$> con) `shouldBe` (rootId <$> wrData wr)
476457
_ -> fail ("Got " ++ show res)
477458

478459
prop "yields the correct ordered resutls when there is one account" $ withMaxSuccess 20 $ do
479460
monadicIO $
480-
withAddressesFixtures 0 15 $ \_ layer _ _ -> do
481-
let (expectedTotal :: Int) = expectedNumber 0 15
482-
let pp = PaginationParams (Page 1) (PerPage 50)
483-
let pp1 = PaginationParams (Page 1) (PerPage (quot expectedTotal 3 + 1))
484-
let pp2 = PaginationParams (Page 2) (PerPage (quot expectedTotal 3 + 1))
485-
let pp3 = PaginationParams (Page 3) (PerPage (quot expectedTotal 3 + 1))
461+
withAddressesFixtures (DesiredNewAccs 0) (DesiredNewAddrs 15) $ \_ layer _ (_, expectedTotal) -> do
462+
let ppSplit = quot expectedTotal 3 + 1
463+
pp = PaginationParams (Page 1) (PerPage 50)
464+
pp1 = PaginationParams (Page 1) (PerPage ppSplit)
465+
pp2 = PaginationParams (Page 2) (PerPage ppSplit)
466+
pp3 = PaginationParams (Page 3) (PerPage ppSplit)
486467
res <- runExceptT $ runHandler' $ do
487468
Handlers.listAddresses layer (RequestParams pp)
488469
res1 <- runExceptT $ runHandler' $ do
@@ -493,25 +474,25 @@ spec = describe "Addresses" $ do
493474
Handlers.listAddresses layer (RequestParams pp3)
494475
case (res, res1, res2, res3) of
495476
(Right wr, Right wr1, Right wr2, Right wr3) -> do
496-
length (wrData wr) `shouldBe` expectedTotal
497477
let con = wrData wr1 <> wrData wr2 <> wrData wr3
478+
length (wrData wr) `shouldBe` expectedTotal
498479
length con `shouldBe` expectedTotal
499480
S.fromList con `shouldBe` S.fromList (wrData wr)
500-
(addrRoot . V1.unV1 . V1.addrId <$> con)
501-
`shouldBe` (addrRoot . V1.unV1 . V1.addrId <$> wrData wr)
481+
(rootId <$> con) `shouldBe` (rootId <$> wrData wr)
502482
_ -> fail ("Got " ++ show res)
503483

504484

505485
prop "yields the correct ordered resutls" $ withMaxSuccess 20 $ do
506486
monadicIO $ do
507-
forM_ [(4,8), (6,6), (5,7)] $ \(acc,adr) ->
508-
withAddressesFixtures acc adr $ \_ layer _ _ -> do
487+
forM_ [(DesiredNewAccs 4,DesiredNewAddrs 8),
488+
(DesiredNewAccs 6,DesiredNewAddrs 6),
489+
(DesiredNewAccs 5,DesiredNewAddrs 7)] $ \(acc,adr) ->
490+
withAddressesFixtures acc adr $ \_ layer _ (_, expectedTotal) -> do
509491
forM_ [2..10] $ \k -> do
510492
let indexes = [1..k]
511-
let (expectedTotal :: Int) = expectedNumber acc adr
512-
let pagesParams = map (\i -> PaginationParams (Page i) (PerPage (quot expectedTotal k + 1)))
493+
pagesParams = map (\i -> PaginationParams (Page i) (PerPage (quot expectedTotal k + 1)))
513494
indexes
514-
let pp = PaginationParams (Page 1) (PerPage 50)
495+
pp = PaginationParams (Page 1) (PerPage 50)
515496
res <- runExceptT $ runHandler' $ do
516497
Handlers.listAddresses layer (RequestParams pp)
517498
eiResultsArray <- forM pagesParams $ \ppi -> runExceptT $ runHandler' $ do
@@ -523,8 +504,7 @@ spec = describe "Addresses" $ do
523504
length (wrData wr) `shouldBe` expectedTotal
524505
length con `shouldBe` expectedTotal
525506
S.fromList con `shouldBe` S.fromList (wrData wr)
526-
(addrRoot . V1.unV1 . V1.addrId <$> con)
527-
`shouldBe` (addrRoot . V1.unV1 . V1.addrId <$> wrData wr)
507+
(rootId <$> con)`shouldBe` (rootId <$> wrData wr)
528508
_ -> fail ("Got " ++ show res)
529509

530510
describe "ValidateAddress" $ do

0 commit comments

Comments
 (0)