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

Modify coin selection algorithm to support minting and burning #2725

Merged
merged 40 commits into from
Jul 8, 2021

Conversation

sevanspowell
Copy link
Contributor

@sevanspowell sevanspowell commented Jun 18, 2021

Issue Number

ADP-997
ADP-346

Pre-merge checks

  • Perform soak test of test suite to ensure no flakiness has been introduced.
    (✅ 200 test runs with --match "RoundRobin" passed with no failures.)

Overview

This PR modifies the coin selection algorithm to account for minting and burning.

  • Modifies "performSelection" to account for minted and burnt tokens. On a superficial level, mints provide extra tokens to use, where burns increase the amount of tokens we need to select.
  • Modifies the "makeChange" algorithm to account for minted and burnt tokens. When tokens are minted they are added to the largest change bundle. When tokens are burnt they are removed from the smallest change bundles until the burn has been satisfied. See the code for more detailed commentary.
  • Adds property tests that ensure the "addMintChange" and "removeBurnChange" family of functions:
    • maintain number of change bundles,
    • maintain partial ascending ordering of change bundles
    • modify the total value of the change bundle by their respective mint/burn amounts.
  • Adds a few unit tests to ensure the change generation occurs as we expect it to.
  • Adds some debugging information to the coin selection tests to make debugging in the presence of minting and burning easier.

@piotr-iohk
Copy link
Contributor

🤔 Interesting, sending POST on this branch to the ep gives me 405:

$ curl -X POST http://localhost:8090/v2/wallets/1b0aa24994b4181e79116c131510f2abf6cdaa4f/assets \
-d '{"mint_burn":{"monetary_policy_index":"11","asset_name":"484148414841","operations":[{"mint":{"receiving_address":"addr_test1qq223dyrt96yx79rz3yda2vs6xjx28ts2ax39hp8cxq2p0shpgwhzykzha0z6w27gxsps40gurvxjt2vxh26009q5wqqxpj2ey","amount":{"quantity":14,"unit":"assets"}}},{"burn":{"quantity":14,"unit":"assets"}}]},"passphrase":"Secure Passphrase","metadata":{"0":{"string":"cardano"},"1":{"int":14},"2":{"bytes":"2512a00e9653fe49a44a5886202e24d77eeb998f"},"3":{"list":[{"int":14},{"int":42},{"string":"1337"}]},"4":{"map":[{"k":{"string":"key"},"v":{"string":"value"}},{"k":{"int":14},"v":{"int":42}}]}},"time_to_live":{"quantity":10,"unit":"second"}}' -H "Content-Type: application/json" | jq


{
  "code": "method_not_allowed",
  "message": "You've reached a known endpoint but I don't know how to handle the HTTP method specified. Please double-check both the endpoint and the method: one of them is likely to be incorrect (for example: POST instead of PUT, or GET instead of POST...)."
}

@sevanspowell
Copy link
Contributor Author

sevanspowell commented Jun 18, 2021

Interesting, sending POST on this branch to the ep gives me 405:

$ curl -X POST http://localhost:8090/v2/wallets/1b0aa24994b4181e79116c131510f2abf6cdaa4f/assets \
-d '{"mint_burn":{"monetary_policy_index":"11","asset_name":"484148414841","operations":[{"mint":{"receiving_address":"addr_test1qq223dyrt96yx79rz3yda2vs6xjx28ts2ax39hp8cxq2p0shpgwhzykzha0z6w27gxsps40gurvxjt2vxh26009q5wqqxpj2ey","amount":{"quantity":14,"unit":"assets"}}},{"burn":{"quantity":14,"unit":"assets"}}]},"passphrase":"Secure Passphrase","metadata":{"0":{"string":"cardano"},"1":{"int":14},"2":{"bytes":"2512a00e9653fe49a44a5886202e24d77eeb998f"},"3":{"list":[{"int":14},{"int":42},{"string":"1337"}]},"4":{"map":[{"k":{"string":"key"},"v":{"string":"value"}},{"k":{"int":14},"v":{"int":42}}]}},"time_to_live":{"quantity":10,"unit":"second"}}' -H "Content-Type: application/json" | jq


{
  "code": "method_not_allowed",
  "message": "You've reached a known endpoint but I don't know how to handle the HTTP method specified. Please double-check both the endpoint and the method: one of them is likely to be incorrect (for example: POST instead of PUT, or GET instead of POST...)."
}

Ah, interesting @piotr-iohk. My stub definition was malformed. Should be fixed now. Of course by "fixed" I mean the stub will still return:

< HTTP/1.1 500 Internal Server Error
< Transfer-Encoding: chunked
< Date: Fri, 18 Jun 2021 09:04:34 GMT
< Server: Warp/3.3.14
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
Something went wrong

Because the API endpoint is still stubbed, I've only changed coin selection.

It should correctly verify the form of the request data though!

