Skip to content

Commit

Permalink
[ADP-3335] Add functions and mock implementations to Deposit Wallet (#…
Browse files Browse the repository at this point in the history
…4527)

This pull request adds various functions and mock implementations to the
Deposit Wallet in order to prepare the execution of user scenarios.

### Comment

This pull request prepares the implementation of a mock environment for
the Deposit Wallet. In turn, this enables execution of user scenarios.

### Issue Number

ADP-3335
  • Loading branch information
HeinrichApfelmus authored May 14, 2024
2 parents 496a391 + 1c697ff commit 59176a5
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 30 deletions.
1 change: 1 addition & 0 deletions lib/customer-deposit-wallet/customer-deposit-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ library
, async
, base
, bytestring
, cardano-crypto
, cardano-wallet:cardano-wallet
, cardano-wallet-network-layer
, cardano-wallet-primitive
Expand Down
77 changes: 59 additions & 18 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,34 @@
module Cardano.Wallet.Deposit.IO
(
-- * Types
WalletEnv
WalletEnv (..)
, WalletInstance

-- * Operations
-- ** Initialization
, withWallet
, withWalletInit
, withWalletLoad

-- ** Mapping between customers and addresses
, listCustomers
, createAddress

-- ** Reading from the blockchain
, getWalletTip
, availableBalance
, getCustomerHistory
, getCustomerHistories

-- ** Writing to the blockchain
, createPayment
, getBIP32PathsForOwnedInputs
) where

import Prelude

import Cardano.Crypto.Wallet
( XPub
)
import Cardano.Wallet.Deposit.Pure
( Customer
, WalletState
Expand Down Expand Up @@ -54,6 +61,7 @@ import qualified Data.Delta as Delta
( Replace (..)
)
import qualified Data.Delta.Update as Delta
import qualified Data.Map.Strict as Map
import qualified Data.Store as Store

{-----------------------------------------------------------------------------
Expand Down Expand Up @@ -96,20 +104,37 @@ readWalletState WalletInstance{env,walletState} =
Operations
Initialization
------------------------------------------------------------------------------}
withWallet :: WalletEnv IO -> (WalletInstance -> IO a) -> IO a
withWallet env@WalletEnv{..} action = do
walletState <- loadWalletStateFromDatabase
-- | Initialize a new wallet in the given environment.
withWalletInit
:: WalletEnv IO
-> XPub
-> Integer
-> (WalletInstance -> IO a)
-> IO a
withWalletInit env@WalletEnv{..} xpub knownCustomerCount action = do
walletState <- atomically
$ DBVar.initDBVar database
$ 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 <- atomically $ DBVar.loadDBVar database
withWalletDBVar env walletState action

withWalletDBVar
:: WalletEnv IO
-> DBVar.DBVar DB.SqlM 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
loadWalletStateFromDatabase = atomically $ do
es <- Store.loadS database
case es of
Left _ ->
DBVar.initDBVar database $ Wallet.fromGenesis genesisData
Right _ ->
DBVar.loadDBVar database

doChainSync = Network.chainSync networkEnv trChainSync . chainFollower
trChainSync = contramap (\_ -> WalletLogDummy) logger
chainFollower w = Network.ChainFollower
Expand Down Expand Up @@ -138,14 +163,25 @@ createAddress c w =
Operations
Reading from the blockchain
------------------------------------------------------------------------------}
getWalletTip :: WalletInstance -> IO Read.ChainPoint
getWalletTip w =
Wallet.getWalletTip <$> readWalletState w

availableBalance :: WalletInstance -> IO Read.Value
availableBalance w =
Wallet.availableBalance <$> readWalletState w

getCustomerHistory :: WalletInstance -> Customer -> IO [Wallet.TxSummary]
getCustomerHistory w c =
getCustomerHistory :: Customer -> WalletInstance -> IO [Wallet.TxSummary]
getCustomerHistory c w =
Wallet.getCustomerHistory c <$> readWalletState w

getCustomerHistories
:: (Read.ChainPoint, Read.ChainPoint)
-> WalletInstance
-> IO (Map.Map Customer Wallet.ValueTransfer)
getCustomerHistories a w =
Wallet.getCustomerHistories a <$> readWalletState w

rollForward :: WalletInstance -> NonEmpty Read.Block -> tip -> IO ()
rollForward w blocks _nodeTip =
onWalletState w
Expand All @@ -164,9 +200,14 @@ rollBackward w point =
------------------------------------------------------------------------------}

createPayment
:: WalletInstance -> [(Address, Read.Value)] -> IO (Maybe Write.Tx)
createPayment w destinations =
Wallet.createPayment destinations <$> readWalletState w
:: [(Address, Read.Value)] -> WalletInstance -> IO (Maybe Write.TxBody)
createPayment a w =
Wallet.createPayment a <$> readWalletState w

getBIP32PathsForOwnedInputs
:: Write.TxBody -> WalletInstance -> IO [()]
getBIP32PathsForOwnedInputs a w =
Wallet.getBIP32PathsForOwnedInputs a <$> readWalletState w

