Skip to content

Commit

Permalink
[ADP-3344] Change Deposit Wallet to use Cardano.Wallet.Read (#4760)
Browse files Browse the repository at this point in the history
This pull request changes the module `Cardano.Wallet.Deposit.Read` to
use the types from `Cardano.Wallet.Read` and implements a minimal set of
necessary follow-up adjustments.

This pull request manages to remove the dependency of the
`customer-deposit-wallet` on the `cardano-wallet-primitive` package.

### Issue Number

ADP-3344
  • Loading branch information
HeinrichApfelmus authored Aug 30, 2024
2 parents c6aefbe + 5de63d8 commit d0ac1ec
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 111 deletions.
4 changes: 2 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ source-repository-package
source-repository-package
type: git
location: https://github.com/cardano-foundation/cardano-wallet-agda
tag: 1feea08e8c387cf23deee780e0de52b24edc004c
--sha256: 1zsx0191pwaw30017jrxll1ldfvp4pk9jkw0fb9pd4235kpmslkm
tag: 525eb93be15a8c1ea6198e472f401ea0f9a985cd
--sha256: 1mw98kdqhafdq89ry3yxwd1xwjd7g69fs5pd1p2np8sdrpxh3n8g
subdir:
lib/customer-deposit-wallet-pure
lib/cardano-wallet-read
Expand Down
4 changes: 1 addition & 3 deletions lib/customer-deposit-wallet/customer-deposit-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ library
, cardano-crypto
, cardano-wallet:cardano-wallet
, cardano-wallet-network-layer
, cardano-wallet-primitive
, cardano-wallet-read == 0.2024.8.27
, cardano-ledger-byron
, containers
Expand Down Expand Up @@ -117,6 +116,7 @@ library customer-deposit-wallet-http
, aeson-pretty
, base
, bytestring
, cardano-wallet-read
, customer-deposit-wallet
, http-media
, insert-ordered-containers
Expand Down Expand Up @@ -148,8 +148,6 @@ test-suite unit
, base
, bytestring
, cardano-crypto
, cardano-wallet:cardano-wallet
, cardano-wallet-primitive
, cardano-wallet-test-utils
, customer-deposit-wallet:{customer-deposit-wallet, customer-deposit-wallet-http}
, directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ import Data.Aeson.Types
import Data.Bifunctor
( first
)
import Data.ByteArray.Encoding
( Base (Base16)
, convertFromBase
, convertToBase
)
import Data.ByteString.Short
( fromShort
, toShort
)
import Data.OpenApi
( NamedSchema (..)
, ToSchema (..)
Expand All @@ -57,13 +66,17 @@ import Data.Text
)
import Data.Text.Class
( FromText (..)
, TextDecodingError (..)
, ToText (..)
, getTextDecodingError
)
import Servant
( FromHttpApiData (..)
)

import qualified Cardano.Wallet.Read as Read
import qualified Data.Text as T
import qualified Data.Text.Encoding as T

{-----------------------------------------------------------------------------
Additional type definitions
Expand All @@ -83,8 +96,29 @@ newtype ApiT a = ApiT {unApiT :: a}
------------------------------------------------------------------------------}

-- Address
deriving via ViaText Address instance FromJSON (ApiT Address)
deriving via ViaText Address instance ToJSON (ApiT Address)
instance ToText (ApiT Address) where
toText = T.decodeUtf8
. convertToBase Base16
. fromShort
. Read.toShortByteString
. unApiT

instance FromText (ApiT Address) where
fromText t = do
bytes <-
first textDecodingError
. convertFromBase Base16
$ T.encodeUtf8 t
maybe (Left errInvalidAddress) (Right . ApiT)
. Read.fromShortByteString
$ toShort bytes
where
errInvalidAddress = TextDecodingError $ "Invalid address: " <> show t
textDecodingError = TextDecodingError . show

-- FIXME: Bech32 encodings
deriving via ViaText (ApiT Address) instance FromJSON (ApiT Address)
deriving via ViaText (ApiT Address) instance ToJSON (ApiT Address)

instance ToSchema (ApiT Address) where
declareNamedSchema _ = do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
--
module Cardano.Wallet.Deposit.HTTP.Types.JSON.Encoding
( Custom (..)
, ViaText (..)
, customOptions
, ViaText (..)
) where

import Prelude
Expand Down
28 changes: 12 additions & 16 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/Pure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ import Cardano.Wallet.Deposit.Pure.UTxOHistory
import Cardano.Wallet.Deposit.Read
( Address
)
import Data.Bifunctor
( second
)
import Data.Foldable
( foldl'
)
Expand Down Expand Up @@ -86,6 +83,7 @@ import qualified Cardano.Wallet.Deposit.Pure.UTxOHistory as UTxOHistory
import qualified Cardano.Wallet.Deposit.Read as Read
import qualified Cardano.Wallet.Deposit.Write as Write
import qualified Data.Delta as Delta
import qualified Data.Set as Set

{-----------------------------------------------------------------------------
Types
Expand All @@ -110,20 +108,18 @@ type DeltaWalletState = Delta.Replace WalletState

listCustomers :: WalletState -> [(Customer, Address)]
listCustomers =
map (second Read.fromRawAddress)
. Address.listCustomers . addresses
Address.listCustomers . addresses

createAddress :: Customer -> WalletState -> (Address, WalletState)
createAddress customer w0 =
(Read.fromRawAddress address, w0{addresses = s1})
(address, w0{addresses = s1})
where
(address, s1) = Address.createAddress customer (addresses w0)

-- depend on the private key only, not on the entire wallet state
deriveAddress :: WalletState -> (Customer -> Address)
deriveAddress w =
Read.fromRawAddress
. Address.deriveAddress (Address.getXPub (addresses w))
Address.deriveAddress (Address.getXPub (addresses w))
. Address.DerivationCustomer

-- FIXME: More performant with a double index.
Expand All @@ -132,11 +128,11 @@ knownCustomer c = (c `elem`) . map fst . listCustomers

knownCustomerAddress :: Address -> WalletState -> Bool
knownCustomerAddress address =
Address.knownCustomerAddress (Read.toRawAddress address) . addresses
Address.knownCustomerAddress address . addresses

isCustomerAddress :: Address -> WalletState -> Bool
isCustomerAddress address =
flip Address.isCustomerAddress (Read.toRawAddress address) . addresses
flip Address.isCustomerAddress address . addresses

fromRawCustomer :: Word31 -> Customer
fromRawCustomer = id
Expand Down Expand Up @@ -172,12 +168,12 @@ rollForwardOne block w =
}
where
isOurs :: Address -> Bool
isOurs = Address.isOurs (addresses w) . Read.toRawAddress
isOurs = Address.isOurs (addresses w)

rollForwardUTxO
:: (Address -> Bool) -> Read.Block -> UTxOHistory -> UTxOHistory
rollForwardUTxO isOurs block u =
Delta.apply (UTxOHistory.AppendBlock slot deltaUTxO) u
UTxOHistory.appendBlock slot deltaUTxO u
where
(deltaUTxO,_) = Balance.applyBlock isOurs block (UTxOHistory.getUTxO u)
slot = Read.slot . Read.blockHeaderBody $ Read.blockHeader block
Expand All @@ -203,13 +199,13 @@ data TxSummary = TxSummary
, blockHeaderBody :: Read.BHBody
, transfer :: ValueTransfer
}
deriving (Eq, Ord, Show)
deriving (Eq, Show)

