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

Fix cli build command #2995

Merged
merged 1 commit into from
Aug 4, 2021
Merged

Fix cli build command #2995

merged 1 commit into from
Aug 4, 2021

Conversation

Jimbo4350
Copy link
Contributor

The build command was underestimating tx fees

cardano-api/src/Cardano/Api/Fees.hs Outdated Show resolved Hide resolved
cardano-api/src/Cardano/Api/Fees.hs Outdated Show resolved Hide resolved
txbody1 <- first TxBodyError $ -- TODO: impossible to fail now
makeTransactionBody txbodycontent1 {
txFee = TxFeeExplicit explicitTxFees 0
txFee = TxFeeExplicit explicitTxFees $ Lovelace (2^(32 :: Integer)),
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this is set so that the this field takes up the maximal bytes for size calculation, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, though I think this is a hack and we've not understood something. I thought we would only need a 4 byte integer, i.e. 2^32-1. Jordan's example was then off by 2 bytes, and switching from 2^32-1 to 2^32 is basically a hack to add in an extra 4 bytes.

The fee cannot possibly be that high, indeed in Jordan's example the fee would actually fit into a 2 byte integer (i.e. it's less than 2^16-1).

It'd be preferable to track down where the missing bytes are. It looks like in Jordan's example we're actually off by exactly 4 bytes, since the validation error was for a fee for 2 bytes (2 * 44), and the fee field was already overly generous by 2 bytes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also using 2^32 is a bit misleading. It'd be better to be more explicit that we're reserving 8 bytes by using 2^64-1

Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

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

The fact that we've had to set both fields to be 2^32 rather than 2^32-1 means we've got our accounting off by a few bytes. Using 8 byte integer fields here is a hack. We should figure out where we're out.

txFee = TxFeeExplicit explicitTxFees 0
txFee = TxFeeExplicit explicitTxFees $ Lovelace (2^(31 :: Integer)),
txOuts = TxOut changeaddr
(lovelaceToTxOutValue $ Lovelace (2^(31 :: Integer)))
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to reserve more space for the change address. it could potentially take up 8 bytes. reserving 4 bytes for the fee is great, though.

txbody1 <- first TxBodyError $ -- TODO: impossible to fail now
makeTransactionBody txbodycontent1 {
txFee = TxFeeExplicit explicitTxFees 0
txFee = TxFeeExplicit explicitTxFees $ Lovelace (2^(31 :: Integer) - 1),
Copy link
Contributor

@dcoutts dcoutts Aug 3, 2021

Choose a reason for hiding this comment

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

Should be (2^(32 :: Integer) - 1), i.e. 32 not 31

@Jimbo4350 Jimbo4350 force-pushed the jordan/fix-cli-build-cmd branch 2 times, most recently from 9e4da6b to d10dd95 Compare August 3, 2021 11:42
Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

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

Looking good. Just one problem I spot, that we regressed on the balance check while adding a min utxo check for the ordinary user-specified outputs.

Comment on lines 862 to 878
balanceCheck :: Lovelace -> Either TxBodyErrorAutoBalance ()
balanceCheck balance
Copy link
Contributor

Choose a reason for hiding this comment

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

This no longer checks that the balance is over the min utxo value. The check earlier

    mapM_ (`checkMinUTxOValue` pparams) $ txOuts txbodycontent1

does not cover the case of the balance, because the change output with the balance is not included in txbodycontent1.

I would keep the original check

    | balance < minUTxOValue = Left (TxBodyErrorAdaBalanceTooSmall balance)

I would also suggest splitting the error case into two because they are different errors with different causes, different solutions and should have different error messages. The TxBodyErrorAdaBalanceTooSmall should be for the case of the balance being too small.

We should have a separate error for the other user-specified outputs being too small, i.e. used by checkMinUTxOValue in

    mapM_ (`checkMinUTxOValue` pparams) $ txOuts txbodycontent1

@Jimbo4350 Jimbo4350 force-pushed the jordan/fix-cli-build-cmd branch 2 times, most recently from f0c8229 to 7a74ecc Compare August 3, 2021 13:16
Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

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

We're still misreporting the balance < min utxo issue.

Comment on lines 877 to 882
balanceCheck :: TxOutValue era -> Either TxBodyErrorAutoBalance ()
balanceCheck balance
| txOutValueToLovelace balance < 0 =
Left . TxBodyErrorAdaBalanceNegative $ txOutValueToLovelace balance
| otherwise =
checkMinUTxOValue (TxOut changeaddr balance TxOutDatumHashNone) pparams
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not a good idea to merge the balance < minUTxOValue check here into the general checkMinUTxOValue.

Note how the code now never uses the TxBodyErrorAdaBalanceTooSmall error constructor and so will report the wrong error message.

I actually don't see why we need to change the balanceCheck code at all. It does not need to be given the full TxOutValue. As far as I can see the Lovelace only was fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The minUTxO value is calculated differently depending on the era, which is why I put checkMinUTxOValue in balanceCheck.

@Jimbo4350 Jimbo4350 force-pushed the jordan/fix-cli-build-cmd branch 8 times, most recently from 063de69 to 1b5672b Compare August 4, 2021 09:53
Co-authored-by: Duncan Coutts <duncan@well-typed.com>
Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

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

So I still think the balanceCheck and checkMinUTxOValue is ugly and overly complicated, but I'm not going to block merging the PR over that now.

cardano-api/src/Cardano/Api/Fees.hs Show resolved Hide resolved
@Jimbo4350
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request Aug 4, 2021
2995: Fix cli build command r=Jimbo4350 a=Jimbo4350

The `build` command was underestimating tx fees

Co-authored-by: Jordan Millar <jordan.millar@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Aug 4, 2021

Build failed:

@Jimbo4350
Copy link
Contributor Author

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Aug 4, 2021

@iohk-bors iohk-bors bot merged commit cb11587 into master Aug 4, 2021
@iohk-bors iohk-bors bot deleted the jordan/fix-cli-build-cmd branch August 4, 2021 12:11
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