ValidityRange is not encoded into CBOR when Balancing Transactions
MartorSkull opened this issue · comments
Summary
This bug occurs when the PAB tries to encode a transaction, it “forgets” to insert the required fields to denote the ValidityRange. Then when the wallet receives this CBOR it can’t find the fields and so sets the Range to always. This means that any validator using this field to ensure the timing of a transaction will fail if a value different than always is expected.
Steps to reproduce the behavior
Using a validator with the following checks:
{-# INLINABLE mkContractValidator #-}
mkContractValidator
:: Parameter
-> MyContractDatum
-> MyContractRedeemer
-> ScriptContext
-> Bool
mkContractValidator _ _ _ ctx =
traceIfFalse
"This should only happen when not using the mustValidateIn Constraint"
(txRange /= always)
where
info :: TxInfo
info = scriptContextTxInfo ctx
txRange :: POSIXTimeRange
txRange = txInfoValidRange info
And building the transaction with the following constraint, where ct
is the current time:
Constraints.mustValidateIn (interval ct (ct+1500000))
Actual Result
The wallet returns the following error
[pab:Warning:263] [2022-03-07 17:08:01.38 UTC] WalletClientError "FailureResponse (Request {requestPath = (BaseUrl {baseUrlScheme = Http, baseUrlHost = \\"localhost\\", baseUrlPort = 8090, baseUrlPath = \\"\\"},\\"/v2/wallets/3b3bde62a1012e9e9ee0914af0b1ff10faef0ba8/transactions-balance\\"), requestQueryString = fromList [], requestBody = Just ((),application/json;charset=utf-8), requestAccept = fromList [application/json;charset=utf-8,application/json], requestHeaders = fromList []), requestHttpVersion = HTTP/1.1, requestMethod = \\"POST\\"} (Response {responseStatusCode = Status {statusCode = 400, statusMessage = \\"Bad Request\\"}, responseHeaders = fromList [(\\"Transfer-Encoding\\",\\"chunked\\"),(\\"Date\\",\\"Mon, 07 Mar 2022 17:08:01 GMT\\"),(\\"Server\\",\\"Warp/3.3.17\\"),(\\"Content-Type\\",\\"application/json;charset=utf-8\\")], responseHttpVersion = HTTP/1.1, responseBody = \\"{\\\\\\"message\\\\\\":\\\\\\"I was unable to assign execution units to one of your redeemers: spending(1st f3a23879); Its execution is failing with the following error: ValidationFailedV1 (CekError An error has occurred: User error: The provided Plutus code called 'error'.) [\\\\\\\\\\\\\\"This should only happen when not using the mustValidateIn Constraint\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"PT5\\\\\\\\\\\\\\"].\\\\\\",\\\\\\"code\\\\\\":\\\\\\"redeemer_script_failure\\\\\\"}\\"})"
Showing the error ["This should only happen when not using the mustValidateIn Constraint","PT5"]
which is traced in the on-chain validator shown above.
We found out this was a PAB issue, and not a wallet one, by capturing packets that the PAB sent to the wallet. Inside these packets we found the transaction CBOR, but after decoding it we couldn’t find the expected fields in the transaction_body
part of the CBOR (namely, the third and eighth fields, as described here).
Here is the transactions
part of the CBOR for the transaction generated and sent by the PAB:
[{0: [[a22bb475acd036f9af74f08de16203fdee13af90ff5f3f882de9a8d8c403c073,
0]],
1: [[709d5501676afa4dea1e0c8ae52a5763a6cbb56030387a8920d9451780,
2000000,
ed16b7c053ffb878113c84e81d79a5ecfe86be57fe30941dd05405a67c7bb180]],
2: 0,
13: [],
14: []},
{3: [590bd601000033233322233223322323233322232333222323333333322222222323332223233332222323233223233322232333222323233223322323233...],
4: [CBORTag(121, [CBORTag(121, [0])])],
5: [[0, 0, CBORTag(121, []), [0, 0]]]},
True,
None]
Expected Result
The wallet should receive the entire CBOR and run the validator using the correct ScriptContext with the ValidityRange set correctly.
Describe the approach you would take to fix this
No response
System info
This bug was tested in 2 different settings, namely Arch Linux (version: rolling) and Ubuntu (version: 21.10). In both cases, we used the following tags:
- plutus: 2721c59fd2302b75c4138456c29fd5b509e8340a
- plutus-apps: c330fc6
It seems that it's been solved in that fix. Thanks for helping us.