CardanoSolutions / ogmios

❇️ A WebSocket JSON/RPC bridge for Cardano
https://ogmios.dev
Mozilla Public License 2.0
304 stars 90 forks source link

Return normal JSON for transactions metadata #117

Closed zandeck closed 3 years ago

zandeck commented 3 years ago

Describe your idea, in simple words.

I have been working on a library in Rust to be able to parse all the request that Ogmios returns, and the last element I am having a bit of trouble is the metadata.

For example, on this response,

{"type":"jsonwsp/response","version":"1.0","servicename":"ogmios","methodname":"RequestNext","result":{"RollForward":{"block":{"mary":{"body":[{"id":"466b55b13a6e51beda5154b63311cebe05e2a9b5f5794dedd776c2c17f369f21","body":{"inputs":[{"txId":"bab1ceeb7da0307ff475e7a9983567002e4005a4b8a6f3e8d2aa1192dbcccfa5","index":0}],"outputs":[{"address":"addr1qyzc52977e0j2knv2zaxv2pclvw3j3ry64rhdhr6pzxrty3uynmsl5hj0eaaeqkqarmd8f25czf6zcj6g0e6lyut7h5qh9gttw","value":{"coins":1000000,"assets":{}}},{"address":"addr1qxtpyfuhsvsvwf7acvd2g8j5sxe66f77f8277hqecsxyxk3uynmsl5hj0eaaeqkqarmd8f25czf6zcj6g0e6lyut7h5q6zc8td","value":{"coins":26313347702,"assets":{}}}],"certificates":[],"withdrawals":{},"fee":179361,"validityInterval":{"invalidBefore":null,"invalidHereafter":23096339},"update":null,"mint":{"coins":0,"assets":{}}},"metadata":{"hash":"10e07663401943d7a823b8a05ac49cef32dc3bac46e18faa25d748be160245eb","body":{"blob":{"61284":{"map":[{"k":{"int":1},"v":{"bytes":"9fba74135205ead3e6371f5b8f2ba0750ed83d5126d72cc82aa9ef8da6dfbf2a"}},{"k":{"int":2},"v":{"bytes":"f56cd094c28588e391bf1d0b2493ab7a51d6e440321c735b03e341a408a1910a"}},{"k":{"int":3},"v":{"bytes":"01058a28bef65f255a6c50ba662838fb1d194464d54776dc7a088c35923c24f70fd2f27e7bdc82c0e8f6d3a554c093a1625a43f3af938bf5e8"}}]},"61285":{"map":[{"k":{"int":1},"v":{"bytes":"ba27131677979f5a2b5cfde3b7bddbd0f80afe57d4a1973ffe0747a373ea58176bbff67ca877a8b327a3cde254c81c1a1b47ec5d84f47308b748e7009d37d10a"}}]}},"scripts":[]}}},{"id":"0e478dd7cd22c2efef1944d75e80a5fc4a03e4d0d6e3f89090745023c511c065","body":{"inputs":[{"txId":"5f374dbbf6dc2f2cdce88611bfd2223ece4de4e42d5071714878a9fbc4268a10","index":0}],"outputs":[{"address":"addr1qxzme05whmewxnkc2264e8w96ghg9j7q8jml2akyshq3p4amqexym3gmklq3d7rwsfv95slufsk2mzdr7fhwtny3k8gqkzpmcr","value":{"coins":147824863,"assets":{}}}],"certificates":[{"stakeKeyRegistration":"bb064c4dc51bb7c116f86e82585a43fc4c2cad89a3f26ee5cc91b1d0"},{"stakeDelegation":{"delegator":"bb064c4dc51bb7c116f86e82585a43fc4c2cad89a3f26ee5cc91b1d0","delegatee":"pool1l37xvdpcl49kr3wscpjp9pr854g06nnjrlndtu3h7k6pvfapgap"}}],"withdrawals":{},"fee":175137,"validityInterval":{"invalidBefore":null,"invalidHereafter":23096342},"update":null,"mint":{"coins":0,"assets":{}}},"metadata":null}],"header":{"blockHeight":5407743,"slot":23089144,"prevHash":"340cbcb0aa6615b736629600495796970d294b4530b842f20f38f1fe5cffe29a","issuerVk":"f0924d0f7444c5d6c237d8bdda3df164e1e36815c41ed394d30716fd2d1e2a27","issuerVrf":"clVtfvyWRAwnL3/0LKzBnu5Z6264d329rE3ikyNtmNI=","blockSize":961,"blockHash":"3b7877c2d1ae2d5e7ae34d51a13db24e4b1648d45f30a95cd6f5cf88739694ce"},"headerHash":"b68289c4a240a86aa20b0ed755b91911a7a0f675ef1b7fa60256318147be160c"}},"tip":{"slot":39606229,"hash":"47bb214a74f839901fe0e0e7411835cdef27d5c3e361b13534f8c51d89b7ec26","blockNo":6220761}}},"reflection":null}

The JSON returned for the meta data is enforcing indicating types, and is quite annoying to transform to a normal JSON.

:{"map":[{"k":{"int":1},"v":{"bytes":"9fba74135205ead3e6371f5b8f2ba0750ed83d5126d72cc82aa9ef8da6dfbf2a"}},{"k":{"int":2},"v":{"bytes":"f56cd094c28588e391bf1d0b2493ab7a51d6e440321c735b03e341a408a1910a"}},{"k":{"int":3},"v":{"bytes":"01058a28bef65f255a6c50ba662838fb1d194464d54776dc7a088c35923c24f70fd2f27e7bdc82c0e8f6d3a554c093a1625a43f3af938bf5e8"}}]}

Why is it a good idea?

That would be good if we could get a normal JSON straight from Ogmios, and not have to retransform it on the client side. I don't know if that's something the node returns directly, and if it has its place in Ogmios.

Are you willing to work on it yourself?

I have basic knowledge of Haskell, but I could give it a try.

KtorZ commented 3 years ago

Hey! Thanks for your feedback, I totally understand your point. However, there's a good reason this JSON schema to be written in this way and not as a "plain JSON". Behind the scene, metadata are serialized to binary when stored on the blockchain using a binary serialization format called CBOR which is very much inspired by JSON, but tailored to binary data.

While any JSON can be turned into CBOR, the converse isn't true: not any CBOR can be turned into "direct" JSON equivalent. For example, CBOR maps can have keys of any arbitrary type. For example, another CBOR map! Whereas in JSON, keys can only be strings. All-in-all, the CBOR format is more expressive than JSON, and thus we cannot guarantee that any on-chain metadata could be represented as plain JSON. Thus, the choice was made to use an intermediate representation for metadata, which describes the CBOR encoding in JSON. It is safer and work for any CBOR.

zandeck commented 3 years ago

Hey @KtorZ!

Thanks for the quick answer, it makes more sense in this case. I though that Ogmios was serving "normal" JSON.

Thanks for the great work!