-
Notifications
You must be signed in to change notification settings - Fork 217
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
Adjust fee estimation to account for minting and burning. #2741
Adjust fee estimation to account for minting and burning. #2741
Conversation
@@ -183,7 +197,7 @@ spec = do | |||
prop "roundtrip for Byron witnesses" prop_decodeSignedByronTxRoundtrip | |||
|
|||
estimateMaxInputsTests @ShelleyKey | |||
[(1,115),(5,106),(10,101),(20,85),(50,32)] | |||
[(1,114),(5,106),(10,101),(20,85),(50,32)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the expected number of inputs, because my change to the fee estimation caused this test to fail, but I'll admit I don't quite understand the test.
A small difference such as this in the expected result doesn't seem to be a cause for concern, but if anyone has more knowledge on this I'd love to hear it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that the max inputs should decrease if you have caused all fee estimations to increase.
I wonder why only the first test case needed adjustment though.
730347d
to
5517e3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work - tests look good.
I have some change requests, so please merge once they're done.
P.S. Squash commits together where it make sense
sizeOf_ValidityIntervalStart | ||
= sizeOf_UInt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About this one - is it for the validity interval of the transaction as a whole or, is it an interval which is part of a script?
Are the validity interval bounds optional? What about the size of the validity interval end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
This is the validity interval of the transaction as a whole, separate validity intervals exist for the scripts (see here).
-
Shelley and later eras support an upper bound on the validity range, this is known as the TTL, so it is already part of the fee estimation (https://github.com/input-output-hk/cardano-wallet/blob/5517e3f699aaeeb78fe3abd5bf7cc41042dc83fb/lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs#L866). Allegra and later eras support a lower bound on the validity range, and that's what I'm adding here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So both ends of the validity bound are present, just one end is aliased as "TTL".
-- multiasset<a> = { * policy_id => { * asset_name => a } } | ||
-- policy_id = scripthash | ||
-- asset_name = bytes .size (0..32) | ||
sizeOf_Mint AssetId{tokenName} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could sizeOf_Mint
and sizeOf_NativeAsset
be refactored and parameterised by the inner type?
Like how it's done in the shelley-ma.cddl
file with multiasset<a>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 5dbf25e.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- , ? 8 : uint ; validity interval start | ||
-- , ? 9 : mint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are things added in shelley-ma.
There is a link to the source shelley.cddl
file above.
Can we also add a link to shelley-ma.cddl
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks :) Addressed in b8cbd8a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -1107,6 +1178,11 @@ estimateTxSize skeleton = | |||
sizeOf_SmallArray = 1 | |||
sizeOf_Array = 3 | |||
|
|||
-- Small helper function for summing values. Given a list of values, get the sum | |||
-- of the values, after the given function has been applied to each value. | |||
sumVia :: (Foldable t, Num m) => (a -> m) -> t a -> m |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
-- ; Timelock validity intervals are half-open intervals [a, b). | ||
-- ; This field specifies the right (excluded) endpoint b. | ||
-- ] | ||
sizeOf_NativeScript = \case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to add this into the size estimation, because I think it would also be needed for spending from a multi-sig wallet.
-- A CBOR Int which is less than 23 in value fits on a single byte. Beyond, | ||
-- the first byte is used to encode the number of bytes necessary to encode | ||
-- the number, followed by the number itself. | ||
sizeOf_LargeInt = 9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to call this sizeOf_Int64
? Because that's the max size for minting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 51d5f93.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -183,7 +197,7 @@ spec = do | |||
prop "roundtrip for Byron witnesses" prop_decodeSignedByronTxRoundtrip | |||
|
|||
estimateMaxInputsTests @ShelleyKey | |||
[(1,115),(5,106),(10,101),(20,85),(50,32)] | |||
[(1,114),(5,106),(10,101),(20,85),(50,32)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that the max inputs should decrease if you have caused all fee estimations to increase.
I wonder why only the first test case needed adjustment though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making this PR!
My main question relates to burning: is support for burned assets included in this PR?
I've done an initial review. I still have a bit of work to do to understand the test suite additions. I'll have another look tomorrow morning!
@@ -714,6 +719,8 @@ data TxSkeleton = TxSkeleton | |||
, txInputCount :: !Int | |||
, txOutputs :: ![TxOut] | |||
, txChange :: ![Set AssetId] | |||
, txScripts :: [Script KeyHash] | |||
, txMintAssets :: [AssetId] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sevanspowell.
Does this field refer only to minted assets, or can it also contain burned assets?
If it only refers to minted assets, then will you need to add another field for burned assets?
If it also contains burned assets, then what happens if there are assets that are both minted and burned? (This is allowed by coin selection, but I'm not sure if it's planned to allow this in the API, so asking just in case!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is some somewhat confusing terminology here. cardano-node
just refers to the minting and burning field as "mint". So this refers to both minted and burned assets.
When constructing a transaction manually, mints look something like +3 deadbeef.aaaaaa
, whereas burns look something like -3 deadbeef.aaaaaa
. If an asset is both minted and burned, it will just be added twice to the txMintAssets
list. This is what we want because the Tx construction will do that same, add some data for the mint, add some data for the burn. From the perspective of tx size estimation, negative (burned) and positive (minted) quantities are no different, they are both represented with an int64
. We don't have to do any fancy logic here, mints and burns are both treated as (qty, policyId, assetName), as they will be in the final Tx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've improved the terminology and added a comment to explain the usage of the field: c0de116.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
numberOf_ScriptVkeyWitnesses | ||
= sumVia scriptRequiredKeySigs txScripts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
numberOf_ScriptVkeyWitnesses | |
= sumVia scriptRequiredKeySigs txScripts | |
numberOf_ScriptVkeyWitnesses | |
= sumVia scriptRequiredKeySigs txScripts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scriptRequiredKeySigs :: Num num => Script KeyHash -> num | ||
scriptRequiredKeySigs (RequireSignatureOf _) = 1 | ||
scriptRequiredKeySigs (RequireAllOf ss) = sumVia scriptRequiredKeySigs ss | ||
scriptRequiredKeySigs (RequireAnyOf ss) = sumVia scriptRequiredKeySigs ss | ||
scriptRequiredKeySigs (ActiveFromSlot _) = 0 | ||
scriptRequiredKeySigs (ActiveUntilSlot _) = 0 | ||
-- We don't know how many the user will sign with, so we just assume the worst case of "signs with all". | ||
scriptRequiredKeySigs (RequireSomeOf _ ss) = sumVia scriptRequiredKeySigs ss |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Request: follow the coding standards here (line length + avoid vertical alignment).
Suggestion: use LambdaCase
to resolve this:
scriptRequiredKeySigs :: Num num => Script KeyHash -> num
scriptRequiredKeySigs = \case
RequireSignatureOf _ ->
1
RequireAllOf ss ->
sumVia scriptRequiredKeySigs ss
RequireAnyOf ss ->
sumVia scriptRequiredKeySigs ss
ActiveFromSlot _ ->
0
ActiveUntilSlot _ ->
0
RequireSomeOf _ ss ->
-- We don't know how many the user will sign with, so we just assume
-- the worst case of "signs with all".
sumVia scriptRequiredKeySigs ss
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggestion makes a small function consume a quite unnecessary amount of vertical space. 😛
You could also keep it under 80 characters, and vertically compact too, just by renaming the ss
variable to s
, and/or by removing the column alignment on =
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easier to scroll down than sideways? :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sizeOf_ValidityIntervalStart | ||
= sizeOf_UInt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sizeOf_ValidityIntervalStart | |
= sizeOf_UInt | |
sizeOf_ValidityIntervalStart | |
= sizeOf_UInt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- multiasset<a> = { * policy_id => { * asset_name => a } } | ||
-- policy_id = scripthash | ||
-- asset_name = bytes .size (0..32) | ||
sizeOf_Mint AssetId{tokenName} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sevanspowell is there a sizeOf_Burn
function to accompany sizeOf_Mint
?
Or is it the intention to put everything into the same field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #2741 (comment)
& counterexample ("cost with: " <> show costWith) | ||
& counterexample ("cost without: " <> show costWithout) | ||
|
||
it "increasing mint increases tx size at least proportionate to asset names" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it "increasing mint increases tx size at least proportionate to asset names" | |
it "increasing mint increases tx size at least proportionally to asset names" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
(if null assets | ||
then property $ marginalCost == 0 | ||
else property $ marginalCost > 0 | ||
) & classify (null assets) "null minting assets" | ||
& counterexample ("marginal cost: " <> show marginalCost) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(if null assets | |
then property $ marginalCost == 0 | |
else property $ marginalCost > 0 | |
) & classify (null assets) "null minting assets" | |
& counterexample ("marginal cost: " <> show marginalCost) | |
(if null assets | |
then property $ marginalCost == 0 | |
else property $ marginalCost > 0 | |
) | |
& classify (null assets) "null minting assets" | |
& counterexample ("marginal cost: " <> show marginalCost) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
(if null scripts | ||
then property $ marginalCost == 0 | ||
else property $ marginalCost > 0 | ||
) & classify (null scripts) "null scripts" | ||
& counterexample ("marginal cost: " <> show marginalCost) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(if null scripts | |
then property $ marginalCost == 0 | |
else property $ marginalCost > 0 | |
) & classify (null scripts) "null scripts" | |
& counterexample ("marginal cost: " <> show marginalCost) | |
(if null scripts | |
then property $ marginalCost == 0 | |
else property $ marginalCost > 0 | |
) | |
& classify (null scripts) "null scripts" | |
& counterexample ("marginal cost: " <> show marginalCost) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
& counterexample ("asset names length: " | ||
<> show lengthAssetNames) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
& counterexample ("asset names length: " | |
<> show lengthAssetNames) | |
& counterexample | |
("asset names length: " <> show lengthAssetNames) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
& counterexample ("witness size: " | ||
<> show (numWitnesses * sizeWitness)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
& counterexample ("witness size: " | |
<> show (numWitnesses * sizeWitness)) | |
& counterexample | |
("witness size: " <> show (numWitnesses * sizeWitness)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sevanspowell
8517e91
to
3e589c5
Compare
bors r+ |
👎 Rejected by code reviews #expected (not flaky) |
-- ^ Assets that have been both minted and burned, or minted or burned | ||
-- multiple times, will appear multiple times in this list, once for each | ||
-- mint or burn. For example if the caller "mints 3" of asset id "A", and | ||
-- "burns 3" of asset id "A", "A" will appear twice in the list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this is a really nice and clear explanation. 👍🏻
RequireSignatureOf _ -> sizeOf_SmallUInt + sizeOf_Hash28 | ||
RequireAllOf ss -> sizeOf_SmallUInt + sizeOf_Array + sumVia sizeOf_NativeScript ss | ||
RequireAnyOf ss -> sizeOf_SmallUInt + sizeOf_Array + sumVia sizeOf_NativeScript ss | ||
RequireSomeOf _ ss -> sizeOf_SmallUInt + sizeOf_UInt + sizeOf_Array + sumVia sizeOf_NativeScript ss | ||
ActiveFromSlot _ -> sizeOf_SmallUInt + sizeOf_UInt | ||
ActiveUntilSlot _ -> sizeOf_SmallUInt + sizeOf_UInt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 73caf08.
Hi Sam, I think this commit may have been dropped, perhaps accidentally?
0848d02
to
f5788f5
Compare
bors r+ |
2741: Adjust fee estimation to account for minting and burning. r=jonathanknowles a=sevanspowell # Issue Number ADP-998 ADP-955 # Overview I've adjusted fee estimation to account for minted assets and scripts. And also added some tests to cover it. This PR is still a draft as I am not confident that the tests sufficiently assert the expected behaviour of fee estimation. I'm testing the estimation with more estimation, although I'm not sure how we typically test heuristics like this. Co-authored-by: Samuel Evans-Powell <[email protected]> Co-authored-by: Jonathan Knowles <[email protected]>
Build failed: Failure log: , totalFee = Quantity
{ getQuantity = 3121400 }
, balanceLeftover = ApiWalletMigrationBalance
{ ada = Quantity
{ getQuantity = 0 }
, assets = ApiT
{ getApiT = TokenMap
( fromList [] )
}
}
, balanceSelected = ApiWalletMigrationBalance
{ ada = Quantity
{ getQuantity = 10000100000000 }
, assets = ApiT
{ getApiT = TokenMap
( fromList [] )
}
}
}
)
)
expected: 3120400
but got: 3121400
To rerun use: --match "/API Specifications/SHELLEY_MIGRATIONS/SHELLEY_MIGRATE_02 - Can migrate a large wallet requiring more than one transaction./" It looks like the fee estimation has gone up for ordinary transactions, even those that don't require minting and burning. #expected |
bors r+ |
2741: Adjust fee estimation to account for minting and burning. r=jonathanknowles a=sevanspowell # Issue Number ADP-998 ADP-955 # Overview I've adjusted fee estimation to account for minted assets and scripts. And also added some tests to cover it. This PR is still a draft as I am not confident that the tests sufficiently assert the expected behaviour of fee estimation. I'm testing the estimation with more estimation, although I'm not sure how we typically test heuristics like this. Co-authored-by: Samuel Evans-Powell <[email protected]> Co-authored-by: Jonathan Knowles <[email protected]>
Build failed: Similar failures to previous bors run. For example, w.r.t. expected fees: expected: 1129000
but got: 1129500
To rerun use: --match "/API Specifications/NEW_SHELLEY_TRANSACTIONS/TRANS_NEW_CREATE_02 - Only metadata/" Again, it does look like the fee estimations for ordinary transactions have increased, even in contexts where there are no minted or burned tokens. #expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might need to make further changes to this PR.
According to the integration test failure log (example), it seems that the fee estimates for ordinary transactions have increased, even for those that don't involve minting or burning.
I'm not sure if this is intentional or not.
Perhaps we need to look at the estimateTxSize
function again, to see why estimates are increasing even when there are no minted or burned tokens.
OTOH, if this is intentional, then we'll probably need to adjust the expectations of the failing integration tests. This isn't necessarily a bad thing, as it gives us an opportunity to check (with a human pair of eyes) that the fees still remain reasonable.
Let me know if I can be of any assistance!
Yes, the base fee estimation will increase somewhat, due to the presence of the new "validity interval start" field. The size of the field is 5 bytes. I'm verifying now that this is the only cause for the increase in fees. EDIT: I've verified that the cardano-wallet integration test passes when the validity interval is commented out:
I think this verifies that the cause of the increase in fees is solely due to the presence of the new validity interval start, for which we'd expect an increase in fees. I'll modify the test expectations accordingly. |
I added |
7846243
to
1c3c5f9
Compare
- Update fee estimation function to provide fee estimates for minted/burned assets and for scripts. - Move Cardano.Wallet.Gen to cardano-wallet-core (with the other test modules) so it can be re-used across cardano-wallet-core and cardano-wallet tests. - Both "NativeAsset" and "Mint" are "multiasset"s from the perspective of the CDDL, refactor their size definitions to use a new "multiasset" size function. - The base estimate for the size of transactions has increased due to the presence of the "Tx is valid from this point forward" field (validity interval start). - Adjust the test fee expectations to match this.
1c3c5f9
to
f82d8c5
Compare
bors r+ |
👎 Rejected by code reviews #expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
bors r+ |
2741: Adjust fee estimation to account for minting and burning. r=sevanspowell a=sevanspowell # Issue Number ADP-998 ADP-955 # Overview This PR: - [x] adjusts fee estimation to account for minted assets and scripts. - [x] adds property and unit tests to cover changes to `estimateTxSize`. - [x] makes small adjustments to integration test expectations for transaction fees. Co-authored-by: Samuel Evans-Powell <[email protected]> Co-authored-by: Jonathan Knowles <[email protected]>
Build failed: Looks like there are still a couple of failing integration tests: Failures:
src/Test/Integration/Scenario/API/Shelley/StakePools.hs:850:19:
1) API Specifications, SHELLEY_STAKE_POOLS, STAKE_POOLS_JOIN_01x - Fee boundary values, STAKE_POOLS_JOIN_01x - I can join if I have just the right amount
expected: Status {statusCode = 202, statusMessage = "Accepted"}
but got: Status {statusCode = 403, statusMessage = "Forbidden"}
from the following response: Left (DecodeFailure "Error in $: parsing Cardano.Wallet.Api.Types.ApiTransaction(ApiTransaction) failed, key \"id\" not found: Response {responseStatus = Status {statusCode = 403, statusMessage = \"Forbidden\"}, responseVersion = HTTP/1.1, responseHeaders = [(\"Transfer-Encoding\",\"chunked\"),(\"Date\",\"Fri, 16 Jul 2021 03:40:18 GMT\"),(\"Server\",\"Warp/3.3.14\"),(\"Content-Type\",\"application/json;charset=utf-8\")], responseBody = \"{\\\"code\\\":\\\"cannot_cover_fee\\\",\\\"message\\\":\\\"I am unable to finalize the transaction, as there is not enough ada I can use to pay for fees, or to satisfy the minimum ada quantities of change outputs. I need about pretty 1.000500 ada to proceed; try increasing your wallet balance as such, or try sending a different, smaller payment.\\\"}\", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}")
While verifying value:
( Status
{ statusCode = 403
, statusMessage = "Forbidden"
}
, Left
( DecodeFailure "Error in $: parsing Cardano.Wallet.Api.Types.ApiTransaction(ApiTransaction) failed, key "id" not found: Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Transfer-Encoding","chunked"),("Date","Fri, 16 Jul 2021 03:40:18 GMT"),("Server","Warp/3.3.14"),("Content-Type","application/json;charset=utf-8")], responseBody = "{\"code\":\"cannot_cover_fee\",\"message\":\"I am unable to finalize the transaction, as there is not enough ada I can use to pay for fees, or to satisfy the minimum ada quantities of change outputs. I need about pretty 1.000500 ada to proceed; try increasing your wallet balance as such, or try sending a different, smaller payment.\"}", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}" )
)
To rerun use: --match "/API Specifications/SHELLEY_STAKE_POOLS/STAKE_POOLS_JOIN_01x - Fee boundary values/STAKE_POOLS_JOIN_01x - I can join if I have just the right amount/"
src/Test/Integration/Scenario/API/Shelley/StakePools.hs:938:19:
2) API Specifications, SHELLEY_STAKE_POOLS, STAKE_POOLS_QUIT_01x - Fee boundary values, STAKE_POOLS_QUIT_01x - I cannot quit if I have not enough to cover fees
expected: Status {statusCode = 202, statusMessage = "Accepted"}
but got: Status {statusCode = 403, statusMessage = "Forbidden"}
from the following response: Left (DecodeFailure "Error in $: parsing Cardano.Wallet.Api.Types.ApiTransaction(ApiTransaction) failed, key \"id\" not found: Response {responseStatus = Status {statusCode = 403, statusMessage = \"Forbidden\"}, responseVersion = HTTP/1.1, responseHeaders = [(\"Transfer-Encoding\",\"chunked\"),(\"Date\",\"Fri, 16 Jul 2021 03:40:58 GMT\"),(\"Server\",\"Warp/3.3.14\"),(\"Content-Type\",\"application/json;charset=utf-8\")], responseBody = \"{\\\"code\\\":\\\"cannot_cover_fee\\\",\\\"message\\\":\\\"I am unable to finalize the transaction, as there is not enough ada I can use to pay for fees, or to satisfy the minimum ada quantities of change outputs. I need about pretty 1.000500 ada to proceed; try increasing your wallet balance as such, or try sending a different, smaller payment.\\\"}\", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}")
While verifying value:
( Status
{ statusCode = 403
, statusMessage = "Forbidden"
}
, Left
( DecodeFailure "Error in $: parsing Cardano.Wallet.Api.Types.ApiTransaction(ApiTransaction) failed, key "id" not found: Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Transfer-Encoding","chunked"),("Date","Fri, 16 Jul 2021 03:40:58 GMT"),("Server","Warp/3.3.14"),("Content-Type","application/json;charset=utf-8")], responseBody = "{\"code\":\"cannot_cover_fee\",\"message\":\"I am unable to finalize the transaction, as there is not enough ada I can use to pay for fees, or to satisfy the minimum ada quantities of change outputs. I need about pretty 1.000500 ada to proceed; try increasing your wallet balance as such, or try sending a different, smaller payment.\"}", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}" )
)
To rerun use: --match "/API Specifications/SHELLEY_STAKE_POOLS/STAKE_POOLS_QUIT_01x - Fee boundary values/STAKE_POOLS_QUIT_01x - I cannot quit if I have not enough to cover fees/"
Randomized with seed 1727163690
Finished in 1025.0644 seconds, used 538.3794 seconds of CPU time
837 examples, 2 failures, 25 pending Error text:
#expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sevanspowell!
It looks as though these tests are still failing:
I can also reliably reproduce these failures locally, with:
stack build --fast --test cardano-wallet:test:integration --test-arguments '--match "STAKE_POOLS"'
From a quick look, these tests appear to probe the boundaries of fee calculations. So it's somewhat expected that these might fail if our fee calculations change.
Let me know if I can provide any assistance!
2762: Quieten `show` output for API types. r=rvl a=jonathanknowles # Issue Number None. (Produced while debugging test failures for #2741) # Overview Integration test failures occasionally produce very verbose output, similar to the following (an extract from a [multi-page error](https://hydra.iohk.io/build/6925587/nixlog/1)): ```hs , derivationPath = ApiT { getApiT = DerivationIndex { getDerivationIndex = 2147485500 } } :| [ ApiT { getApiT = DerivationIndex { getDerivationIndex = 2147485463 } } , ApiT { getApiT = DerivationIndex { getDerivationIndex = 2147483648 } } , ApiT { getApiT = DerivationIndex { getDerivationIndex = 0 } } , ApiT { getApiT = DerivationIndex { getDerivationIndex = 4 } } ] , amount = Quantity { getQuantity = 100000000000 } , assets = ApiT { getApiT = TokenMap ( fromList [] ) } ``` Most of the above output is **boilerplate**: the `getApiT` and `getDerivationIndex` deconstructor field names are not necessary to understand the output, as each of these types is just a wrapper type with exactly one field. We can remove this boilerplate by deriving our `Show` instances for newtypes via `Quiet`, which produces output similar to the following: ```hs , derivationPath = ApiT (DerivationIndex 2147485500) :| [ ApiT (DerivationIndex 2147485463) , ApiT (DerivationIndex 2147483648) , ApiT (DerivationIndex 0) , ApiT (DerivationIndex 4) ] , amount = Quantity 100000000000 , assets = ApiT (TokenMap (fromList [])) ``` Real log output, demonstrating the difference in verbosity: * [verbose.log](https://github.com/input-output-hk/cardano-wallet/files/6827653/verbose.log) `451 1451 23191 verbose.log` * [concise.log](https://github.com/input-output-hk/cardano-wallet/files/6827652/concise.log) `337 1027 16641 concise.log` Co-authored-by: Jonathan Knowles <[email protected]>
- We have increased the base tx size by 5 bytes with the inclusion of the validity interval start for a tx. Increase the magic constant in costOfJoining by 5 to match this. Note that increasing it by 4 causes the test to fail so I am confident this value is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻
bors r+ |
Build succeeded: |
Issue Number
ADP-998
ADP-955
Overview
This PR:
estimateTxSize
.