Skip to content

Commit

Permalink
[ADP-3344] Implement REST-like IO interface for Deposit Wallet (#4769)
Browse files Browse the repository at this point in the history
This pull requests implements a REST-like `IO` interface for the Deposit
Wallet. This interface corresponds more closely to an HTTP interface.

Essentially, the main difference between `Cardano.Wallet.Deposit.IO` and
`Cardano.Wallet.Deposit.REST` is that the latter postpones the need to
initialize the wallet. Instead of working with a `WalletInstance`, the
latter module now works with a `WalletResource`, which is roughly a
`TVar (Maybe WalletInstance)`. This mutable variable starts with
`Nothing` and the function `putWallet` can be used to initialize the
wallet, putting a `Just` in the mutable variable.

In turn, a module `Cardano.Wallet.Deposit.IO.Resource` implements a data
type `Resource` that encapsulate the idea of `TVar (Maybe
WalletInstance)` and is (reasonably) safe to use in a concurrent
environment.

### Comments

* Not implemented yet: `withWalletResource` inspects the database
directory and loads a wallet if necessary.

### Issue Number

ADP-3344
  • Loading branch information
paolino committed Sep 10, 2024
2 parents b515094 + 053d8b1 commit 5847239
Show file tree
Hide file tree
Showing 7 changed files with 797 additions and 50 deletions.
4 changes: 4 additions & 0 deletions lib/crypto-primitives/src/Cryptography/Hash/Blake.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Cryptography.Hash.Blake
, Blake2b_224
, Blake2b_256

, blake2b160
, blake2b256
, blake2b224
, hashSizeBlake2b224
Expand Down Expand Up @@ -41,5 +42,8 @@ blake2b256 = BA.convert . hash @_ @Blake2b_256
blake2b224 :: ByteArrayAccess a => a -> ByteString
blake2b224 = BA.convert . hash @_ @Blake2b_224

blake2b160 :: ByteArrayAccess a => a -> ByteString
blake2b160 = BA.convert . hash @_ @Blake2b_160

hashSizeBlake2b224 :: Int
hashSizeBlake2b224 = hashDigestSize Blake2b_224
60 changes: 35 additions & 25 deletions lib/customer-deposit-wallet/customer-deposit-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,21 @@ maintainer: hal@cardanofoundation.org
copyright: 2023 Cardano Foundation
category: Web
data-files: data/swagger.json

extra-source-files:
spec/**/*.lagda.md
spec/**/*.lhs.md
spec/**/*.openapi.yaml

common language
default-language:
Haskell2010
default-language: Haskell2010
default-extensions:
NoImplicitPrelude
OverloadedStrings

common opts-lib
ghc-options:
-Wall -Wcompat
-Wredundant-constraints
-Wincomplete-uni-patterns -Wincomplete-record-updates
-Wall -Wcompat -Wredundant-constraints -Wincomplete-uni-patterns
-Wincomplete-record-updates

if flag(release)
ghc-options: -O2 -Werror
Expand All @@ -50,49 +47,58 @@ library
, async
, base
, bytestring
, cardano-addresses
, cardano-binary
, cardano-crypto
, cardano-wallet:cardano-wallet
, cardano-wallet-network-layer
, cardano-wallet-read == 0.2024.8.27
, cardano-ledger-api
, cardano-ledger-binary
, cardano-ledger-byron
, cardano-strict-containers
, cardano-wallet
, cardano-wallet-network-layer
, cardano-wallet-read ==0.2024.8.27
, containers
, contra-tracer
, crypto-primitives
, customer-deposit-wallet-pure
, delta-store
, delta-table
, delta-types
, directory
, filepath
, io-classes
, iohk-monitoring-extra
, memory
, microlens
, OddWord
, sqlite-simple
, serialise
, text
, transformers
, time
, cardano-ledger-api
, cardano-strict-containers
, microlens
, transformers

exposed-modules:
Cardano.Wallet.Deposit.IO
Cardano.Wallet.Deposit.IO.DB
Cardano.Wallet.Deposit.IO.Network.Mock
Cardano.Wallet.Deposit.IO.Network.Type
Cardano.Wallet.Deposit.IO.Resource
Cardano.Wallet.Deposit.Pure
Cardano.Wallet.Deposit.Pure.Balance
Cardano.Wallet.Deposit.Pure.Submissions
Cardano.Wallet.Deposit.Pure.UTxO
Cardano.Wallet.Deposit.Pure.UTxOHistory
Cardano.Wallet.Deposit.Pure.Submissions
Cardano.Wallet.Deposit.Read
Cardano.Wallet.Deposit.REST
Cardano.Wallet.Deposit.Write

test-suite scenario
import: language, opts-exe
type: exitcode-stdio-1.0
hs-source-dirs: test/scenario
main-is: test-suite-scenario.hs
build-tool-depends:
markdown-unlit:markdown-unlit
ghc-options:
-pgmL markdown-unlit
build-tool-depends: markdown-unlit:markdown-unlit
ghc-options: -pgmL markdown-unlit
build-depends:
, base
, bytestring
Expand All @@ -102,7 +108,8 @@ test-suite scenario
, contra-tracer
, customer-deposit-wallet
, delta-store
, hspec >=2.8.2
, hspec >=2.8.2

other-modules:
Test.Scenario.Blockchain
Test.Scenario.Wallet.Deposit.Exchanges
Expand All @@ -128,6 +135,7 @@ library customer-deposit-wallet-http
, text
, text-class
, warp

exposed-modules:
Cardano.Wallet.Deposit.HTTP
Cardano.Wallet.Deposit.HTTP.Endpoints
Expand All @@ -149,24 +157,26 @@ test-suite unit
, bytestring
, cardano-crypto
, cardano-wallet-test-utils
, customer-deposit-wallet:{customer-deposit-wallet, customer-deposit-wallet-http}
, customer-deposit-wallet
, customer-deposit-wallet:customer-deposit-wallet-http
, directory
, hspec >=2.8.2
, hspec
, hspec-golden
, openapi3
, QuickCheck
, temporary
, with-utf8

build-tool-depends: hspec-discover:hspec-discover
other-modules:
Cardano.Wallet.Deposit.HTTP.JSON.JSONSpec
Cardano.Wallet.Deposit.HTTP.OpenAPISpec
Cardano.Wallet.Deposit.RESTSpec
Paths_customer_deposit_wallet
Spec

executable customer-deposit-wallet
import: language, opts-exe
hs-source-dirs: exe
build-depends:
, base
main-is:
customer-deposit-wallet.hs
build-depends: base
main-is: customer-deposit-wallet.hs
71 changes: 51 additions & 20 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Cardano.Wallet.Deposit.IO
(
-- * Types
WalletEnv (..)
, WalletBootEnv (..)
, WalletInstance

-- * Operations
Expand All @@ -27,6 +28,7 @@ module Cardano.Wallet.Deposit.IO
, createPayment
, getBIP32PathsForOwnedInputs
, signTxBody
, WalletStore
) where

import Prelude
Expand Down Expand Up @@ -72,12 +74,28 @@ import qualified Data.Store as Store
{-----------------------------------------------------------------------------
Types
------------------------------------------------------------------------------}
data WalletEnv m =
WalletEnv

-- | The environment needed to initialize a wallet, before a database is
-- connected.
data WalletBootEnv m = WalletBootEnv
{ logger :: Tracer m WalletLog
-- ^ Logger for the wallet.
, genesisData :: Read.GenesisData
-- ^ Genesis data for the wallet.
, networkEnv :: Network.NetworkEnv m Read.Block
, database :: Store.UpdateStore IO Wallet.DeltaWalletState
-- ^ Network environment for the wallet.
}

-- | The wallet store type.
type WalletStore = Store.UpdateStore IO Wallet.DeltaWalletState

-- | The full environment needed to run a wallet.
data WalletEnv m =
WalletEnv
{ bootEnv :: WalletBootEnv m
-- ^ The boot environment.
, store :: WalletStore
-- ^ The store for the wallet.
}

data WalletInstance = WalletInstance
Expand Down Expand Up @@ -108,44 +126,57 @@ readWalletState WalletInstance{walletState} =
Operations
Initialization
------------------------------------------------------------------------------}

