Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database changes for resubmission of pending transactions #2570

Merged
merged 7 commits into from
Apr 20, 2021

Conversation

rvl
Copy link
Contributor

@rvl rvl commented Mar 19, 2021

Issue Number

ADP-764

Overview

Database layer support for transaction resubmission.

  • Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
  • Add DBLayer method to list pending transactions for resubmissions
  • Add DBLayer method to add a submitted transaction to the pool of transactions.
  • Update db model and state machine tests with generators for new methods
  • Swagger update

The wallet layer and server changes are in PR #2611.

@rvl rvl self-assigned this Mar 19, 2021
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 0ac5c53 to 7f53256 Compare March 23, 2021 08:16
pending <- atomically $ getLocalTxSubmissionPending (PrimaryKey wid)
-- re-submit those transactions, ignore errors
forM_ pending $ \st -> do
-- TODO: compare slots to schedule retries less often
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! That's exactly the bit I was looking for 😶; no schedule yet that is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably won't need anything more sophisticated that resend every n slots.
(Maybe resending every slot is overkill, but perhaps not).

lib/core/src/Cardano/Wallet/DB/Sqlite.hs Show resolved Hide resolved
-> SqlPersistT IO [(W.SlotNo, LocalTxSubmission)]
listPendingLocalTxSubmissionQuery wid = fmap unRaw <$> rawSql query params
where
query = "SELECT meta.slot,?? FROM (select tx_id, status, slot, MAX(slot) AS latest_slot FROM tx_meta WHERE wallet_id=? GROUP by tx_id) AS meta INNER JOIN local_tx_submission ON meta.tx_id=local_tx_submission.tx_id WHERE status=? AND slot=latest_slot"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This MAX(slot) suggests that we are now storing multiple metadata per transaction? This raises an alarm in my head for some reasons I am not yet able to explain. I'd like to review the implication of this a bit more carefully (will do in a next review).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this check isn't needed. There is only ever one TxMeta per txid per wallet. In the case of rollback, the status field is mutated.

@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch 2 times, most recently from d2fecfa to 8bee89a Compare March 29, 2021 06:24
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 8bee89a to 0c5a214 Compare March 29, 2021 07:35
@rvl rvl changed the base branch from master to rvl/adp-764/tx-submit-logging March 29, 2021 07:36
@rvl rvl force-pushed the rvl/adp-764/tx-submit-logging branch from c80226d to e267153 Compare March 29, 2021 11:38
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 0c5a214 to 39f3c0c Compare March 29, 2021 11:39
@rvl rvl force-pushed the rvl/adp-764/tx-submit-logging branch from e267153 to 74e1b08 Compare March 29, 2021 12:07
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 39f3c0c to afd0f98 Compare March 29, 2021 12:09
@Anviking
Copy link
Member

I came across this code, and wondered: how should tx retrying work across era-boundaries?

IIRC, the node has some way of converting past-era txs to new-era txs? If so I guess we should simply try to decode the SealedTx as any era tx, not necessarily just the current one.

@rvl rvl force-pushed the rvl/adp-764/tx-submit-logging branch 2 times, most recently from 945ec7e to a174b7a Compare March 30, 2021 00:39
iohk-bors bot added a commit that referenced this pull request Mar 30, 2021
2585: Switch to use separate Win32-network repository r=rvl a=newhoggy

# Issue Number
N/A

# Overview
`Win32-network` has been move to a separate repository.  Updating dependencies accordingly.

# Comments
N/A


2586: Add logging of tx submission r=rvl a=rvl

### Issue Number

ADP-630 / ADP-764

### Overview

These are some logging/worker improvements I made in #2570. I'll put them in a separate PR because they overlap with #2583.

- Adds logging of transaction submission results in the wallet layer.
- Fixes the logging types in the tracer bundle.
- Removes duplication between `initWorker` and `registerWorker`.


Co-authored-by: John Ky <[email protected]>
Co-authored-by: Rodney Lorrimar <[email protected]>
Co-authored-by: IOHK <[email protected]>
Base automatically changed from rvl/adp-764/tx-submit-logging to master March 30, 2021 01:58
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from afd0f98 to 4c5c65b Compare March 30, 2021 03:51
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch 2 times, most recently from 072f69f to 7347449 Compare April 6, 2021 05:53
newtype PrimaryKey key = PrimaryKey key
deriving (Show, Eq, Ord)
newtype PrimaryKey key = PrimaryKey { unPrimaryKey :: key }
deriving (Show, Eq, Ord, Generic, NFData)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side-note: I am not sure this PrimaryKey type is any useful nowadays. Not the point of this PR, but we could perhaps leave a TODO / FIXME note about removing this altogether, it just creates noise in many places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes - that's what I thought too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll sort this in the next PR.

