cardano-foundation / cardano-rosetta

An implementation of Rosetta for Cardano
https://www.rosetta-api.org
Apache License 2.0
98 stars 50 forks source link

Wrong decoding used in temp file creation of construction/submit api #439

Closed mahdi13 closed 2 years ago

mahdi13 commented 2 years ago

Assuming I try to call the construction/submit API to submit a raw signed transaction. Something like :

{"network_identifier":{"blockchain":"cardano","network":"mainnet"},"signed_transaction":"83a400818258202f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f01018282581d61bb40f1a647bc88c1bd6b738db8eb66357d926474ea5ffd6baa76c9fb82192710a1581cb0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a7a249477569646f436f696e190906476e7574636f696e19271082581d61bb40f1a647bc88c1bd6b738db8eb66357d926474ea5ffd6baa76c9fb199c4002199c400300a100818258200000000000000000000000000000000000000000000000000000000000000000584000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6"}

I get this error everytime:

{"code":5006,"message":"Error when sending the transaction","retriable":true,"details":{"message":"Command failed: transaction submit  Error: /tmp/f5644e5b-148c-456f-aa1a-29473f3fb3e5 TextEnvelope aeson decode error: Error in $: invalid character at offset: 0"}}

When I tried to find out what is going on inside the controller of rosetta, I checked the temp file (For example in the previous request /tmp/f5644e5b-148c-456f-aa1a-29473f3fb3e5) and it was like:

{
        "type": "Tx AlonzoEra",
        "description": "",
        "cborHex": "[object Map]"
 }

Instead of

{
        "type": "Tx AlonzoEra",
        "description": "",
        "cborHex": "83a400818258202f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f01018282581d61bb40f1a647bc88c1bd6b738db8eb66357d926474ea5ffd6baa76c9fb82192710a1581cb0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a7a249477569646f436f696e190906476e7574636f696e19271082581d61bb40f1a647bc88c1bd6b738db8eb66357d926474ea5ffd6baa76c9fb199c4002199c400300a100818258200000000000000000000000000000000000000000000000000000000000000000584000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6"
 }

So it was reasonable that cardano-cli was not able to parse that.

A fast (an non-reliable) workaround to fix is urgency. was to change https://github.com/input-output-hk/cardano-rosetta/blob/5cd02e36581788a03eab76fa40e2a93a0e6141e0/cardano-rosetta-server/src/server/controllers/construction-controller.ts#L278 to

                    const signedTransaction = request.body.signed_transaction;

and it fixed it temporarily.

But I think there is something wrong. Am I doing the API call the wrong way or is it a bug or what?

Thanks

AlanVerbner commented 2 years ago

Hi @mahdi13,

Have you created the transaction payload using Rosetta construction API or you just crated it on your own and tried to send it using construction/submit?

mahdi13 commented 2 years ago

@AlanVerbner I created and signed it myself. So, is it the problem? If so, isn't there any way for submitting a raw signed transaction through rosetta API? Because it's the case for many people who create and sign their transaction offline, or somewhere else, thanks

AlanVerbner commented 2 years ago

@mahdi13 basically Rosetta (not just this implementation but in general) was not meant to be used as a raw transaction sender API without invoking the construction workflow. The main reason is it requires some extra-data to be added when sending the transactions due to it's offline operation nature which is appended on each request payload from previous calls (sorry I cannot find the source in the Rosetta spec or the forum atm).

That being said, I guess you have two options:

  1. Create the transaction using the construction workflow stated here
  2. Use the cardano-cli as this node does directly without using Rosetta (Which doesn't make sense as you are already building the tx) or consider using something like Ogmios or any other transaction submission API.
mahdi13 commented 2 years ago

@AlanVerbner Thanks for the great explanation. Now I understood the matter, and I found the description on your docs: https://github.com/input-output-hk/cardano-rosetta/blob/faf36526fcd0630f2c20e27f71f750356dbf6807/docs/rosetta-custom-definitions.md#encoded-transactions

As an urgent solution, for the ones who are really stuck, there is a dummy workaround, which is to add a mock payload as the second's parameter:

  1. Encode the "hex string" of the raw binary message to Cbor, drop the last byte
  2. Add 82 as it's prefix and 36a16a6f7065726174696f6e7380 as it's suffix
  3. You can now pass it to the /construction/submit API.

Again: It's a very bad, experimental, non-tested, non-secure, dangerous, traceable, this-version-only solution!!