-- | Initialize a new wallet in the given environment.
withWalletInit
:: WalletEnv IO
-> XPub
-> Word31
-> (WalletInstance -> IO a)
-> IO a
withWalletInit env@WalletEnv{..} xpub knownCustomerCount action = do
walletState <- DBVar.initDBVar database
$ Wallet.fromXPubAndGenesis xpub knownCustomerCount genesisData
withWalletDBVar env walletState action
withWalletInit
env@WalletEnv
{ bootEnv = WalletBootEnv{genesisData}
, ..
}
xpub
knownCustomerCount
action = do
walletState <-
DBVar.initDBVar store
$ Wallet.fromXPubAndGenesis xpub knownCustomerCount genesisData
withWalletDBVar env walletState action

-- | Load an existing wallet from the given environment.
withWalletLoad
:: WalletEnv IO
-> (WalletInstance -> IO a)
-> IO a
withWalletLoad env@WalletEnv{..} action = do
walletState <- DBVar.loadDBVar database
walletState <- DBVar.loadDBVar store
withWalletDBVar env walletState action

withWalletDBVar
:: WalletEnv IO
-> DBVar.DBVar IO Wallet.DeltaWalletState
-> (WalletInstance -> IO a)
-> IO a
withWalletDBVar env@WalletEnv{..} walletState action = do
let w = WalletInstance{env,walletState}
Async.withAsync (doChainSync w) $ \_ -> action w
where
doChainSync = Network.chainSync networkEnv trChainSync . chainFollower
trChainSync = contramap (\_ -> WalletLogDummy) logger
chainFollower w = Network.ChainFollower
{ checkpointPolicy = undefined
, readChainPoints = undefined
, rollForward = rollForward w
, rollBackward = rollBackward w
}
withWalletDBVar
env@WalletEnv{bootEnv = WalletBootEnv{logger, networkEnv}}
walletState
action = do
let w = WalletInstance{env, walletState}
Async.withAsync (doChainSync w) $ \_ -> action w
where
doChainSync = Network.chainSync networkEnv trChainSync . chainFollower
trChainSync = contramap (\_ -> WalletLogDummy) logger
chainFollower w =
Network.ChainFollower
{ checkpointPolicy = undefined
, readChainPoints = undefined
, rollForward = rollForward w
, rollBackward = rollBackward w
}

{-----------------------------------------------------------------------------
Operations
Expand Down
Loading

0 comments on commit 5847239

Please sign in to comment.