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

ADP-1183 (Part 1): Balancing execution units #2952

Merged
merged 20 commits into from
Oct 11, 2021

Conversation

KtorZ
Copy link
Member

@KtorZ KtorZ commented Oct 6, 2021

  • 📍 Add tx max script execution units to ProtocolParameters

  • 📍 Calculate max script execution cost of transactions instead of relying on redeemers' ex units.
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

  • 📍 Allow changing ExUnits of redeemers on sealed tx
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

  • 📍 Rework balance-tx to always use max execution units.
    This is because, we can't actually predict script execution cost
    before the full final transaction is constructed. So, as a first step,
    we use the biggest approximation we can use which is to always
    consider the max execution steps and memory. While this is NOT okay
    for production code, it is sufficient to kick off preliminary testing
    and integration work.

    The goal is to now, in further commits, adjust the ex units of each
    redeemers after balancing, changing the change output consequently.
    Note that this should not in practice change the cost of execution of
    a script, if it does, then we push back on this by arguing that the
    underlying script validator is bonkers. Developers ought not to do
    this.

  • 📍 Fix typos in comments
    Co-authored-by: paweljakubas [email protected]
    Co-authored-by: Jonathan Knowles [email protected]

  • 📍 Calculate script integrity hash when updating pre-constructed tx
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

  • 📍 Write e2e scenario using balance+submit on transaction containing Plutus script(s).

  • 📍 Rework tests using pre-constructed Shelley transactions

    • Avoid hard-coding names in the test file, but instead, list files in the test directory.
    • Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
    • Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx
  • 📍 replace plutus pre-generated transactions with newly generated, cbor-only binaries.

  • 📍 Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.

  • 📍 Cleanup balance endpoint and reduce noise.
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

  • 📍 Wire collateral requirements into balance endpoint handler

  • 📍 Add feePadding to TransactionCtx, used by calcMinimumCost

  • 📍 Add fee padding to transaction context for balancing
    Co-authored-by: Johannes Lund [email protected]

  • 📍 Fix ordering of argument for 'subtract' currently causing underflow.

  • 📍 Rework balance transaction request body to enable passing redeemers.
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.

Comments

To be done in a next PR:

  • Calculate the actual execution cost for all redeemers after balancing (using evaluateTransactionExecutionUnits from the cardano-api, or its equivalent from the cardano-ledger-specs).

  • Replace the execution units of each redeemers with their correspond value.

  • Adjust the change output's value accordingly.

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.

Issue Number

ADP-1183

@KtorZ KtorZ requested review from Anviking and paweljakubas October 6, 2021 15:48
@KtorZ KtorZ self-assigned this Oct 6, 2021
@@ -199,25 +201,26 @@ data TransactionLayer k tx = TransactionLayer

, updateTx
:: tx
-> ExtraTxBodyContent
-> TxUpdate
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, TxUpdate is definitely better name 😅

{ extraInputs :: [TxIn]
, extraCollateral :: [TxIn]
-- ^ Only used in the Alonzo era and later. Will be silently ignored in
-- previous eras.
, extraOutputs :: [TxOut]
, newExUnits :: ScriptWitnessIndex -> ExecutionUnits -> ExecutionUnits
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

where
modifyRedeemers :: Cardano.TxBodyScriptData era -> Cardano.TxBodyScriptData era
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe it is absolutely obvious modifyRedeemers is correct, but feel some property test showing the case would not be harmful;-)

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@paweljakubas paweljakubas left a comment

Choose a reason for hiding this comment

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

LGTM! Big shout for the comments in Cardano.Server module! What about adding property test that starts with some SealedTx makes updating of redeemer execution units and as a check we lookup redeemers and see if the execution cost were really properly updated? Redundant or worth having?

Also as now we have TxUpdate we need to change accordingly here:

  1. https://github.com/input-output-hk/cardano-wallet/blob/master/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs#L1654
  2. https://github.com/input-output-hk/cardano-wallet/blob/master/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs#L1728

Copy link
Member

@Anviking Anviking left a comment

Choose a reason for hiding this comment

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