@sevanspowell sevanspowell force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch from fd4960f to bfd7afa Compare June 18, 2021 09:06
Copy link
Member

@jonathanknowles jonathanknowles left a comment

Choose a reason for hiding this comment

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

Hi @sevanspowell

Many thanks for creating this PR.

I've not yet finished looking through it, but what I've seen so far looks good.

I've added a few comments and suggestions. Will continue looking tomorrow!

Copy link
Member

@jonathanknowles jonathanknowles left a comment

Choose a reason for hiding this comment

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

Hi Sam.

Some more comments. I'm about to look at the property tests. Will leave more comments later!

Copy link
Member

@jonathanknowles jonathanknowles left a comment

Choose a reason for hiding this comment

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

Hi @sevanspowell . Here's a first review of the property tests.

Will add more comments later!

-- "sort it". One quick way to get ascending partial order is to make the
-- change maps ourself. Presuming of course
-- "makeChangeForNonUserSpecifiedAssets" is correctly implemented, which
-- other tests should confirm.
Copy link
Member

@jonathanknowles jonathanknowles Jun 24, 2021

Choose a reason for hiding this comment

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

Suggestion: consider using NE.scanl to generate values in ascending partial order.

You're right that an arbitrary list of TokenMap values [m1, m2, m3, ..., mi] is not ordered.

However, if we treat the generated list as a list of differences, then we can transform those differences into a list that is guaranteed to be in ascending partial order:

[ m1
, m1 <> m2
, m1 <> m2 <> m3
, ...
, mi <> m2 <> m3 <> ... <> mi
]

Full implementation:

prop_addMintValueToChangeMaps_order
    :: (AssetId, TokenQuantity)
    -> NonEmpty TokenMap
    -> Property
prop_addMintValueToChangeMaps_order mint changeMapDiffs =
    property
        $ inAscendingPartialOrder
        $ addMintValueToChangeMaps mint changeMaps
  where
    -- A list of change maps already in ascending partial order.
    changeMaps = NE.scanl (<>) TokenMap.empty changeMapDiffs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Where can I download your smarts? :) Addressed in e77bcc4.

@jonathanknowles jonathanknowles self-requested a review June 25, 2021 09:52
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch from 142c2ee to 0929921 Compare June 29, 2021 07:25
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-api branch from fb3abfc to 7c0636d Compare June 29, 2021 07:27
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch 5 times, most recently from acf5628 to 2295304 Compare June 29, 2021 08:35
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch 6 times, most recently from c5a1985 to efdf9a6 Compare July 6, 2021 04:25
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch from 7e208a0 to 36b2be9 Compare July 8, 2021 05:42
…riteria`.

In particular, we add coverage for the case where some minted values are
not spent or burned, so we can trigger the `OutputsInsufficient` error.
This assertion should have been negated.

The error was only revealed once we had deliberately tweaked the
generator to generate selection criteria with some minted values
that are not spent or burned.
In the `genAssetsToMintAndBurn` subgenerator for `genMakeChangeData`, we
deliberately create the possibliity of a non-empty intersection between
the sets of assets to mint and assets to burn.
@jonathanknowles jonathanknowles force-pushed the sevanspowell/ADP-346/mint-burn-coin-select branch from 36b2be9 to 378d35f Compare July 8, 2021 08:38
@jonathanknowles
Copy link
Member

bors try

iohk-bors bot added a commit that referenced this pull request Jul 8, 2021
@jonathanknowles jonathanknowles self-requested a review July 8, 2021 09:37
Copy link
Member

@jonathanknowles jonathanknowles left a comment

Choose a reason for hiding this comment

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

I've given this a fairly exhaustive review, and added some missing coverage to the test suite. I think it's good to go. 👍🏻

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jul 8, 2021

try

Build succeeded:

@jonathanknowles
Copy link
Member

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jul 8, 2021

Build succeeded:

@iohk-bors iohk-bors bot merged commit 9ef7a6a into master Jul 8, 2021
@iohk-bors iohk-bors bot deleted the sevanspowell/ADP-346/mint-burn-coin-select branch July 8, 2021 13:57
WilliamKingNoel-Bot pushed a commit that referenced this pull request Jul 8, 2021
iohk-bors bot added a commit that referenced this pull request Jul 13, 2021
2756: Add coverage checks to property tests for `TokenMap.intersection`  r=jonathanknowles a=jonathanknowles

# Issue Number

ADP-997

# Pre-merge checks

- [x] Perform soak test of test suite to ensure no flakiness has been introduced.
    (✅ 1000 test runs with `--match "/Token map properties/Arithmetic/prop_intersection"` passed with no failures.)

# Overview

PR #2725 added a `TokenMap.intersection` function and property tests.

This PR:
- [x] adds coverage checks to the `prop_intersection_*` series of properties.
- [x] where necessary, adjusts property inputs in order to attain the required level of coverage.

Co-authored-by: Jonathan Knowles <[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.

4 participants