data ValueTransfer = ValueTransfer
{ spent :: Read.Value
, received :: Read.Value
}
deriving (Eq, Ord, Show)
deriving (Eq, Show)

getCustomerHistory :: Customer -> WalletState -> [TxSummary]
getCustomerHistory = undefined
Expand Down Expand Up @@ -246,7 +242,7 @@ getBIP32PathsForOwnedInputs txbody w =

getBIP32Paths :: WalletState -> [Read.Address] -> [BIP32Path]
getBIP32Paths w =
mapMaybe $ Address.getBIP32Path (addresses w) . Read.toRawAddress
mapMaybe $ Address.getBIP32Path (addresses w)

signTxBody :: Write.TxBody -> WalletState -> Maybe Write.Tx
signTxBody _txbody _w = undefined
Expand All @@ -256,4 +252,4 @@ addTxSubmission _tx _w = undefined

listTxsInSubmission :: WalletState -> Set Write.Tx
-- listTxsInSubmission = Sbm.listInSubmission . submissions
listTxsInSubmission _ = mempty
listTxsInSubmission _ = Set.empty
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,18 @@ import Cardano.Wallet.Deposit.Pure.UTxO
, balance
, excluding
)
import Cardano.Wallet.Primitive.Ledger.Read.Tx
( primitiveTx
)
import Cardano.Wallet.Primitive.Model
( utxoFromTx
)
import Data.Foldable
( foldMap'
)
import Data.Set
( Set
)