Sounds sane! Will have another look tomorrow with fresh eyes, but feel free to merge before that

-- transaction considering only the maximum cost, and only after, try to
-- adjust the change and ExUnits of each redeemer to something more
-- sensible than the max execution cost.
let maxCost = maxScriptExecutionCost tl pp sealedTxIncoming
Copy link
Member

Choose a reason for hiding this comment

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

It just occurred to me: actualCost <= maxCost only holds if pp is the protocol parameters active when the tx is accepted, i.e. if pp and the protocol parameter hash match.

Not sure if we, or the client will set the protocol parameter hash, but we should make sure it always matches with pp.

Copy link
Member Author

Choose a reason for hiding this comment

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

The protocol parameter hash is only needed for validators who depends on it. I'd expect the PAB (or really, anyone constructing the transaction) to set it to what is expected.

{ extraInputs :: [TxIn]
, extraCollateral :: [TxIn]
-- ^ Only used in the Alonzo era and later. Will be silently ignored in
-- previous eras.
, extraOutputs :: [TxOut]
, newExUnits :: ScriptWitnessIndex -> ExecutionUnits -> ExecutionUnits
-- ^ Adjust execution units on existing redeemers.
, newFee :: Coin -> Coin
Copy link
Member

Choose a reason for hiding this comment

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

I thought I went with modifyFee here, which would make more sense when it's a a -> a. If you feel like renaming to say modifyExUnits / modifyFee, feel free.

@paweljakubas
Copy link
Contributor

@KtorZ maybe it would be good also to have a check like this for max execution unit prices in network's integration test -> https://github.com/input-output-hk/cardano-wallet/blob/master/lib/core-integration/src/Test/Integration/Scenario/API/Shelley/Network.hs#L78

Copy link
Member

@Anviking Anviking left a comment

Choose a reason for hiding this comment

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

lgtm! (modulo some test would be nice)

-> Cardano.TxBody era
-> Either ErrUpdateSealedTx (Cardano.TxBody era)
modifyLedgerTxBody ebc (Cardano.ShelleyTxBody shelleyEra bod scripts scriptData aux val) =
Right $ Cardano.ShelleyTxBody shelleyEra (adjust ebc shelleyEra bod) scripts scriptData aux val
modifyLedgerTx ebc (Cardano.ShelleyTxBody shelleyEra bod scripts scriptData aux val) =
Copy link
Member

Choose a reason for hiding this comment

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

Re the name change… It still takes a TxBody 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

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

It does indeed, but that's because the cardano-api has made the choice of including script witnesses inside a type called TxBody 😬 ... which is actually not at all reflecting the TxBody. Script witnesses are, witnesses.

Copy link
Member Author

Choose a reason for hiding this comment

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

The function is actually called modifyLedgerTx but it's not a "ledger tx" (if reading this as a tx from the cardano-ledger-specs), it's a cardano-api's tx.

@KtorZ
Copy link
Member Author

KtorZ commented Oct 7, 2021

(modulo some test would be nice)

I am working on adding the full end-to-end tests. I thought there was already more tests for the balancing endpoint but I discovered that, not so much 😬 ..

@KtorZ
Copy link
Member Author

KtorZ commented Oct 7, 2021

@KtorZ maybe it would be good also to have a check like this for max execution unit prices in network's integration test -> https://github.com/input-output-hk/cardano-wallet/blob/master/lib/core-integration/src/Test/Integration/Scenario/API/Shelley/Network.hs#L78

Yes and.. not 😄 ... I haven't added the max execution units to the API yet because that's extra side-work which is really not related to this feature. So I would rather not do it now to not add needless noise.

@KtorZ KtorZ force-pushed the KtorZ/ADP-1183/balancing-execution-units branch from 58b790d to dfc8688 Compare October 7, 2021 18:40
KtorZ and others added 6 commits October 8, 2021 13:50
…g on redeemers' ex units.

  In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.
  Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.
  This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.
Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
  This is required for any transaction which includes scripts, redeemers or datums as witnesses.
@@ -0,0 +1,8 @@
{
Copy link
Member

Choose a reason for hiding this comment

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

Did you mean to have this in the lib/core-integration/test/ instead?

I couldn't run the ping-pong test without copying this from lib/shelley/test/data/plutus-integration to lib/core-integration/test/data/plutus-integration.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I moved it before pushing the PR, but didn't commit :|

KtorZ added 5 commits October 8, 2021 20:54
  - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx
  There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 10, 2021

Build failed:

@KtorZ
Copy link
Member Author

KtorZ commented Oct 10, 2021

bors r+

iohk-bors bot added a commit that referenced this pull request Oct 10, 2021
2952: ADP-1183 (Part 1): Balancing execution units  r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

- 📍 **Add tx max script execution units to ProtocolParameters**
  
- 📍 **Calculate max script execution cost of transactions instead of relying on redeemers' ex units.**
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

- 📍 **Allow changing ExUnits of redeemers on sealed tx**
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

- 📍 **Rework balance-tx to always use max execution units.**
    This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.

- 📍 **Fix typos in comments**
  Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
- 📍 **Calculate script integrity hash when updating pre-constructed tx**
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

- 📍 **Write e2e scenario using balance+submit on transaction containing Plutus script(s).**
  
- 📍 **Rework tests using pre-constructed Shelley transactions**
    - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx

- 📍 **replace plutus pre-generated transactions with newly generated, cbor-only binaries.**
  
- 📍 **Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.**
  
- 📍 **Cleanup balance endpoint and reduce noise.**
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

- 📍 **Wire collateral requirements into balance endpoint handler**
  
- 📍 **Add feePadding to TransactionCtx, used by calcMinimumCost**
  
- 📍 **Add fee padding to transaction context for balancing**
  Co-authored-by: Johannes Lund <[email protected]>

- 📍 **Fix ordering of argument for 'subtract' currently causing underflow.**
  
- 📍 **Rework balance transaction request body to enable passing redeemers.**
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.



### Comments

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

To be done in a next PR:

- Calculate the actual execution cost for all redeemers after balancing (using [evaluateTransactionExecutionUnits](https://input-output-hk.github.io/cardano-node/cardano-api/lib/Cardano-Api-Fees.html#v:evaluateTransactionExecutionUnits) from the `cardano-api`, or its equivalent from the `cardano-ledger-specs`).

- Replace the execution units of each redeemers with their correspond value. 

- Adjust the change output's value accordingly. 

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.  

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
Co-authored-by: Matthias Benkort <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
Co-authored-by: IOHK <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 10, 2021

Build failed:

@KtorZ
Copy link
Member Author

KtorZ commented Oct 10, 2021

bors retry

iohk-bors bot added a commit that referenced this pull request Oct 10, 2021
2952: ADP-1183 (Part 1): Balancing execution units  r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

- 📍 **Add tx max script execution units to ProtocolParameters**
  
- 📍 **Calculate max script execution cost of transactions instead of relying on redeemers' ex units.**
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

- 📍 **Allow changing ExUnits of redeemers on sealed tx**
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

- 📍 **Rework balance-tx to always use max execution units.**
    This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.

- 📍 **Fix typos in comments**
  Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
- 📍 **Calculate script integrity hash when updating pre-constructed tx**
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

- 📍 **Write e2e scenario using balance+submit on transaction containing Plutus script(s).**
  
- 📍 **Rework tests using pre-constructed Shelley transactions**
    - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx

- 📍 **replace plutus pre-generated transactions with newly generated, cbor-only binaries.**
  
- 📍 **Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.**
  
- 📍 **Cleanup balance endpoint and reduce noise.**
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

- 📍 **Wire collateral requirements into balance endpoint handler**
  
- 📍 **Add feePadding to TransactionCtx, used by calcMinimumCost**
  
- 📍 **Add fee padding to transaction context for balancing**
  Co-authored-by: Johannes Lund <[email protected]>

- 📍 **Fix ordering of argument for 'subtract' currently causing underflow.**
  
- 📍 **Rework balance transaction request body to enable passing redeemers.**
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.



### Comments

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

To be done in a next PR:

- Calculate the actual execution cost for all redeemers after balancing (using [evaluateTransactionExecutionUnits](https://input-output-hk.github.io/cardano-node/cardano-api/lib/Cardano-Api-Fees.html#v:evaluateTransactionExecutionUnits) from the `cardano-api`, or its equivalent from the `cardano-ledger-specs`).

- Replace the execution units of each redeemers with their correspond value. 

- Adjust the change output's value accordingly. 

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.  

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
Co-authored-by: Matthias Benkort <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
Co-authored-by: IOHK <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 10, 2021

Build failed:

edit (KtorZ): I don't get ☝️ , does the nix-scripts need something additional to figure out the existence of the test folder?

@KtorZ
Copy link
Member Author

KtorZ commented Oct 11, 2021

bors retry

iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2952: ADP-1183 (Part 1): Balancing execution units  r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

- 📍 **Add tx max script execution units to ProtocolParameters**
  
- 📍 **Calculate max script execution cost of transactions instead of relying on redeemers' ex units.**
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

- 📍 **Allow changing ExUnits of redeemers on sealed tx**
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

- 📍 **Rework balance-tx to always use max execution units.**
    This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.

- 📍 **Fix typos in comments**
  Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
- 📍 **Calculate script integrity hash when updating pre-constructed tx**
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

- 📍 **Write e2e scenario using balance+submit on transaction containing Plutus script(s).**
  
- 📍 **Rework tests using pre-constructed Shelley transactions**
    - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx

- 📍 **replace plutus pre-generated transactions with newly generated, cbor-only binaries.**
  
- 📍 **Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.**
  
- 📍 **Cleanup balance endpoint and reduce noise.**
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

- 📍 **Wire collateral requirements into balance endpoint handler**
  
- 📍 **Add feePadding to TransactionCtx, used by calcMinimumCost**
  
- 📍 **Add fee padding to transaction context for balancing**
  Co-authored-by: Johannes Lund <[email protected]>

- 📍 **Fix ordering of argument for 'subtract' currently causing underflow.**
  
- 📍 **Rework balance transaction request body to enable passing redeemers.**
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.



### Comments

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

To be done in a next PR:

- Calculate the actual execution cost for all redeemers after balancing (using [evaluateTransactionExecutionUnits](https://input-output-hk.github.io/cardano-node/cardano-api/lib/Cardano-Api-Fees.html#v:evaluateTransactionExecutionUnits) from the `cardano-api`, or its equivalent from the `cardano-ledger-specs`).

- Replace the execution units of each redeemers with their correspond value. 

- Adjust the change output's value accordingly. 

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.  

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
Co-authored-by: Matthias Benkort <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
Co-authored-by: IOHK <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 11, 2021

Canceled.

@KtorZ
Copy link
Member Author

KtorZ commented Oct 11, 2021

bors r+

iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2952: ADP-1183 (Part 1): Balancing execution units  r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

- 📍 **Add tx max script execution units to ProtocolParameters**
  
- 📍 **Calculate max script execution cost of transactions instead of relying on redeemers' ex units.**
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

- 📍 **Allow changing ExUnits of redeemers on sealed tx**
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

- 📍 **Rework balance-tx to always use max execution units.**
    This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.

- 📍 **Fix typos in comments**
  Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
- 📍 **Calculate script integrity hash when updating pre-constructed tx**
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

- 📍 **Write e2e scenario using balance+submit on transaction containing Plutus script(s).**
  
- 📍 **Rework tests using pre-constructed Shelley transactions**
    - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx

- 📍 **replace plutus pre-generated transactions with newly generated, cbor-only binaries.**
  
- 📍 **Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.**
  
- 📍 **Cleanup balance endpoint and reduce noise.**
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

- 📍 **Wire collateral requirements into balance endpoint handler**
  
- 📍 **Add feePadding to TransactionCtx, used by calcMinimumCost**
  
- 📍 **Add fee padding to transaction context for balancing**
  Co-authored-by: Johannes Lund <[email protected]>

- 📍 **Fix ordering of argument for 'subtract' currently causing underflow.**
  
- 📍 **Rework balance transaction request body to enable passing redeemers.**
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.



### Comments

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

To be done in a next PR:

- Calculate the actual execution cost for all redeemers after balancing (using [evaluateTransactionExecutionUnits](https://input-output-hk.github.io/cardano-node/cardano-api/lib/Cardano-Api-Fees.html#v:evaluateTransactionExecutionUnits) from the `cardano-api`, or its equivalent from the `cardano-ledger-specs`).

- Replace the execution units of each redeemers with their correspond value. 

- Adjust the change output's value accordingly. 

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.  

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
Co-authored-by: Matthias Benkort <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
Co-authored-by: IOHK <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 11, 2021

Build failed:

  For some misterious reason, this doesn't work under nix (reproducible) builds. *sigh*. So, trying this out in hope.
@KtorZ KtorZ force-pushed the KtorZ/ADP-1183/balancing-execution-units branch from e561c0f to edb6311 Compare October 11, 2021 10:29
@KtorZ
Copy link
Member Author

KtorZ commented Oct 11, 2021

bors r+

iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2952: ADP-1183 (Part 1): Balancing execution units  r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

- 📍 **Add tx max script execution units to ProtocolParameters**
  
- 📍 **Calculate max script execution cost of transactions instead of relying on redeemers' ex units.**
    In practice, we want to actually execute a script to set the right value for each redeemer. And not the other way around. So, unless the transaction is fully constructed, the ExUnits value on redeemers is bonkers.

- 📍 **Allow changing ExUnits of redeemers on sealed tx**
    Doing so, I've also renamed ExtraTxBodyContent -> TxUpdate since (a) it's not only about extra content, (b) it does not only concern the transaction body, but also witnesses now.

- 📍 **Rework balance-tx to always use max execution units.**
    This is because, we can't actually predict script execution cost
  before the full final transaction is constructed. So, as a first step,
  we use the biggest approximation we can use which is to always
  consider the max execution steps and memory. While this is NOT okay
  for production code, it is sufficient to kick off preliminary testing
  and integration work.

  The goal is to now, in further commits, adjust the ex units of each
  redeemers after balancing, changing the change output consequently.
  Note that this should not in practice change the cost of execution of
  a script, if it does, then we push back on this by arguing that the
  underlying script validator is bonkers. Developers ought not to do
  this.

- 📍 **Fix typos in comments**
  Co-authored-by: paweljakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
- 📍 **Calculate script integrity hash when updating pre-constructed tx**
    This is required for any transaction which includes scripts, redeemers or datums as witnesses.

- 📍 **Write e2e scenario using balance+submit on transaction containing Plutus script(s).**
  
- 📍 **Rework tests using pre-constructed Shelley transactions**
    - Avoid hard-coding names in the test file, but instead, list files in the test directory.
  - Use pre-constructed files for all tests, instead of having some inlined hex-binary in the test module.
  - Provide more coverage and fix tests actually wrong now that the script integrity hash changes on calls to updateSealedTx

- 📍 **replace plutus pre-generated transactions with newly generated, cbor-only binaries.**
  
- 📍 **Remove redundant (with integration scenarios) compatibility JSON golden spec for scripts.**
  
- 📍 **Cleanup balance endpoint and reduce noise.**
    There were a lot of things in this handler which were not necessary, as well as many intermediary names which would just add to the noise when reading it. In particular, there's no need to lookup the reward account of the wallet (and it's actually even wrong, because withdrawals may be completely external). Wanting to re-use existing functions is quite flawed in this context because many of the pre-conditions for those functions don't actually hold in the generic balance-tx handler.

- 📍 **Wire collateral requirements into balance endpoint handler**
  
- 📍 **Add feePadding to TransactionCtx, used by calcMinimumCost**
  
- 📍 **Add fee padding to transaction context for balancing**
  Co-authored-by: Johannes Lund <[email protected]>

- 📍 **Fix ordering of argument for 'subtract' currently causing underflow.**
  
- 📍 **Rework balance transaction request body to enable passing redeemers.**
    Because coin-selection will change the order of inputs, we can't construct transactions with redeemers already in place. Redeemers need to be constructed after the facts. Thus, we pass them explicitely in a form that is isomorphic to the ledger's (ScriptPurpose, Data). This way, it's easier to construct transactions once balanced.



### Comments

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

To be done in a next PR:

- Calculate the actual execution cost for all redeemers after balancing (using [evaluateTransactionExecutionUnits](https://input-output-hk.github.io/cardano-node/cardano-api/lib/Cardano-Api-Fees.html#v:evaluateTransactionExecutionUnits) from the `cardano-api`, or its equivalent from the `cardano-ledger-specs`).

- Replace the execution units of each redeemers with their correspond value. 

- Adjust the change output's value accordingly. 

It should actually not be necessary to re-run the selection at all if we indeed assume that changing the change output's value should not change the execution cost. If it does, then the local node will eventually reject the transaction, and that's none of our business.  

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
Co-authored-by: Matthias Benkort <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
Co-authored-by: IOHK <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 11, 2021

Build failed:

KtorZ and others added 2 commits October 11, 2021 13:11
  I am done with Nix. This tool is causing more problems than it gives any benefits.
@KtorZ KtorZ force-pushed the KtorZ/ADP-1183/balancing-execution-units branch from 45d239c to 8305b23 Compare October 11, 2021 11:11
@KtorZ
Copy link
Member Author

KtorZ commented Oct 11, 2021

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 11, 2021

Build succeeded:

@iohk-bors iohk-bors bot merged commit 63df46a into master Oct 11, 2021
@iohk-bors iohk-bors bot deleted the KtorZ/ADP-1183/balancing-execution-units branch October 11, 2021 11:54
WilliamKingNoel-Bot pushed a commit that referenced this pull request Oct 11, 2021
iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2964: Remove 'coin_selection' field from the balance API's response r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- 📍 **Remove 'coin_selection' field from the Balance API's response**
    (a) the implementation of this field was wrong, and getting it right is quite involved as it requires revising several parts of the core wallet. It is perhaps not desirable / out-of-scope for this endpoint actually.

  (b) the coin_selection result is only truly useful when constructing a transaction which is under control of the wallet. Balancing may be done on any arbitrary foreign transaction and as such, breaks several invariants of the wallet (only one withdrawal, only one delegation certificate at a time etc..).


### Comments

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

Based off [`KtorZ/ADP-1183/balancing-execution-units`](#2952)

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2964: Remove 'coin_selection' field from the balance API's response r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- 📍 **Remove 'coin_selection' field from the Balance API's response**
    (a) the implementation of this field was wrong, and getting it right is quite involved as it requires revising several parts of the core wallet. It is perhaps not desirable / out-of-scope for this endpoint actually.

  (b) the coin_selection result is only truly useful when constructing a transaction which is under control of the wallet. Balancing may be done on any arbitrary foreign transaction and as such, breaks several invariants of the wallet (only one withdrawal, only one delegation certificate at a time etc..).


### Comments

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

Based off [`KtorZ/ADP-1183/balancing-execution-units`](#2952)

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[email protected]>
iohk-bors bot added a commit that referenced this pull request Oct 11, 2021
2964: Remove 'coin_selection' field from the balance API's response r=KtorZ a=KtorZ

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- 📍 **Remove 'coin_selection' field from the Balance API's response**
    (a) the implementation of this field was wrong, and getting it right is quite involved as it requires revising several parts of the core wallet. It is perhaps not desirable / out-of-scope for this endpoint actually.

  (b) the coin_selection result is only truly useful when constructing a transaction which is under control of the wallet. Balancing may be done on any arbitrary foreign transaction and as such, breaks several invariants of the wallet (only one withdrawal, only one delegation certificate at a time etc..).


### Comments

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

Based off [`KtorZ/ADP-1183/balancing-execution-units`](#2952)

### Issue Number

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

ADP-1183


Co-authored-by: KtorZ <[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