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

Fork the Selection type. #3111

Merged
merged 4 commits into from
Feb 8, 2022
Merged

Conversation

jonathanknowles
Copy link
Contributor

@jonathanknowles jonathanknowles commented Feb 8, 2022

Issue Number

ADP-1410

Background

The original Selection type was polymorphic in the type of change outputs. The intention behind this was to allow the wallet to reuse the Selection type in different contexts, both before and after assigning addresses to change outputs.

However, the internal coin selection library is not concerned with assigning addresses to change outputs. Assigning change addresses is a function of the wallet, rather than the coin selection library, and the coin selection library shouldn't have to be concerned with this detail.

Moreover, requiring the internal coin selection library's Selection type to be polymorphic in the type of change outputs makes the internal library functions and types more complicated than necessary.

Primary Changes

This PR:

  • Forks the Selection type into two separate types:
    1. A wallet-specific type,
      located in and exported from Cardano.Wallet.CoinSelection
      where the type of change is kept polymorphic (as is currently the case).
    2. An internal type,
      located in and exported from Cardano.Wallet.CoinSelection.Internal
      where the type of change is just [TokenBundle].
  • Provides a pair of functions to{External,Internal}Selection within Cardano.Wallet.CoinSelection to handle conversion between these two types.

Additional Changes

This PR also:

  • Moves the SelectionReport type (and related functions) to the wallet-specific Cardano.Wallet.CoinSelection module, as this is only required by the wallet, and not required by the internal coin selection library.

Motivation

  • Forking the Selection type will make it easier to make further simplifications to the internal type, as we can restrict any breakage to the to{External,Internal}Selection functions.
  • Retaining the original wallet-specific type means that we don’t have to make any changes to wallet code (which relies on change being polymorphic) as part of the library extraction process. If we eventually want to change the wallet-specific type to something else, we can change it later on.

The `SelectionReport` type exists purely in order to provide the wallet
with a way to write a report about a selection to the log.

It's not required or used by the internal coin selection library, and
therefore it can be moved to the wallet-specific coin selection module.
@jonathanknowles jonathanknowles self-assigned this Feb 8, 2022
The original `Selection` type was polymorphic in the type of change
outputs. The intention behind this was to allow the wallet to reuse the
`Selection` type in different contexts, both before and after assigning
change outputs with addresses.

However, the internal coin selection library is not concerned with
assigning addresses to change outputs. Assigning change addresses is a
function of the wallet, rather than the coin selection library, and the
coin selection library should not have to be concerned with this detail.

Moreover, requiring the internal coin selection library's `Selection` type
to be polymorphic in the type of change outputs makes the internal
library functions and types more complicated than necessary.

This change forks the `Selection` type into two separate types:

  - A wallet-specific type,
    located in `Cardano.Wallet.CoinSelection`,
    where the type of `change` is kept polymorphic (as it currently is).

  - An internal type,
    located in `Cardano.Wallet.CoinSelection.Internal`,
    where the type of `change` is simply `TokenBundle`.

We also provide a pair of functions `to{External,Internal}Selection`
located in `Cardano.Wallet.CoinSelection` to handle conversion between these
two types.

The forking of this type into two will make it easier to make further
simplifications to the internal type, as we can restrict any breakage
to the `to{External,Internal}Selection` functions.
@jonathanknowles jonathanknowles force-pushed the jonathanknowles/fork-selection-type branch from 6634598 to 144e43c Compare February 8, 2022 07:10
@HeinrichApfelmus HeinrichApfelmus self-requested a review February 8, 2022 11:25
Copy link
Contributor

@HeinrichApfelmus HeinrichApfelmus left a comment

Choose a reason for hiding this comment

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

Looks good to me! The monomorphic version of Selection is indeed no less general than the polymorphic one.

The specific form of the address may be relevant when estimating fees, though. But it's currently overestimated anyway. 🤔

@jonathanknowles
Copy link
Contributor Author

The specific form of the address may be relevant when estimating fees, though. But it's currently overestimated anyway.

Yes, it's currently overestimated!

If it turns out to be necessary in future, we could introduce an abstraction that gives the "cost" of a particular input, or the cost of a particular "address", hopefully without the library needing to know about the Address type.

@jonathanknowles
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request Feb 8, 2022
3111: Fork the `Selection` type. r=jonathanknowles a=jonathanknowles

## Issue Number

ADP-1410

## Background

The original `Selection` type was **_polymorphic_** in the type of **_change outputs_**. The intention behind this was to allow the wallet to reuse the `Selection` type in different contexts, _both_ **before** _and_ **after** assigning addresses to change outputs.

However, the internal coin selection library is **not** concerned with assigning addresses to change outputs. Assigning change addresses is a function of the **wallet**, rather than the coin selection library, and the coin selection library shouldn't have to be concerned with this detail.

Moreover, requiring the internal coin selection library's `Selection` type to be polymorphic in the type of change outputs makes the internal library functions and types more complicated than necessary.

## Primary Changes

This PR:

- [x] Forks the `Selection` type into two separate types:
    1. A wallet-specific type,
        located in and exported from `Cardano.Wallet.CoinSelection`
        where the type of `change` is kept polymorphic (as is currently the case).
    2. An internal type,
        located in and exported from `Cardano.Wallet.CoinSelection.Internal`
        where the type of `change` is just `[TokenBundle]`.
- [x] Provides a pair of functions `to{External,Internal}Selection` within `Cardano.Wallet.CoinSelection` to handle conversion between these two types.

## Additional Changes

This PR also:
- [x] Moves the `SelectionReport` type (and related functions) to the wallet-specific `Cardano.Wallet.CoinSelection` module, as this is only required by the wallet, and not required by the internal coin selection library.

## Motivation

- Forking the `Selection` type will make it easier to make further simplifications to the internal type, as we can restrict any breakage to the `to{External,Internal}Selection` functions.
- Retaining the original wallet-specific type means that we don’t have to make any changes to wallet code (which relies on `change` being polymorphic) as part of the library extraction process. If we eventually want to change the wallet-specific type to something else, we can change it later on.


Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Feb 8, 2022

Build failed:

Encountered error while migrating Pantry database:
    SQLite3 returned ErrorNotFound while attempting to perform prepare "SELECT sql FROM sqlite_master WHERE type='table' AND name=?": database disk image is malformed
Please report this on https://github.com/commercialhaskell/stack/issues
As a workaround you may delete Pantry database in /build/cardano-wallet.stack/pantry/pantry.sqlite3 triggering its recreation.
error: Command exited with code 1!

#3120

@jonathanknowles
Copy link
Contributor Author

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Feb 8, 2022

Build succeeded:

@iohk-bors iohk-bors bot merged commit 13a6c0b into master Feb 8, 2022
@iohk-bors iohk-bors bot deleted the jonathanknowles/fork-selection-type branch February 8, 2022 13:36
WilliamKingNoel-Bot pushed a commit that referenced this pull request Feb 8, 2022
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.

2 participants