@@ -1517,6 +1534,7 @@ newDBLayerWith cacheBehavior tr ti SqliteContext{runQuery} = do
Nothing -> pure errNoSuchTransaction
Just _ -> do
count <- deletePendingOrExpiredTx wid tid
deleteLocalTxSubmission wid [TxId tid]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be possible maybe to handle that using database constraints and have a cascade delete referencing the TxMeta table? There can't be a local submission without metadata, so if we delete the metadata, it makes sense to delete the tx submission in cascade and we don't have to worry about doing it manually 🤔 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - it makes things simpler.

--
-- The current implementation is really basic. Retry every 10 slots.
scheduleLocalTxSubmission :: LocalTxSubmissionStatus tx -> SlotNo
scheduleLocalTxSubmission st = (st ^. #latestSubmission) + 10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that's about half the block frequency on mainnet, which would means effectively retrying on every block. Maybe a little excessive for exchanges & al, but I see no harm doing this otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #2611

(st ^. #txId)
(st ^. #submittedTx)
sl
watchNodeTip submitPending
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 768b17d to f0bdffc Compare April 9, 2021 09:01
@rvl rvl mentioned this pull request Apr 9, 2021
17 tasks
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from f0bdffc to ad4fed0 Compare April 10, 2021 03:42
@rvl rvl changed the title Wallet DBLayer changes for retrying LocalTxSubmission Retry submission of pending transactions Apr 10, 2021
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch 2 times, most recently from 92557f4 to 923d3df Compare April 13, 2021 22:01
@rvl rvl marked this pull request as ready for review April 13, 2021 22:07
@rvl rvl changed the title Retry submission of pending transactions Database changes for resubmission of pending transactions Apr 13, 2021
@rvl rvl force-pushed the rvl/adp-764/retry-local-tx-submission branch from 32f7078 to 0e9623f Compare April 19, 2021 11:24
@rvl
Copy link
Contributor Author

rvl commented Apr 19, 2021

I believe all review comments so far have been addressed.

@rvl
Copy link
Contributor Author

rvl commented Apr 19, 2021

bors try

iohk-bors bot added a commit that referenced this pull request Apr 19, 2021
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 19, 2021

try

Build failed:

#2472

@rvl
Copy link
Contributor Author

rvl commented Apr 20, 2021

bors r+

iohk-bors bot added a commit that referenced this pull request Apr 20, 2021
2570: Database changes for resubmission of pending transactions r=rvl a=rvl

### Issue Number

ADP-764

### Overview

Database layer support for transaction resubmission.

   - [x] Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
   - [x] Add DBLayer method to list pending transactions for resubmissions
   - [x] Add DBLayer method to add a submitted transaction to the pool of transactions.
   - [x] Update db model and state machine tests with generators for new methods
   - [x] Swagger update

The wallet layer and server changes are in PR #2611.


Co-authored-by: Rodney Lorrimar <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build failed:


cardano-wallet             >   src/Test/Integration/Scenario/CLI/Shelley/HWWallets.hs:152:26:
--
  | cardano-wallet             >   1) CLI Specifications, SHELLEY_CLI_HW_WALLETS, HW_WALLETS_01x - Restoration from account public key preserves funds
  | cardano-wallet             >        While verifying ApiWallet {id = ApiT {getApiT = WalletId {getWalletId = c0f7e53cfb8657101113c266271cac05f800180d}}, addressPoolGap = ApiT {getApiT = AddressPoolGap {getAddressPoolGap = 20}}, balance = ApiWalletBalance {available = Quantity {getQuantity = 0}, total = Quantity {getQuantity = 0}, reward = Quantity {getQuantity = 0}}, assets = ApiWalletAssetsBalance {available = ApiT {getApiT = TokenMap (fromList [])}, total = ApiT {getApiT = TokenMap (fromList [])}}, delegation = ApiWalletDelegation {active = ApiWalletDelegationNext {status = NotDelegating, target = Nothing, changesAt = Nothing}, next = []}, name = ApiT {getApiT = WalletName {getWalletName = "Wallet from pub key"}}, passphrase = Nothing, state = ApiT {getApiT = Syncing (Quantity {getQuantity = Percentage {getPercentage = 4971 % 10000}})}, tip = ApiBlockReference {absoluteSlotNumber = ApiT {getApiT = SlotNo 4002}, slotId = ApiSlotId {epochNumber = ApiT {getApiT = EpochNo {unEpochNo = 80}}, slotNumber = ApiT {getApiT = SlotInEpoch {unSlotInEpoch = 2}}}, time = 2021-04-20 06:21:56.4 UTC, block = ApiBlockInfo {height = Quantity {getQuantity = 2000}}}}
  | cardano-wallet             >        Waited longer than 90s to resolve action: "Wallet balance is as expected on wallet from pubKey".
  | cardano-wallet             >        expected: Quantity {getQuantity = 1000000}
  | cardano-wallet             >         but got: Quantity {getQuantity = 0}
  | cardano-wallet             >
  | cardano-wallet             >   To rerun use: --match "/CLI Specifications/SHELLEY_CLI_HW_WALLETS/HW_WALLETS_01x - Restoration from account public key preserves funds/"


#2428

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Apr 20, 2021
2570: Database changes for resubmission of pending transactions r=Anviking a=rvl

### Issue Number

ADP-764

### Overview

Database layer support for transaction resubmission.

   - [x] Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
   - [x] Add DBLayer method to list pending transactions for resubmissions
   - [x] Add DBLayer method to add a submitted transaction to the pool of transactions.
   - [x] Update db model and state machine tests with generators for new methods
   - [x] Swagger update

The wallet layer and server changes are in PR #2611.


Co-authored-by: Rodney Lorrimar <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build failed:


cardano-wallet             >   src/Test/Integration/Scenario/CLI/Shelley/HWWallets.hs:152:26:
--
  | cardano-wallet             >   1) CLI Specifications, SHELLEY_CLI_HW_WALLETS, HW_WALLETS_01x - Restoration from account public key preserves funds
  | cardano-wallet             >        While verifying ApiWallet {id = ApiT {getApiT = WalletId {getWalletId = 3b41129d303de64174609b4638987ebb4d3b7d6e}}, addressPoolGap = ApiT {getApiT = AddressPoolGap {getAddressPoolGap = 20}}, balance = ApiWalletBalance {available = Quantity {getQuantity = 0}, total = Quantity {getQuantity = 0}, reward = Quantity {getQuantity = 0}}, assets = ApiWalletAssetsBalance {available = ApiT {getApiT = TokenMap (fromList [])}, total = ApiT {getApiT = TokenMap (fromList [])}}, delegation = ApiWalletDelegation {active = ApiWalletDelegationNext {status = NotDelegating, target = Nothing, changesAt = Nothing}, next = []}, name = ApiT {getApiT = WalletName {getWalletName = "Wallet from pub key"}}, passphrase = Nothing, state = ApiT {getApiT = Syncing (Quantity {getQuantity = Percentage {getPercentage = 8031 % 10000}})}, tip = ApiBlockReference {absoluteSlotNumber = ApiT {getApiT = SlotNo 5979}, slotId = ApiSlotId {epochNumber = ApiT {getApiT = EpochNo {unEpochNo = 119}}, slotNumber = ApiT {getApiT = SlotInEpoch {unSlotInEpoch = 29}}}, time = 2021-04-20 11:53:32.8 UTC, block = ApiBlockInfo {height = Quantity {getQuantity = 3000}}}}
  | cardano-wallet             >        Waited longer than 90s to resolve action: "Wallet balance is as expected on wallet from pubKey".
  | cardano-wallet             > [cardano-wallet.network:Warning:48911] [2021-04-20 12:00:28.27 UTC] Connection lost with the node. Network.Socket.recvBuf: resource vanished (Connection reset by peer)
  | cardano-wallet             > [cardano-wallet.network:Warning:48265] [2021-04-20 12:00:28.27 UTC] Connection lost with the node. Network.Socket.recvBuf: resource vanished (Connection reset by peer)
  | cardano-wallet             > [cardano-wallet.network:Warning:49095] [2021-04-20 12:00:28.28 UTC] Connection lost with the node. Network.Socket.recvBuf: resource vanished (Connection reset by peer)
  | cardano-wallet             >        expected: Quantity {getQuantity = 1000000}
  | cardano-wallet             >         but got: Quantity {getQuantity = 0}
  | cardano-wallet             >
  | cardano-wallet             >   To rerun use: --match "/CLI Specifications/SHELLEY_CLI_HW_WALLETS/HW_WALLETS_01x - Restoration from account public key preserves funds/"

#2428

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Apr 20, 2021
2570: Database changes for resubmission of pending transactions r=Anviking a=rvl

### Issue Number

ADP-764

### Overview

Database layer support for transaction resubmission.

   - [x] Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
   - [x] Add DBLayer method to list pending transactions for resubmissions
   - [x] Add DBLayer method to add a submitted transaction to the pool of transactions.
   - [x] Update db model and state machine tests with generators for new methods
   - [x] Swagger update

The wallet layer and server changes are in PR #2611.


Co-authored-by: Rodney Lorrimar <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build failed:

  MVar
    Extra Properties about DB initialization
      createWallet . listWallets yields expected results
        +++ OK, passed 100 tests.
building of '/nix/store/sghr8q7kwhdqm52dalrz5yrsd89iw3ir-cardano-wallet-core-test-unit-2021.4.8-check' timed out after 900 seconds of silence

#2472

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Apr 20, 2021
2570: Database changes for resubmission of pending transactions r=Anviking a=rvl

### Issue Number

ADP-764

### Overview

Database layer support for transaction resubmission.

   - [x] Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
   - [x] Add DBLayer method to list pending transactions for resubmissions
   - [x] Add DBLayer method to add a submitted transaction to the pool of transactions.
   - [x] Update db model and state machine tests with generators for new methods
   - [x] Swagger update

The wallet layer and server changes are in PR #2611.


Co-authored-by: Rodney Lorrimar <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build failed:

test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs:442:9:
  1) Cardano.Wallet.Shelley.Transaction, estimateMaxNumberOfInputs for IcarusKey, more outputs ==> less inputs
       Timeout of 300000 microseconds exceeded. (after 390 tests):
         Quantity {getQuantity = 967}
         NonEmpty {getNonEmpty = [TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 6), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 5), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 2), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 5)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 3, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 1), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 2), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 8), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 1)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 4), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 2), rest = fromList [(UnsafeTokenName "TokenB",TokenQuantity 7)]}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 8), rest = fromList [(UnsafeTokenName "TokenB",TokenQuantity 4),(UnsafeTokenName "TokenD",TokenQuantity 6)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 5), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 9)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 8), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 3)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 8), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 2), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 9), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 8)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 10), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 7), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 8), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 1), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 9)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 0, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 2, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 7), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 9, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 6, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 9), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 3), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 0, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 9, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 8), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 9), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 10), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 6, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 6), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 7),(UnsafeTokenName "TokenD",TokenQuantity 1)]}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 8), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 2), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 0, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 0, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 0, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 7), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 8)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 3), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 2), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 8), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 9)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 10), rest = fromList [(UnsafeTokenName "TokenB",TokenQuantity 3)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 6), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 4), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 6)]}),(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 6), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 5)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 20), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 2)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 1), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 12)]}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 13), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 9)]}),(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 1), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 8)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 1), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 4), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 1)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 10), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 4),(UnsafeTokenName "TokenD",TokenQuantity 6)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 8), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 2, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 10), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 6), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 10)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 8), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 6, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 7, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 9), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 9, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 4), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 6, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 1, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 2), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 8), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 9, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 5), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 10), rest = fromList [(UnsafeTokenName "TokenB",TokenQuantity 4),(UnsafeTokenName "TokenC",TokenQuantity 2)]})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 5, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 4, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 10, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 2, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenD",TokenQuantity 1), rest = fromList []})])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 8, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 3, tokens = TokenMap (fromList [])}},TxOut {address = Address {unAddress = "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"}, tokens = TokenBundle {coin = Coin 2, tokens = TokenMap (fromList [(UnsafeTokenPolicyId (Hash "\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170"),NonEmptyMap {least = (UnsafeTokenName "TokenC",TokenQuantity 1), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 14)]}),(UnsafeTokenPolicyId (Hash "\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187\187"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 2), rest = fromList []}),(UnsafeTokenPolicyId (Hash "\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204\204"),NonEmptyMap {least = (UnsafeTokenName "TokenB",TokenQuantity 9), rest = fromList [(UnsafeTokenName "TokenD",TokenQuantity 9)]}),(UnsafeTokenPolicyId (Hash "\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221\221"),NonEmptyMap {least = (UnsafeTokenName "TokenA",TokenQuantity 5), rest = fromList [(UnsafeTokenName "TokenC",TokenQuantity 1),(UnsafeTokenName "TokenD",TokenQuantity 3)]})])}}]}

  To rerun use: --match "/Cardano.Wallet.Shelley.Transaction/estimateMaxNumberOfInputs for IcarusKey/more outputs ==> less inputs/"

