IntersectMBO / cardano-db-sync

A component that follows the Cardano chain and stores blocks and transactions in PostgreSQL
Apache License 2.0
293 stars 160 forks source link

PlutusV2 script cost doesn't match the one computed by `cardano-cli conway transaction build` #1825

Open mkoura opened 2 months ago

mkoura commented 2 months ago

OS Fedora 40

Versions The db-sync version (eg cardano-db-sync --version): 13.4.0.0 PostgreSQL version: 14.9

Build/Install Method The method you use to build or install cardano-db-sync: nix

Run method The method you used to run cardano-db-sync (eg Nix/Docker/systemd/none): shell script

Additional context

Problem Report I have a test where a PlutusV2 certificate script address is registered and delegated in a single tx. Therefore the same PlutusV2 script is used twice in the same tx. In the test, I check the cost reported by cardano-cli conway transaction build and compare it to data in db-sync. In Conway era, the cost for one use of the script differs from what cardano-cli is reporting.

Cost reported by cardano-cli conway transaction build:

[
    {
        "executionUnits": {
            "memory": 722058,
            "steps": 231636692
        },
        "lovelaceCost": 58364,
        "scriptHash": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d"
    },
    {
        "executionUnits": {
            "memory": 724530,
            "steps": 232782656
        },
        "lovelaceCost": 58590,
        "scriptHash": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d"
    }
]

Cost reported by db-sync:

SELECT redeemer.id, redeemer.tx_id, redeemer.unit_mem, redeemer.unit_steps, redeemer.fee, redeemer.purpose, redeemer.script_hash, redeemer_data.value FROM redeemer LEFT JOIN tx ON tx.id = redeemer.tx_id LEFT JOIN redeemer_data ON redeemer_data.id = redeemer.redeemer_data_id WHERE tx.hash = '\xe2dabf96c1b8c82601b284f574cb53d7296b41bcde7cd2b6e5eee7019abebc47';
 id | tx_id | unit_mem | unit_steps |  fee  | purpose |                        script_hash                         |    value
----+-------+----------+------------+-------+---------+------------------------------------------------------------+-------------
  9 |    23 |   724530 |  232782656 | 58590 | cert    | \x9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d | {"int": 42}
 10 |    23 |   724530 |  232782656 | 58590 | cert    | \x9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d | {"int": 42}
(2 rows)

It looks like db-sync is reporting the same cost for both usages of the same script. Is it possible that db-sync uses data type that allows just single record for each script hash?

There was a change in behavior in Conway vs Babbage: In Babbage, there is only a single cost when the same Plutus script is used multiple times. Also the script and redeemer is specified only once when building the Tx in Babbage, even if the script and redeemer is used multiple times in the Tx. In Conway, the script and redeemer needs to be specified for each use, even if the script is the same.

The transaction is built in Conway like this:

cardano-cli conway transaction build --certificate-file "test_delegate_deregister[reference_script-build-plutus_v2]_ci0_hcl_addr0_stake_reg.cert" --certificate-script-file cardano_node_tests/tests/data/plutus/v2/stake-script.plutus --certificate-redeemer-file cardano_node_tests/tests/data/plutus/42.redeemer --certificate-file "test_delegate_deregister[reference_script-build-plutus_v2]_ci0_hcl_addr0_stake_deleg.cert" --certificate-script-file cardano_node_tests/tests/data/plutus/v2/stake-script.plutus --certificate-redeemer-file cardano_node_tests/tests/data/plutus/42.redeemer --tx-in-collateral "bf5e9f38e6c967984ff911c502d4601bd4a4129cfc1a0b8a02483ddb4e522d06#0" --tx-in "bf5e9f38e6c967984ff911c502d4601bd4a4129cfc1a0b8a02483ddb4e522d06#3" --change-address addr_test1yr52d4pz2jjz6f5ephlglr627ljrrq99hua8jmllme7tn0yu36w607q78j5sfp0n96l0exqn0j9vyc9qw2sqcj40zsksgwdtn2 --witness-override 1 --out-file "test_delegate_deregister[reference_script-build-plutus_v2]_ci0_hcl_reg_deleg_tx.body" --testnet-magic 42

Files used for building the Tx: dbsync_reg_deleg_cost_issue.tar.gz

kderme commented 1 month ago

First step here can be to write a unit test to verify the bug. The fix can be combined with https://github.com/IntersectMBO/cardano-db-sync/issues/1746, which simplifies the code that pottentially has the bug.

sgillespie commented 2 weeks ago

@mkoura: Have you been able to reproduce this in Sanchonet?