This repository was archived by the owner on Aug 18, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 631
/
Copy pathRead.hs
94 lines (82 loc) · 3.42 KB
/
Read.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
-- | Functions on checkpoints
module Cardano.Wallet.Kernel.DB.Spec.Read (
-- * Pure functions on checkpoints
cpAvailableUtxo
, cpAvailableBalance
, cpCheckAvailable
, cpChange
, cpTotalBalance
, cpTxSlotId
, cpTxIsPending
) where
import Universum
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Pos.Chain.Txp as Core
import qualified Pos.Core as Core
import Cardano.Wallet.Kernel.DB.BlockMeta (blockMetaSlotId,
localBlockMeta)
import Cardano.Wallet.Kernel.DB.HdWallet
import Cardano.Wallet.Kernel.DB.InDb (fromDb)
import Cardano.Wallet.Kernel.DB.Spec
import qualified Cardano.Wallet.Kernel.DB.Spec.Pending as Pending
import Cardano.Wallet.Kernel.DB.Util.IxSet (Indexed, IxSet)
import qualified Cardano.Wallet.Kernel.DB.Util.IxSet as IxSet
import qualified Cardano.Wallet.Kernel.Util.Core as Core
{-------------------------------------------------------------------------------
Pure functions that support read-only operations on an account Checkpoint, as
defined in the Wallet Spec
-------------------------------------------------------------------------------}
-- | Available UTxO
--
-- The available UtxO is the current UTxO minus outputs spent by pending txs
cpAvailableUtxo :: IsCheckpoint c => c -> Core.Utxo
cpAvailableUtxo c =
Core.utxoRemoveInputs (c ^. cpUtxo) pendingIns
where
pendingIns = Pending.txIns (c ^. cpPending)
-- | Returns the sets of available and unavailable inputs
cpCheckAvailable :: IsCheckpoint c
=> Set Core.TxIn -> c -> (Set Core.TxIn, Set Core.TxIn)
cpCheckAvailable ins c = Set.partition isAvailable ins
where
isAvailable :: Core.TxIn -> Bool
isAvailable inp = inp `Map.member` cpAvailableUtxo c
-- | Balance of the available UTxO
cpAvailableBalance :: IsCheckpoint c => c -> Core.Coin
cpAvailableBalance c =
fromMaybe subCoinErr balance'
where
pendingIns = Pending.txIns (c ^. cpPending)
spentUtxo = Core.utxoRestrictToInputs (c ^. cpUtxo) pendingIns
spentBalance = Core.unsafeIntegerToCoin $ Core.utxoBalance spentUtxo
balance' = Core.subCoin (c ^. cpUtxoBalance) spentBalance
subCoinErr = error "cpAvailableBalance: spent more than available?"
-- | Change outputs
--
-- Pending outputs paid back into addresses that belong to the wallet.
cpChange :: IsCheckpoint c => IxSet (Indexed HdAddress) -> c -> Core.Utxo
cpChange ours cp =
Map.union
(Pending.change ours' $ cp ^. cpPending)
(Pending.change ours' $ cp ^. cpForeign)
where
ours' :: Core.Address -> Bool
ours' addr = IxSet.size (IxSet.getEQ addr ours) == 1
-- | Total balance (available balance plus change)
cpTotalBalance :: IsCheckpoint c => IxSet (Indexed HdAddress) -> c -> Core.Coin
cpTotalBalance ours c =
Core.unsafeAddCoin availableBalance changeBalance
where
availableBalance = cpAvailableBalance c
changeBalance = Core.unsafeIntegerToCoin $
Core.utxoBalance (cpChange ours c)
-- | SlotId a transaction got confirmed in
cpTxSlotId :: IsCheckpoint c => Core.TxId -> c -> Maybe Core.SlotId
cpTxSlotId txId c = Map.lookup txId slots
where
blockMeta = localBlockMeta (c ^. cpBlockMeta)
slots = view (blockMetaSlotId . fromDb) blockMeta
-- | Check if a transaction is pending
cpTxIsPending :: IsCheckpoint c => Core.TxId -> c -> Bool
cpTxIsPending txId c = Pending.member txId (c ^. cpPending)