Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit c93e8b8

Browse files
committed
[CO-432] Adding foreign inputs to prefilter block
[CO-432] fix applyBlockPartial
1 parent e411663 commit c93e8b8

File tree

9 files changed

+165
-121
lines changed

9 files changed

+165
-121
lines changed

Diff for: wallet-new/docs/RelatingWalletSpecToCardano.md

+39-36
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
This document is pinned to these versions of the Cardano code and Wallet Spec:
44

55
- **Cardano code**: Git commits
6-
- 6659d8501c727714a7861ad2e527a337e0a11b86
7-
- e06f3084a24b988e8491003fab7e1dc6c31aeb0c
6+
- 6659d8501c727714a7861ad2e527a337e0a11b86
7+
- e06f3084a24b988e8491003fab7e1dc6c31aeb0c
88
- **Wallet Spec**: v1.2 (12 July 2018)
99

1010
## Introduction
@@ -128,9 +128,9 @@ Each Cardano Wallet _Account_ corresponds to a _Wallet_ in the Wallet Spec.
128128

129129
```haskell
130130
data HdAccount = HdAccount {
131-
...
131+
...
132132
, _hdAccountState :: !HdAccountState
133-
...
133+
...
134134
}
135135

136136
data HdAccountState =
@@ -544,7 +544,7 @@ where
544544

545545
**Fig 3 - Wallet Spec**
546546

547-
| Spec | Code |
547+
| Spec | Code |
548548
| ------------- | ------------------ |
549549
| txins pending | pendingIns |
550550
| </\| | utxoRemoveInputs |
@@ -556,8 +556,8 @@ where
556556
Note: for a `PrefilteredBlock` all intputs and outputs are restricted to "ours".
557557

558558
```haskell
559-
updatePending :: PrefilteredBlock -> Pending -> (Pending, Set Txp.TxId)
560-
updatePending PrefilteredBlock{..} = Pending.removeInputs pfbInputs
559+
updatePending :: Set Core.TxIn -> Pending -> (Pending, Set Txp.TxId)
560+
updatePending inputs = Pending.removeInputs inputs
561561

562562
removeInputs :: Set Core.TxIn -> Pending -> (Pending, Set Core.TxId)
563563
removeInputs usedInputs (toMap -> p) =
@@ -575,9 +575,9 @@ where
575575

576576
**Fig 3 - Wallet Spec**
577577

578-
| Spec | Code |
579-
| ------- | ---------- |
580-
| txins b | pfbInputs |
578+
| Spec | Code |
579+
| ------- | ---------- |
580+
| txins b | pfbInputs |
581581

582582

583583
## Section 4 - Caching Balance
@@ -604,12 +604,12 @@ where
604604

605605
**Fig 5 - Wallet Spec**
606606

607-
| Spec | Code |
608-
| ------ | --------- |
609-
| txins pending | pendingIns |
607+
| Spec | Code |
608+
| ------ | --------- |
609+
| txins pending | pendingIns |
610610
| utxo | c ^. cpUtxo |
611611
| <\| | utxoRestrictToInputs |
612-
| availableBalance | balance' |
612+
| availableBalance | balance' |
613613

614614
### totalBalance
615615

@@ -628,9 +628,9 @@ where
628628

629629
**Fig 5 - Wallet Spec**
630630