{-----------------------------------------------------------------------------
Logging
Expand Down
48 changes: 36 additions & 12 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/Pure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ module Cardano.Wallet.Deposit.Pure
, isCustomerAddress

-- ** Reading from the blockchain
, fromGenesis
, localTip
, fromXPubAndGenesis
, getWalletTip
, availableBalance
, rollForwardMany
, rollForwardOne
Expand All @@ -25,9 +25,11 @@ module Cardano.Wallet.Deposit.Pure
, TxSummary (..)
, ValueTransfer (..)
, getCustomerHistory
, getCustomerHistories

-- ** Writing to the blockchain
, createPayment
, getBIP32PathsForOwnedInputs

, addTxSubmission
, listTxsInSubmission
Expand All @@ -38,6 +40,9 @@ module Cardano.Wallet.Deposit.Pure

import Prelude

import Cardano.Crypto.Wallet
( XPub
)
import Cardano.Wallet.Deposit.Pure.UTxOHistory
( UTxOHistory
)
Expand All @@ -50,6 +55,9 @@ import Data.Foldable
import Data.List.NonEmpty
( NonEmpty
)
import Data.Map.Strict
( Map
)
import Data.Maybe
( isJust
)
Expand All @@ -75,7 +83,7 @@ import qualified Data.Map.Strict as Map
type Customer = Natural

data WalletState = WalletState
{ customers :: !(Map.Map Customer Address)
{ customers :: !(Map Customer Address)
, changeAddress :: !Address
, utxoHistory :: !UTxOHistory.UTxOHistory
-- , txHistory :: [Read.Tx]
Expand All @@ -96,11 +104,14 @@ listCustomers :: WalletState -> [(Customer, Address)]
listCustomers = Map.toList . customers

createAddress :: Customer -> WalletState -> (Address, WalletState)
createAddress = undefined
createAddress customer w1 = (address, w2)
where
address = deriveAddress w1 customer
w2 = w1{customers = Map.insert customer address (customers w1)}

-- depend on the private key only, not on the entire wallet state
deriveAddress :: WalletState -> (Customer -> Address)
deriveAddress = undefined
deriveAddress _ = Read.mockAddress

knownCustomer :: Customer -> WalletState -> Bool
knownCustomer c = (c `Map.member`) . customers
Expand All @@ -109,15 +120,19 @@ knownCustomerAddress :: Address -> WalletState -> Bool
knownCustomerAddress address = isJust . isCustomerAddress address

isCustomerAddress :: Address -> WalletState -> Maybe Customer
isCustomerAddress _ _ = Nothing
isCustomerAddress address w =
case filter ((== address) . snd) (Map.toList $ customers w) of
[(customer,_address)] -> Just customer
_ -> Nothing

{-----------------------------------------------------------------------------
Operations
Reading from the blockchain
------------------------------------------------------------------------------}

fromGenesis :: Read.GenesisData -> WalletState
fromGenesis = undefined
fromXPubAndGenesis :: XPub -> Integer -> Read.GenesisData -> WalletState
fromXPubAndGenesis _xpub _knownCustomerCount _ = fromGenesisUTxO mempty
-- FIXME: This is a mock implementation

fromGenesisUTxO :: Read.UTxO -> WalletState
fromGenesisUTxO utxo =
Expand All @@ -128,8 +143,8 @@ fromGenesisUTxO utxo =
, submissions = Sbm.empty
}

localTip :: WalletState -> Read.ChainPoint
localTip = error "localTip"
getWalletTip :: WalletState -> Read.ChainPoint
getWalletTip = error "getWalletTip"

rollForwardMany :: NonEmpty Read.Block -> WalletState -> WalletState
rollForwardMany blocks w = foldl' (flip rollForwardOne) w blocks
Expand Down Expand Up @@ -158,7 +173,7 @@ rollBackward
:: Read.ChainPoint
-> WalletState
-> (WalletState, Read.ChainPoint)
rollBackward = undefined
rollBackward point w = (w, point) -- FIXME: This is a mock implementation

availableBalance :: WalletState -> Read.Value
availableBalance w =
Expand All @@ -181,16 +196,25 @@ data ValueTransfer = ValueTransfer
getCustomerHistory :: Customer -> WalletState -> [TxSummary]
getCustomerHistory = undefined

getCustomerHistories
:: (Read.ChainPoint, Read.ChainPoint)
-> WalletState
-> Map Customer ValueTransfer
getCustomerHistories = undefined

{-----------------------------------------------------------------------------
Operations
Writing to blockchain
------------------------------------------------------------------------------}

createPayment :: [(Address, Write.Value)] -> WalletState -> Maybe Write.Tx
createPayment :: [(Address, Write.Value)] -> WalletState -> Maybe Write.TxBody
createPayment = undefined
-- needs balanceTx
-- needs to sign the transaction

getBIP32PathsForOwnedInputs :: Write.TxBody -> WalletState -> [()]
getBIP32PathsForOwnedInputs = undefined

addTxSubmission :: Write.Tx -> WalletState -> WalletState
addTxSubmission _tx _w = undefined

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Cardano.Wallet.Deposit.Read

, Addr
, Address
, mockAddress

, Ix
, TxIn
Expand Down Expand Up @@ -59,6 +60,7 @@ import qualified Cardano.Wallet.Primitive.Types.Tx.TxIn as W
import qualified Cardano.Wallet.Primitive.Types.Tx.TxOut as W
import qualified Cardano.Wallet.Primitive.Types.UTxO as W
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as B8
-- import qualified Ouroboros.Consensus.Cardano.Block as O

{-----------------------------------------------------------------------------
Expand All @@ -81,6 +83,9 @@ type Addr = W.Address
-- Byron addresses are represented by @Addr_bootstrap@.
type Address = Addr

mockAddress :: Show a => a -> Address
mockAddress = W.Address . B8.pack . show

dummyAddress :: Address
dummyAddress = W.Address . BS.pack $ replicate 32 0

Expand Down

0 comments on commit 59176a5

Please sign in to comment.