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

Implement sizeOfCoin and costOfIncreasingCoin #3215

Merged
merged 19 commits into from
Apr 8, 2022

Conversation

Anviking
Copy link
Member

@Anviking Anviking commented Apr 4, 2022

Implement and test the following functions:

-- | Calculate the cost of increasing a CBOR-encoded Coin-value by another Coin
-- with the lovelace/byte cost given by the 'FeePolicy'.
--
-- Outputs values in the range of [0, 8 * perByteFee]
--
-- >>> let p = FeePolicy (Quantity 0) (Quantity 44)
--
-- >>> costOfIncreasingCoin p 4294967295 1
-- Coin 176 -- (9 bytes - 5 bytes) * 44 lovelace/byte
--
-- >>> costOfIncreasingCoin p 0 4294967296
-- Coin 352 -- 8 bytes * 44 lovelace/byte
costOfIncreasingCoin
    :: FeePolicy
    -> Coin -- ^ Original coin
    -> Coin -- ^ Increment
    -> Coin

-- | Calculate the size of a coin when encoded as CBOR.
sizeOfCoin :: Coin -> TxSize

Future work

The next PR will add a function to TransactionLayer with the following shape:

    , distributeSurplus
        :: FeePolicy
        -> Coin -- Surplus to distribute
        -> TxFeeAndChange
        -> Either Coin TxFeeAndChange

Issue number

ADP-1514

@Anviking Anviking changed the title Add sizeOfCoin and costOfIncreasingCoin Implement sizeOfCoin and costOfIncreasingCoin Apr 4, 2022
@Anviking Anviking self-assigned this Apr 4, 2022
@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch from fe581ab to 0a3e29c Compare April 4, 2022 10:44
@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch from 1346eab to b13793b Compare April 4, 2022 10:47
@Anviking Anviking requested a review from jonathanknowles April 4, 2022 10:48
@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch 2 times, most recently from 3eea663 to b17b6a8 Compare April 4, 2022 14:13
Copy link
Contributor

@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 @Anviking

I've made some general comments and suggestions. Will have another look in a bit!

