IntersectMBO / cardano-api

Cardano API
Apache License 2.0
22 stars 20 forks source link

[BUG] - Error when JSON encoding/decoding `TxOut` from preprod #612

Open koslambrou opened 1 month ago

koslambrou commented 1 month ago

Internal/External Internal

Summary

Probable bug on 9.1, and main.

We are indexing the JSON representation of TxOut in a database. However, the encoding/decoding fails for some TxOut that have inline datum inside it.

After JSON encoding a TxOut encountered in Preprod, we get the following error after trying to decode it:

'InAnyCardanoEra (TxOut CtxUTxO) deserialisation failed: "Error in $.txOut: Inline datum not equivalent to inline datum hash" : "{\"tag\":\"BabbageTxOut\",\"txOut\":{\"address\":\"addr_test1wrg7r82k7qmpgp0q5hr8ald7v80zk3zx8qw97fpuktmyyasgxswg7\",\"datum\":null,\"inlineDatum\":{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"int\":1},{\"map\":[{\"k\":{\"constructor\":0,\"fields\":[{\"constructor\":0,\"fields\":[{\"bytes\":\"01234567890123456789012345678901234567890123456789012345\"}]},{\"constructor\":1,\"fields\":[]}]},\"v\":{\"int\":0}}]},{\"int\":1},{\"int\":1},{\"int\":1},{\"map\":[{\"k\":{\"int\":1},\"v\":{\"constructor\":0,\"fields\":[{\"int\":1},{\"int\":1}]}},{\"k\":{\"int\":2},\"v\":{\"constructor\":0,\"fields\":[{\"int\":2},{\"int\":2}]}},{\"k\":{\"int\":3},\"v\":{\"constructor\":0,\"fields\":[{\"int\":3},{\"int\":3}]}},{\"k\":{\"int\":4},\"v\":{\"constructor\":0,\"fields\":[{\"int\":4},{\"int\":4}]}}]}]}]},\"inlineDatumhash\":\"05cd11e6ace746a6bee96d1606437479dc74c82e4f2926dcfe27d1c9f1237322\",\"referenceScript\":null,\"value\":{\"b0476f4ddd13688bd860ca1dde33a99294a2cbe70fea923db6f75193\":{\"7472656173757279\":1},\"lovelace\":2000000}}}"

Then, I inspected the CBOR representation of the inline datum before and after JSON serialization.

Before JSON serialization, for some txOut, doing:

show $ fmap C.serialiseToCBOR $ getTxOutDatumInline txOut

returned

"\216y\159\216y\159\SOH\161\216y\159\216y\159X\FS\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#E\255\216z\159\255\255\NUL\SOH\SOH\SOH\164\SOH\216y\159\SOH\SOH\255\STX\216y\159\STX\STX\255\ETX\216y\159\ETX\ETX\255\EOT\216y\159\EOT\EOT\255\255\255"

Then, doing:

show $ fmap (\dat -> either (error . show) C.serialiseToCBOR $ C.scriptDataFromJsonDetailedSchema (C.scriptDataToJsonDetailedSchema dat)) $ getTxOutDatumInline txOut)

returned

"\216y\159\216y\159\SOH\161\216y\159\216y\159X\FS\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#Eg\137\SOH#E\255\216z\128\255\NUL\SOH\SOH\SOH\164\SOH\216y\159\SOH\SOH\255\STX\216y\159\STX\STX\255\ETX\216y\159\ETX\ETX\255\EOT\216y\159\EOT\EOT\255\255\255"

In short, the returned CBOR representations are different. Seems like we lose information when serializing to JSON.

infrmtcs commented 4 weeks ago

Hi @koslambrou, thanks a lot for the reported issue and your PR fixing it. Our application code is also affected by this issue, specifically because we're still supporting some contracts using Plutus V1 with datum hash. Besides this, we noticed that fromAlonzoTxOut function in the same file is also setting TxOutDatumNone as datum for all cases: https://github.com/IntersectMBO/cardano-api/blob/cardano-api-9.2.0.0/cardano-api/internal/Cardano/Api/Tx/Body.hs#L2002-L2015 Would you please take a look and see if it's related to this issue? Thanks!

koslambrou commented 3 weeks ago

@infrmtcs This issue is not related to the PR you mentioned, it is a different problem.

Also, thanks for pointing out the fromAlonzoTxOut function. I updated the PR to include a fix for this.