@@ -81,6 +81,7 @@ import Cardano.Wallet.DB.Sqlite.TH
81
81
, TxIn (.. )
82
82
, TxMeta (.. )
83
83
, TxOut (.. )
84
+ , TxPending (.. )
84
85
, TxWithdrawal (.. )
85
86
, UTxO (.. )
86
87
, Wallet (.. )
@@ -625,16 +626,14 @@ newDBLayer trace defaultFieldValues mDatabaseFile timeInterpreter = do
625
626
deleteDelegationCertificates wid
626
627
[ CertSlot >. nearestPoint
627
628
]
628
- updateTxMetas wid
629
- [ TxMetaDirection ==. W. Outgoing
630
- , TxMetaSlot >. nearestPoint
629
+ deleteTxMetas wid
630
+ [ TxMetaSlot >. nearestPoint
631
631
]
632
- [ TxMetaStatus =. W. Pending
633
- , TxMetaSlot =. nearestPoint
632
+ updateWhere
633
+ [ TxPendingWalletId ==. wid
634
+ , TxPendingAccepted >. Just nearestPoint
634
635
]
635
- deleteTxMetas wid
636
- [ TxMetaDirection ==. W. Incoming
637
- , TxMetaSlot >. nearestPoint
636
+ [ TxPendingAccepted =. Nothing
638
637
]
639
638
deleteStakeKeyCerts wid
640
639
[ StakeKeyCertSlot >. nearestPoint
@@ -714,12 +713,16 @@ newDBLayer trace defaultFieldValues mDatabaseFile timeInterpreter = do
714
713
putTxs txins txouts txws
715
714
pure $ Right ()
716
715
717
- , readTxHistory = \ (PrimaryKey wid) minWithdrawal order range status -> do
718
- selectTxHistory
719
- timeInterpreter wid minWithdrawal order $ catMaybes
716
+ , readTxHistory = \ (PrimaryKey wid) minWithdrawal order range -> do
717
+ selectTxHistory timeInterpreter wid minWithdrawal order $ catMaybes
720
718
[ (TxMetaSlot >=. ) <$> W. inclusiveLowerBound range
721
719
, (TxMetaSlot <=. ) <$> W. inclusiveUpperBound range
722
- , (TxMetaStatus ==. ) <$> status
720
+ ]
721
+
722
+ , readTxPending = \ (PrimaryKey wid) order range -> do
723
+ selectTxPending wid order $ catMaybes
724
+ [ (TxPendingSlotCreated >=. ) <$> W. inclusiveLowerBound range
725
+ , (TxPendingSlotCreated <=. ) <$> W. inclusiveUpperBound range
723
726
]
724
727
725
728
, removePendingTx = \ (PrimaryKey wid) tid -> ExceptT $ do
@@ -732,14 +735,13 @@ newDBLayer trace defaultFieldValues mDatabaseFile timeInterpreter = do
732
735
selectWallet wid >>= \ case
733
736
Nothing -> pure errNoSuchWallet
734
737
Just _ -> do
735
- metas <- selectPendingTxs wid (TxId tid)
736
- let isPending meta = txMetaStatus meta == W. Pending
737
- case metas of
738
- [] -> pure errNoSuchTransaction
739
- txs | any isPending txs -> do
740
- deletePendingTx wid (TxId tid)
741
- pure $ Right ()
742
- _ -> pure errNoMorePending
738
+ txs <- selectPendingTxs wid (TxId tid)
739
+ deletePendingTx wid (TxId tid)
740
+ pure $ case txs of
741
+ [] -> errNoSuchTransaction
742
+ txs | all (isJust . txPendingAccepted) txs ->
743
+ errNoMorePending
744
+ _ -> Right ()
743
745
744
746
, getTx = \ (PrimaryKey wid) tid -> ExceptT $ do
745
747
selectWallet wid >>= \ case
@@ -748,7 +750,9 @@ newDBLayer trace defaultFieldValues mDatabaseFile timeInterpreter = do
748
750
metas <- selectTxHistory
749
751
timeInterpreter wid Nothing W. Descending
750
752
[ TxMetaTxId ==. (TxId tid) ]
751
- case metas of
753
+ pendings <- selectTxPending wid W. Descending
754
+ [ TxPendingTxId ==. (TxId tid) ]
755
+ case metas ++ pendings of
752
756
[] -> pure (Right Nothing )
753
757
meta: _ -> pure (Right $ Just meta)
754
758
@@ -1058,7 +1062,6 @@ mkTxMetaEntity :: W.WalletId -> W.Hash "Tx" -> W.TxMeta -> TxMeta
1058
1062
mkTxMetaEntity wid txid meta = TxMeta
1059
1063
{ txMetaTxId = TxId txid
1060
1064
, txMetaWalletId = wid
1061
- , txMetaStatus = meta ^. # status
1062
1065
, txMetaDirection = meta ^. # direction
1063
1066
, txMetaSlot = meta ^. # slotNo
1064
1067
, txMetaBlockHeight = getQuantity (meta ^. # blockHeight)
@@ -1125,6 +1128,60 @@ txHistoryFromEntity ti tip metas ins outs ws =
1125
1128
, W. amount = Quantity (txMetaAmount m)
1126
1129
}
1127
1130
1131
+ txHistoryFromPendingEntity
1132
+ :: W. SlotParameters
1133
+ -> W. BlockHeader
1134
+ -> [TxPending ]
1135
+ -> [(TxIn , Maybe TxOut )]
1136
+ -> [TxOut ]
1137
+ -> [W. TransactionInfo ]
1138
+ txHistoryFromPendingEntity sp tip pendings ins outs =
1139
+ map mkItem pendings
1140
+ where
1141
+ mkItem m = mkTxWith (txMetaTxId m) (mkTxMeta m)
1142
+ mkTxWith txid meta = W. TransactionInfo
1143
+ { W. txInfoId =
1144
+ getTxId txid
1145
+ , W. txInfoInputs =
1146
+ map mkTxIn $ filter ((== txid) . txInputTxId . fst ) ins
1147
+ , W. txInfoOutputs =
1148
+ map mkTxOut $ filter ((== txid) . txOutputTxId) outs
1149
+ , W. txInfoWithdrawals =
1150
+ Map. fromList $ map mkTxWithdrawal $ filter ((== txid) . txWithdrawalTxId) ws
1151
+ , W. txInfoMeta =
1152
+ meta
1153
+ , W. txInfoDepth =
1154
+ Quantity $ fromIntegral $ if tipH > txH then tipH - txH else 0
1155
+ , W. txInfoTime =
1156
+ W. slotStartTime sp (meta ^. # slotId)
1157
+ }
1158
+ where
1159
+ txH = getQuantity (meta ^. # blockHeight)
1160
+ tipH = getQuantity (tip ^. # blockHeight)
1161
+ mkTxIn (tx, out) =
1162
+ ( W. TxIn
1163
+ { W. inputId = getTxId (txInputSourceTxId tx)
1164
+ , W. inputIx = txInputSourceIndex tx
1165
+ }
1166
+ , txInputSourceAmount tx
1167
+ , mkTxOut <$> out
1168
+ )
1169
+ mkTxOut tx = W. TxOut
1170
+ { W. address = txOutputAddress tx
1171
+ , W. coin = txOutputAmount tx
1172
+ }
1173
+ mkTxWithdrawal w =
1174
+ ( txWithdrawalAccount w
1175
+ , txWithdrawalAmount w
1176
+ )
1177
+ mkTxMeta m = W. TxMeta
1178
+ { W. status = txMetaStatus m
1179
+ , W. direction = txMetaDirection m
1180
+ , W. slotId = txMetaSlot m
1181
+ , W. blockHeight = Quantity (txMetaBlockHeight m)
1182
+ , W. amount = Quantity (txMetaAmount m)
1183
+ }
1184
+
1128
1185
mkProtocolParametersEntity
1129
1186
:: W. WalletId
1130
1187
-> W. ProtocolParameters
@@ -1208,14 +1265,6 @@ deleteStakeKeyCerts
1208
1265
deleteStakeKeyCerts wid filters =
1209
1266
deleteWhere ((StakeKeyCertWalletId ==. wid) : filters)
1210
1267
1211
- updateTxMetas
1212
- :: W. WalletId
1213
- -> [Filter TxMeta ]
1214
- -> [Update TxMeta ]
1215
- -> SqlPersistT IO ()
1216
- updateTxMetas wid filters =
1217
- updateWhere ((TxMetaWalletId ==. wid) : filters)
1218
-
1219
1268
-- | Add new TxMeta rows, overwriting existing ones.
1220
1269
putTxMetas :: [TxMeta ] -> SqlPersistT IO ()
1221
1270
putTxMetas metas = dbChunked repsertMany
@@ -1376,20 +1425,48 @@ selectTxHistory ti wid minWithdrawal order conditions = do
1376
1425
W. Ascending -> [Asc TxMetaSlot , Desc TxMetaTxId ]
1377
1426
W. Descending -> [Desc TxMetaSlot , Asc TxMetaTxId ]
1378
1427
1428
+ selectTxPending
1429
+ :: W. WalletId
1430
+ -> W. SortOrder
1431
+ -> [Filter TxPending ]
1432
+ -> SqlPersistT IO [W. TransactionInfo ]
1433
+ selectTxPending wid order conditions = do
1434
+ selectLatestCheckpoint wid >>= \ case
1435
+ Nothing -> pure []
1436
+ Just cp -> do
1437
+ pendings <- fmap entityVal <$> selectList
1438
+ ((TxPendingWalletId ==. wid): conditions)
1439
+ sortOpt
1440
+
1441
+ let txids = map txPendingTxId pendings
1442
+ (ins, outs, _) <- selectTxs txids
1443
+
1444
+ let wal = checkpointFromEntity cp [] ()
1445
+ let tip = W. currentTip wal
1446
+ let slp = W. slotParams $ W. blockchainParameters wal
1447
+
1448
+ return $ txHistoryFromEntity slp tip pendings ins outs
1449
+ where
1450
+ -- Note: The secondary sort by TxId is to make the ordering stable
1451
+ -- so that testing with random data always works.
1452
+ sortOpt = case order of
1453
+ W. Ascending -> [Asc TxPendingSlotCreated , Desc TxPendingTxId ]
1454
+ W. Descending -> [Desc TxPendingSlotCreated , Asc TxPendingTxId ]
1455
+
1379
1456
selectPendingTxs
1380
1457
:: W. WalletId
1381
1458
-> TxId
1382
- -> SqlPersistT IO [TxMeta ]
1459
+ -> SqlPersistT IO [TxPending ]
1383
1460
selectPendingTxs wid tid =
1384
1461
fmap entityVal <$> selectList
1385
- [TxMetaWalletId ==. wid, TxMetaTxId ==. tid] []
1462
+ [TxPendingWalletId ==. wid, TxPendingTxId ==. tid] []
1386
1463
1387
1464
deletePendingTx
1388
1465
:: W. WalletId
1389
1466
-> TxId
1390
1467
-> SqlPersistT IO ()
1391
1468
deletePendingTx wid tid = deleteWhere
1392
- [TxMetaWalletId ==. wid, TxMetaTxId ==. tid, TxMetaStatus ==. W. Pending ]
1469
+ [TxPendingWalletId ==. wid, TxPendingTxId ==. tid]
1393
1470
1394
1471
selectPrivateKey
1395
1472
:: (MonadIO m , PersistPrivateKey (k 'RootK))
0 commit comments