631-
| Spec | Code |
632-
| ------ | --------- |
633-
| availableBalance | availableBalance |
631+
| Spec | Code |
632+
| ------ | --------- |
633+
| availableBalance | availableBalance |
634634
| change pending | Core.utxoBalance (cpChange ours c) |
635635
| balance | changeBalance |
636636
| totalBalance | cpTotalBalance |
@@ -677,10 +677,13 @@ data PrefilteredBlock = PrefilteredBlock {
677677
-- | Relevant inputs
678678
pfbInputs :: !(Set TxIn)
679679

680+
-- | Relevant foreign inputs
681+
, pfbForeignInputs :: !(Set TxIn)
682+
680683
-- | Relevant outputs
681684
, pfbOutputs :: !Utxo
682685

683-
...
686+
...
684687
}
685688
```
686689
[AddrWithId,PrefilteredBlock](https://github.com/input-output-hk/cardano-sl/blob/6659d8501c727714a7861ad2e527a337e0a11b86/wallet-new/src/Cardano/Wallet/Kernel/PrefilterTx.hs#L48-L68)
@@ -729,13 +732,13 @@ where
729732

730733
**Fig 6 - Wallet Spec**
731734

732-
| Spec | Code |
733-
| ------ | --------- |
734-
| txins_b | pfbInputs |
735-
| utxo+ | pfbOutputs |
736-
| utxo- | utxoMin |
737-
| utxo' | utxo' |
738-
| sigma' | balance' |
735+
| Spec | Code |
736+
| ------ | --------- |
737+
| txins_b | pfbInputs |
738+
| utxo+ | pfbOutputs |
739+
| utxo- | utxoMin |
740+
| utxo' | utxo' |
741+
| sigma' | balance' |
739742
| <\| | Core.utxoRestrictToInputs |
740743
| </\| | Core.utxoRemoveInputs |
741744

@@ -774,9 +777,9 @@ where
774777

775778
**Fig 7/11 - Wallet Spec**
776779

777-
| Spec | Code |
778-
| ------ | --------- |
779-
| updateUTxo | updateUtxo |
780+
| Spec | Code |
781+
| ------ | --------- |
782+
| updateUTxo | updateUtxo |
780783
| updatePending | updatePending |
781784
| updateExpected | (not implemented) |
782785

@@ -826,8 +829,8 @@ cpCheckAvailable ins c = Set.partition isAvailable ins
826829

827830
where
828831

829-
| Spec | Code |
830-
| ------ | --------- |
832+
| Spec | Code |
833+
| ------ | --------- |
831834
| pending U {tx} | insertPending |
832835
| **precondition:** ins `subset` dom (available) | cpCheckAvailable |
833836

@@ -885,9 +888,9 @@ rollback (NewestFirst (c :| SL.Cons c' cs)) = (NewestFirst $ Checkpoint {
885888

886889
where
887890

888-
| Spec | Code |
889-
| ------ | -------- |
890-
| utxo' | c' ^. checkpointUtxo |
891+
| Spec | Code |
892+
| ------ | -------- |
893+
| utxo' | c' ^. checkpointUtxo |
891894
| pending U pending' | Pending.union (c ...) (c' ...) |
892895
| blockMeta' | c' ^. checkpointBlockMeta |
893896

@@ -1204,8 +1207,8 @@ where
12041207

12051208
**Fig 11 - Wallet Spec**
12061209

1207-
| Spec | Code |
1208-
| ------- | ---------- |
1210+
| Spec | Code |
1211+
| ------- | ---------- |
12091212
| blockMeta U+ blockMeta' | appendBlockMeta |
12101213
| "take the union of block numbers" | _blockMetaSlotId = combineUsing (liftA2 Map.union) |
12111214
| (u,c) U+ (u',c') | _blockMetaAddressMeta = combineUsing (liftA2 (Map.unionWith (<>))) |
@@ -1512,7 +1515,7 @@ initSubmission :: PassiveWallet -> IO ()
15121515
initSubmission pw = do
15131516
pendings <- pendingByAccount <$> getWalletSnapshot pw
15141517
modifyMVar_ (_walletSubmission pw) $
1515-
return . addPendings pendings
1518+
return . addPendings pendings
15161519
```
15171520
Note: the above code was added shortly after this document was pinned to a git hash (hence no link).
15181521

Diff for: wallet-new/src/Cardano/Wallet/Kernel/BListener.hs

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ import Cardano.Wallet.Kernel.Internal
4545
import qualified Cardano.Wallet.Kernel.NodeStateAdaptor as Node
4646
import Cardano.Wallet.Kernel.PrefilterTx (PrefilteredBlock (..),
4747
prefilterBlock)
48-
import Cardano.Wallet.Kernel.Read (getWalletCredentials)
48+
import Cardano.Wallet.Kernel.Read (foreignPendingByAccount,
49+
getWalletCredentials, getWalletSnapshot)
4950
import Cardano.Wallet.Kernel.Restore
5051
import qualified Cardano.Wallet.Kernel.Submission as Submission
5152
import Cardano.Wallet.Kernel.Types (WalletId (..))
@@ -72,9 +73,10 @@ prefilterBlocks :: PassiveWallet
7273
prefilterBlocks pw bs = do
7374
let nm = makeNetworkMagic (pw ^. walletProtocolMagic)
7475
res <- getWalletCredentials pw
76+
foreignPendings <- foreignPendingByAccount <$> getWalletSnapshot pw
7577
return $ case res of
7678
[] -> Nothing
77-
xs -> Just $ map (\b -> first (b ^. rbContext,) $ prefilterBlock nm b xs) bs
79+
xs -> Just $ map (\b -> first (b ^. rbContext,) $ prefilterBlock nm foreignPendings b xs) bs
7880