import qualified Cardano.Wallet.Deposit.Pure.UTxO as UTxO
import qualified Cardano.Wallet.Deposit.Pure.UTxO.DeltaUTxO as DeltaUTxO
import qualified Cardano.Wallet.Deposit.Pure.UTxO.UTxO as UTxO
import qualified Cardano.Wallet.Deposit.Read as Read
import qualified Cardano.Wallet.Deposit.Write as Write
import qualified Data.Set as Set
import qualified Cardano.Wallet.Read.Tx as Tx

{-----------------------------------------------------------------------------
Wallet Balance
Expand Down Expand Up @@ -59,20 +54,19 @@ type IsOurs addr = addr -> Bool
--
-- Returns both a delta and the new value.
applyBlock
:: IsOurs Read.Addr -> Read.Block -> UTxO -> (DeltaUTxO, UTxO)
:: IsOurs Read.Address -> Read.Block -> UTxO -> (DeltaUTxO, UTxO)
applyBlock isOurs block u0 =
(mconcat $ reverse dus, u1)
where
(dus, u1) =
mapAccumL' (applyTx isOurs) u0
. map primitiveTx
$ Read.transactions block

-- | Apply a transactions to the 'UTxO'.
--
-- Returns both a delta and the new value.
applyTx
:: IsOurs Read.Addr -> Read.Tx -> UTxO -> (DeltaUTxO, UTxO)
:: IsOurs Read.Address -> Read.Tx -> UTxO -> (DeltaUTxO, UTxO)
applyTx isOurs tx u0 =
if isUnchangedUTxO
then (mempty, u0)
Expand All @@ -81,16 +75,16 @@ applyTx isOurs tx u0 =
(du, u) = (du21 <> du10, u2)

(du10, u1) = spendTxD tx u0
receivedUTxO = UTxO.filterByAddress isOurs (utxoFromTx tx)
(du21, u2) = UTxO.receiveD u1 receivedUTxO
receivedUTxO = UTxO.filterByAddress isOurs (Read.utxoFromEraTx tx)
(du21, u2) = DeltaUTxO.receiveD u1 receivedUTxO

-- NOTE: Performance.
-- 'applyTx' is part of a tight loop that inspects all transactions
-- (> 30M Txs as of Feb 2022).
-- Thus, we make a small performance optimization here.
-- Specifically, we want to reject a transaction as soon as possible
-- if it does not change the 'UTxO' set. The test
isUnchangedUTxO = UTxO.null receivedUTxO && mempty == du10
isUnchangedUTxO = UTxO.null receivedUTxO && DeltaUTxO.null du10
-- allocates slightly fewer new Set/Map than the definition
-- isUnchangedUTxO = mempty == du

Expand All @@ -100,12 +94,12 @@ applyTx isOurs tx u0 =
-- | Remove unspent outputs that are consumed by the given transaction.
spendTxD :: Read.Tx -> UTxO -> (DeltaUTxO, UTxO)
spendTxD tx !u =
u `UTxO.excludingD` Set.fromList inputsToExclude
u `DeltaUTxO.excludingD` inputsToExclude
where
inputsToExclude =
if Read.txScriptInvalid tx
then Read.collateralInputs tx
else Read.inputs tx
case Tx.getScriptValidity tx of
Tx.IsValid True -> Tx.getInputs tx
Tx.IsValid False -> Tx.getCollateralInputs tx

{-----------------------------------------------------------------------------
Helpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@ module Cardano.Wallet.Deposit.Pure.UTxO
, null
) where

import Cardano.Wallet.Primitive.Types.UTxO
import Cardano.Wallet.Deposit.Pure.UTxO.DeltaUTxO
( DeltaUTxO
, excludingD
, null
, receiveD
)
import Cardano.Wallet.Deposit.Pure.UTxO.UTxO
( UTxO
, balance
, excluding
, filterByAddress
, restrictedBy
)
import Data.Map.Strict
( toList
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
module Cardano.Wallet.Deposit.Pure.UTxOHistory
( UTxOHistory
, empty
, appendBlock

, DeltaUTxOHistory (..)
, getUTxO
) where

import Cardano.Wallet.DB.Store.UTxOHistory.Model
import Cardano.Wallet.Deposit.Pure.UTxO.DeltaUTxO
( DeltaUTxO
)
import Cardano.Wallet.Deposit.Pure.UTxO.UTxOHistory
( UTxOHistory
, appendBlock
, empty
, getUTxO
)
import Cardano.Wallet.Deposit.Read
( Slot
, SlotNo
)

-- | Changes to the UTxO history.
data DeltaUTxOHistory
= -- | New slot tip, changes within that block.
AppendBlock SlotNo DeltaUTxO
| -- | Rollback tip.
Rollback Slot
| -- | Move finality forward.
Prune SlotNo
Loading

0 comments on commit d0ac1ec

Please sign in to comment.