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 pathCore.hs
129 lines (103 loc) · 4.26 KB
/
Core.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
-- | Utility functions on core types
--
-- Intended for qualified import
--
-- > import qualified Cardano.Wallet.Kernel.Util.Core as Core
module Cardano.Wallet.Kernel.Util.Core (
-- * General utility functions
getCurrentTimestamp
, derefIn
, fromUtxo
, toOutPair
, getSomeTimestamp
-- * UTxO
, utxoBalance
, utxoRestrictToInputs
, utxoRemoveInputs
, utxoUnions
-- * Transactions
, paymentAmount
, txOuts
, txIns
, txAuxId
) where
import Universum
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Data.Time.Clock.POSIX (getPOSIXTime)
import Data.Time.Units (fromMicroseconds)
import Serokell.Util (enumerate)
import qualified Pos.Chain.Txp as Core
import qualified Pos.Core as Core
import Pos.Crypto.Hashing (hash)
import Cardano.Wallet.Kernel.Util
{-------------------------------------------------------------------------------
General-utility functions
-------------------------------------------------------------------------------}
-- | Get current timestamp
--
-- NOTE: we are abandoning the 'Mockable time' strategy of core.
getCurrentTimestamp :: IO Core.Timestamp
getCurrentTimestamp = Core.Timestamp . round . (* 1000000) <$> getPOSIXTime
getSomeTimestamp :: Core.Timestamp
getSomeTimestamp = Core.Timestamp $ fromMicroseconds 12340000
{-------------------------------------------------------------------------------
UTxO
-------------------------------------------------------------------------------}
-- | Computes the balance for this UTxO
--
-- This returns an 'Integer' rather than a 'Coin' because the outputs of a
-- block may sum to more than 'maxCoinVal' (if some outputs of the transactions
-- in the block are used as inputs by other transactions in that block).
utxoBalance :: Core.Utxo -> Integer
utxoBalance = foldl' updateFn 0 . Map.elems
where
updateFn :: Integer -> Core.TxOutAux -> Integer
updateFn acc txOut = acc + Core.coinToInteger (toCoin txOut)
-- | Restricts the 'Utxo' to only the selected set of inputs.
utxoRestrictToInputs :: Core.Utxo -> Set Core.TxIn -> Core.Utxo
utxoRestrictToInputs = restrictKeys
utxoRemoveInputs :: Core.Utxo -> Set Core.TxIn -> Core.Utxo
utxoRemoveInputs = withoutKeys
utxoUnions :: [Core.Utxo] -> Core.Utxo
utxoUnions = Map.unions
{-------------------------------------------------------------------------------
Transactions
-------------------------------------------------------------------------------}
-- | Calculates the amount of a requested payment.
paymentAmount :: NonEmpty Core.TxOut -> Core.Coin
paymentAmount = Core.unsafeIntegerToCoin
. Core.sumCoins
. map Core.txOutValue
. toList
txOuts :: Core.Tx -> Core.Utxo
txOuts tx = Map.fromList $ map (toTxInOut (hash tx)) (outs tx)
txIns :: Core.TxAux -> Set Core.TxIn
txIns = Set.fromList . NE.toList . Core._txInputs . Core.taTx
txAuxId :: Core.TxAux -> Core.TxId
txAuxId = hash . Core.taTx
{-------------------------------------------------------------------------------
External auxiliary
-------------------------------------------------------------------------------}
toOutPair :: Core.TxOutAux -> (Core.Address, Core.Coin)
toOutPair txOutAux = (toAddress txOutAux, toCoin txOutAux)
fromUtxo :: Core.Utxo -> Maybe (NE.NonEmpty (Core.Address, Core.Coin))
fromUtxo utxo = NE.nonEmpty $ toOutPair <$> Map.elems utxo
derefIn :: Core.TxIn -> Maybe (Core.TxId, Word32)
derefIn txIn = case txIn of
Core.TxInUnknown _ _ -> Nothing
Core.TxInUtxo txId ix -> Just (txId, ix)
{-------------------------------------------------------------------------------
Internal auxiliary
-------------------------------------------------------------------------------}
-- | Gets the underlying value (as a 'Coin') from a 'TxOutAux'.
toCoin :: Core.TxOutAux -> Core.Coin
toCoin = Core.txOutValue . Core.toaOut
-- | Gets the underlying address from a 'TxOutAux'.
toAddress :: Core.TxOutAux -> Core.Address
toAddress = Core.txOutAddress . Core.toaOut
outs :: Core.Tx -> [(Word32, Core.TxOut)]
outs tx = enumerate $ toList $ tx ^. Core.txOutputs
toTxInOut :: Core.TxId -> (Word32, Core.TxOut) -> (Core.TxIn, Core.TxOutAux)
toTxInOut txId (idx, out) = (Core.TxInUtxo txId idx, Core.TxOutAux out)