7981
data BackfillFailed
8082
= SuccessorChanged BlockContext (Maybe BlockContext)

Diff for: wallet-new/src/Cardano/Wallet/Kernel/DB/HdWallet/Read.hs

+9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Cardano.Wallet.Kernel.DB.HdWallet.Read (
1111
, addressesByRootId
1212
, addressesByAccountId
1313
, pendingByAccount
14+
, foreignPendingByAccount
1415
-- | Simple lookups
1516
, lookupHdRootId
1617
, lookupHdAccountId
@@ -79,6 +80,14 @@ pendingByAccount = fmap aux . IxSet.toMap <$> view hdWalletsAccounts
7980
aux :: HdAccount -> Pending
8081
aux acc = acc ^. hdAccountState . hdAccountStateCurrent cpPending
8182

83+
-- | All pending foreign transactions in all accounts
84+
foreignPendingByAccount :: Query' e HdWallets (Map HdAccountId Pending)
85+
foreignPendingByAccount = fmap aux . IxSet.toMap <$> view hdWalletsAccounts
86+
where
87+
aux :: HdAccount -> Pending
88+
aux acc = acc ^. hdAccountState . hdAccountStateCurrent cpForeign
89+
90+
8291
{-------------------------------------------------------------------------------
8392
Simple lookups
8493
-------------------------------------------------------------------------------}

Diff for: wallet-new/src/Cardano/Wallet/Kernel/DB/Read.hs

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Cardano.Wallet.Kernel.DB.Read (
66
, addressesByRootId
77
, addressesByAccountId
88
, pendingByAccount
9+
, foreignPendingByAccount
910
-- | Lookups
1011
, lookupHdRootId
1112
, lookupHdAccountId
@@ -71,6 +72,9 @@ addressesByAccountId = liftNoErrorsHd1 HD.addressesByAccountId
7172
pendingByAccount :: DB -> Map HdAccountId Pending
7273
pendingByAccount = liftNoErrorsHd0 HD.pendingByAccount
7374

75+
foreignPendingByAccount :: DB -> Map HdAccountId Pending
76+
foreignPendingByAccount = liftNoErrorsHd0 HD.foreignPendingByAccount
77+
7478
lookupHdRootId :: DB -> HdRootId -> Either UnknownHdRoot HdRoot
7579
lookupHdRootId = liftHd1 HD.lookupHdRootId
7680

Diff for: wallet-new/src/Cardano/Wallet/Kernel/DB/Spec/Pending.hs

-26
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ module Cardano.Wallet.Kernel.DB.Spec.Pending (
3232
, txOuts
3333
, change
3434
, removeInputs
35-
, removeForeign
3635
, PendingDiff
3736
) where
3837

@@ -179,31 +178,6 @@ removeInputs usedInputs (toMap -> p) =
179178
shouldKeep :: Core.TxAux -> Bool
180179
shouldKeep tx = Util.disjoint (Core.txIns tx) usedInputs
181180

182-
-- | Remove any transactions corresponding to a given Utxo
183-
--
184-
-- We store foreign transaction as `Pending`, using their transaction ids
185-
-- and outputs, however, we filter them based on the UTxO since they don't
186-
-- actually come from our wallet, but from a "foreign" source. Therefore, they
187-
-- appear in blocks as outputs targetting one of our addresses (and not coming
188-
-- from one of them).
189-
removeForeign :: Core.Utxo -> Pending -> (Pending, Set Core.TxId)
190-
removeForeign utxo (toMap -> p) =
191-
let (pToKeep, pToEvict) = Map.partitionWithKey shouldKeep p
192-
in (fromMap pToKeep, Map.keysSet pToEvict)
193-
where
194-
-- | We remove foreign transactions from te Pending map iif their id
195-
-- appear in an available UTxO. It means the transaction has been accepted
196-
-- and isn't pending anymore.
197-
shouldKeep :: Core.TxId -> Core.TxAux -> Bool
198-
shouldKeep txId _ =
199-
not (txId `elem` (mapMaybe toTxId $ Map.keys utxo))
200-
201-
toTxId :: Core.TxIn -> Maybe Core.TxId
202-
toTxId txIn = case txIn of
203-
Core.TxInUtxo txId _ -> Just txId
204-
Core.TxInUnknown _ _ -> Nothing
205-
206-
207181
{-------------------------------------------------------------------------------
208182
Internal auxiliary
209183

Diff for: wallet-new/src/Cardano/Wallet/Kernel/DB/Spec/Update.hs

+7-16
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import Serokell.Util.Text (listBuilderJSON)
3232
import Test.QuickCheck (Arbitrary (..), elements)
3333

3434
import qualified Pos.Chain.Block as Core
35-
import Pos.Chain.Txp (Utxo)
35+
import Pos.Chain.Txp (TxIn, Utxo)
3636
import qualified Pos.Chain.Txp as Txp
3737
import qualified Pos.Core as Core
3838
import Pos.Core.Chrono (NewestFirst (..), OldestFirst (..))
@@ -195,9 +195,9 @@ applyBlock (SecurityParameter k) pb = do
195195
utxo = current ^. checkpointUtxo . fromDb
196196
balance = current ^. checkpointUtxoBalance . fromDb
197197
(utxo', balance') = updateUtxo pb (utxo, balance)
198-
(pending', rem1) = updatePending pb (current ^. checkpointPending)
198+
(pending', rem1) = updatePending (pfbInputs pb) (current ^. checkpointPending)
199199
blockMeta' = updateBlockMeta pb (current ^. checkpointBlockMeta)
200-
(foreign', rem2) = updateForeign pb (current ^. checkpointForeign)
200+
(foreign', rem2) = updatePending (pfbForeignInputs pb) (current ^. checkpointForeign)
201201
if (pfbContext pb) `blockContextSucceeds` (current ^. checkpointContext . lazy) then do
202202
put $ Checkpoints . takeNewest k . NewestFirst $ Checkpoint {
203203
_checkpointUtxo = InDb utxo'
@@ -228,9 +228,9 @@ applyBlockPartial pb = do
228228
utxo = current ^. pcheckpointUtxo . fromDb
229229
balance = current ^. pcheckpointUtxoBalance . fromDb
230230
(utxo', balance') = updateUtxo pb (utxo, balance)
231-
(pending', rem1) = updatePending pb (current ^. pcheckpointPending)
231+
(pending', rem1) = updatePending (pfbInputs pb) (current ^. pcheckpointPending)
232232
blockMeta' = updateLocalBlockMeta pb (current ^. pcheckpointBlockMeta)
233-
(foreign', rem2) = updatePending pb (current ^. pcheckpointForeign)
233+
(foreign', rem2) = updatePending (pfbInputs pb) (current ^. pcheckpointForeign)
234234
if (pfbContext pb) `blockContextSucceeds` (current ^. cpContext . lazy) then do
235235
put $ Checkpoints $ NewestFirst $ PartialCheckpoint {
236236
_pcheckpointUtxo = InDb utxo'
@@ -358,17 +358,8 @@ updateUtxo PrefilteredBlock{..} (utxo, balance) =
358358
-- | Update the pending transactions with the given prefiltered block
359359
--
360360
-- Returns the set of transactions that got removed from the pending set.
361-
updatePending :: PrefilteredBlock -> Pending -> (Pending, Set Txp.TxId)
362-
updatePending PrefilteredBlock{..} = Pending.removeInputs pfbInputs
363-
364-
-- | Update the foreign transactions with the given prefiltered block
365-
--
366-
-- Returns the set of transactions that got removed from the pending set.
367-
-- Note that this is slightly different from pending transactions as it doesn't
368-
-- filter on the "inputs" (which aren't part of the wallet for Foreign
369-
-- transactions) but filter out based on the outputs.
370-
updateForeign :: PrefilteredBlock -> Pending -> (Pending, Set Txp.TxId)
371-
updateForeign PrefilteredBlock{..} = Pending.removeForeign pfbOutputs
361+
updatePending :: Set TxIn -> Pending -> (Pending, Set Txp.TxId)
362+
updatePending inputs = Pending.removeInputs inputs
372363

373364
takeNewest :: Int -> NewestFirst StrictNonEmpty a -> NewestFirst StrictNonEmpty a
374365
takeNewest = liftNewestFirst . SNE.take

0 commit comments

Comments
 (0)