#2522

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Apr 20, 2021
2570: Database changes for resubmission of pending transactions r=Anviking a=rvl

### Issue Number

ADP-764

### Overview

Database layer support for transaction resubmission.

   - [x] Adds a new table with serialized transactions, and the latest slot that they have been submitted at.
   - [x] Add DBLayer method to list pending transactions for resubmissions
   - [x] Add DBLayer method to add a submitted transaction to the pool of transactions.
   - [x] Update db model and state machine tests with generators for new methods
   - [x] Swagger update

The wallet layer and server changes are in PR #2611.


Co-authored-by: Rodney Lorrimar <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build failed:

Failures:

  src/Test/Integration/Scenario/API/Byron/Wallets.hs:187:59:
  1) API Specifications, BYRON_WALLETS, BYRON_RESTORE_01, GET_01, LIST_01 - Restore a wallet, trezor 21 words
       While verifying (Status {statusCode = 200, statusMessage = "OK"},Right (ApiByronWallet {id = ApiT {getApiT = WalletId {getWalletId = 0a74f465eca7ce8e367aa0c3500feb71e77e72b3}}, balance = ApiByronWalletBalance {available = Quantity {getQuantity = 0}, total = Quantity {getQuantity = 0}}, assets = ApiWalletAssetsBalance {available = ApiT {getApiT = TokenMap (fromList [])}, total = ApiT {getApiT = TokenMap (fromList [])}}, discovery = DiscoverySequential, name = ApiT {getApiT = WalletName {getWalletName = "Empty Byron Wallet"}}, passphrase = Just (ApiWalletPassphraseInfo {lastUpdatedAt = 2021-04-20 14:56:07.952437 UTC}), state = ApiT {getApiT = Syncing (Quantity {getQuantity = Percentage {getPercentage = 6771 % 10000}})}, tip = ApiBlockReference {absoluteSlotNumber = ApiT {getApiT = SlotNo 2132}, slotId = ApiSlotId {epochNumber = ApiT {getApiT = EpochNo {unEpochNo = 42}}, slotNumber = ApiT {getApiT = SlotInEpoch {unSlotInEpoch = 32}}}, time = 2021-04-20 14:52:46.4 UTC, block = ApiBlockInfo {height = Quantity {getQuantity = 1000}}}}))
       Waited longer than 90s to resolve action: "wallet is available and ready".