lib/core/src/Cardano/Api/Gen.hs Outdated Show resolved Hide resolved
lib/core/src/Cardano/Api/Gen.hs Outdated Show resolved Hide resolved
lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs Outdated Show resolved Hide resolved
lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs Outdated Show resolved Hide resolved
it "costs 176 lovelace to increase 4294967295 by one on mainnet" $ do
let feePolicy = LinearFee $ LinearFunction
{ intercept = 150_000, slope = 44 }
costOfIncreasingCoin feePolicy (Coin 4294967295) (Coin 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: use an explicit power of 2 here.

Justification: it's now really obvious why this is a boundary. (Some readers of the code might not recognize that these values are related to the powers of 2.)

Suggested change
costOfIncreasingCoin feePolicy (Coin 4294967295) (Coin 1)
costOfIncreasingCoin feePolicy (Coin $ 2^32 - 1) (Coin 1)

Copy link
Member Author

Choose a reason for hiding this comment

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

#3215 (comment), however because of the test title I think it in particular makes sense to use 4294967295 here. I tweaked the title a bit: 1303e02

lib/core/src/Cardano/Api/Gen.hs Show resolved Hide resolved
@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch from d496b19 to 98a73ec Compare April 6, 2022 14:25
@Anviking
Copy link
Member Author

Anviking commented Apr 6, 2022

@jonathanknowles about changing 4294967296 to 2^32 — we could do that. To me, however, it is much easier to correlate 4_294_967_296 and 65_536 with imagined scenarios on mainnet. For instance, the first could be a common output value, whereas the second should practically never be seen. This stands out less clearly when seeing 2^32 or 2^16.

Also I believe the real values are easier to correlate to failures from prop_balanceTransactionValid, which may look like:

( SealedTx
    ( InAnyCardanoEra AlonzoEra
        ( ShelleyTx ShelleyBasedEraAlonzo
            ( ValidatedTx
                { body = TxBodyConstr TxBodyRaw
                    { _inputs = fromList
                        [ TxInCompact
                            ( TxId
                                { _unTxId = SafeHash "01f4b788593d4f70de2a45c2e1e87088bfbdfa29577ae1b62aba60e095e3ab53" }
                            ) 1
                        ]
                    , _collateral = fromList []
                    , _outputs = StrictSeq
                        { fromStrict = fromList
                            [
                                ( Addr Mainnet
                                    ( ScriptHashObj
                                        ( ScriptHash "13a0e59ca61ab277e909ffd20def27d296051fbc634cf623c02322a5" )
                                    ) StakeRefNull
                                , Value 4295103487
                                    ( fromList [] )
                                , SNothing
                                )
                            ]
                        }
                    , _certs = StrictSeq
                        { fromStrict = fromList [] }
                    , _wdrls = Wdrl
                        { unWdrl = fromList [] }
                    , _txfee = Coin 164269
                    , _vldt = ValidityInterval
                        { invalidBefore = SJust
                            ( SlotNo 1 )
                        , invalidHereafter = SJust
                            ( SlotNo 1 )
                        }

So in my mind "why are these values magic" is less important than "these are the magic values", although I admit there's some neatness to #3215 (comment). What do you think?

@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch from 21e87d7 to 1303e02 Compare April 6, 2022 15:14
Anviking and others added 16 commits April 7, 2022 16:01
This improves coverage of boundary cases in sizeOfCoin properties.
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Use 4-space indents, and put exports into alphabetical order.
This commit also uses these named constants in `genLovelace` to replace
hard-coded values.

If a developer is new to the codebase, they can understand the choice of
these constants by navigating to their definitions and reading the
comments.
Since `Lovelace` is an instance of `Num` and `Random`, we can avoid
wrapping and unwrapping `Lovelace` values when using `choose`.
In the implementation of `sizeOfCoin`, we use hard-coded constants for
powers of two, which avoids computing these values on each call.

However, in the test code, we can be even clearer about our intent, by
explicitly stating which powers of two we're interested in.

For someone new to the codebase, being able to see the relationship with
the powers of two is arguably helpful for being able to comprehend why
we're testing these particular values.

At a glance, it's arguably quite hard to see the the difference between:
    - 4294967295
    - 4294967296

But it's very easy to see the difference between:
    - 2^32 - 1
    - 2^32
jonathanknowles and others added 3 commits April 7, 2022 16:01
In this commit, we also remove the expected cost increase from the name
of the test. Otherwise, if someone updates this constant in future, it's
possible that they'll forget to update the name of the test case, and
the compiler won't tell them.
- Lead with "[it] costs"
- Clearly specify the ≈4.29 ada value in the title
@Anviking Anviking force-pushed the anviking/ADP-1514/costOfIncreasingCoin branch from a285cec to ab82b9d Compare April 7, 2022 14:04
@Anviking Anviking requested a review from jonathanknowles April 7, 2022 18:51
Copy link
Contributor

@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.

Nice work! 👍🏻

@jonathanknowles
Copy link
Contributor

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Apr 8, 2022

Build succeeded:

@iohk-bors iohk-bors bot merged commit a854531 into master Apr 8, 2022
@iohk-bors iohk-bors bot deleted the anviking/ADP-1514/costOfIncreasingCoin branch April 8, 2022 02:57
WilliamKingNoel-Bot pushed a commit that referenced this pull request Apr 8, 2022
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
iohk-bors bot added a commit that referenced this pull request Apr 19, 2022
3223: Implement `distributeSurplus` and use in `balanceTransaction` r=Anviking a=Anviking

- [x] Factors out fee-minimisation logic such that it can be made more sophisticated and tested separately from `balanceTransaction`
- [x] Fee- and change-related padding before fee-minimisation is _increased_.
- [x] The padding _after_ fee-minimisation is (in most cases) _removed_ (see goldens; we are no longer overpaying the fee with 176 lovelace)
- [x] The fee minimisation is more robust, and should work regardless of ProtocolParameters, whether a 5 ada fee is required, or a 21 lovelace one.
- <s>[ ] Implement `guardReasonableExcessFee` based on `2 * minUTxOValue`, rather than using the hard-coded limit of 20 ada. </s>
- <s>[ ] Extra: adjust error types (could be moved to separate PR)</s>
- [x] Look over comments & polish etc

### Comments

- Depends on #3215 

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

ADP-1514

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Johannes Lund <johannes.lund@iohk.io>
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