[cardano-wallet.network:Warning:51401] [2021-04-20 15:30:57.64 UTC] Connection lost with the node.
       expected: Ready
        but got: Syncing (Quantity {getQuantity = Percentage {getPercentage = 6771 % 10000}})

  To rerun use: --match "/API Specifications/BYRON_WALLETS/BYRON_RESTORE_01, GET_01, LIST_01 - Restore a wallet/trezor 21 words/"

Randomized with seed 1680867042

@Anviking
Copy link
Member

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 20, 2021

Build succeeded:

@iohk-bors iohk-bors bot merged commit 66e1de2 into master Apr 20, 2021
@iohk-bors iohk-bors bot deleted the rvl/adp-764/retry-local-tx-submission branch April 20, 2021 16:28
iohk-bors bot added a commit that referenced this pull request Apr 21, 2021
2611: Retry submission of pending transactions r=rvl a=rvl

### Issue Number

ADP-764

### Overview

Adds tx resubmission to the wallet server.

   - [x] Add a wallet thread for resubmitting transactions
   - [x] Initial version resubmits every pending tx about every 10 blocks after initial submission.
   - [x] Unit test retry thread
   - [x] Design doc

### Comments

- Based on PR #2570 branch - merge that first.



Co-authored-by: Rodney Lorrimar <[email protected]>
iohk-bors bot added a commit that referenced this pull request Apr 21, 2021
2611: Retry submission of pending transactions r=rvl a=rvl

### Issue Number

ADP-764

### Overview

Adds tx resubmission to the wallet server.

   - [x] Add a wallet thread for resubmitting transactions
   - [x] Initial version resubmits every pending tx about every 10 blocks after initial submission.
   - [x] Unit test retry thread
   - [x] Design doc

### Comments

- Based on PR #2570 branch - merge that first.



Co-authored-by: Rodney Lorrimar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants