cardano-serialization-lib icon indicating copy to clipboard operation
cardano-serialization-lib copied to clipboard

`hash_script_data` accidentally frees datums object

Open longngn opened this issue 1 year ago • 1 comments

How to reproduce:

import {
  hash_script_data,
  PlutusList,
  Redeemers,
  TxBuilderConstants,
} from "@emurgo/cardano-serialization-lib-nodejs";

let datums = PlutusList.new();
console.log(datums);
hash_script_data(
  Redeemers.new(),
  TxBuilderConstants.plutus_vasil_cost_models(),
  datums
);
console.log(datums);
console.log(datums.len());

Logs:

PlutusList { ptr: 1245192 }
PlutusList { ptr: 0 }
/home/long/code/test/node_modules/@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib.js:20244
    throw new Error(getStringFromWasm0(arg0, arg1));
          ^
Error: null pointer passed to rust
    at module.exports.__wbindgen_throw (/home/long/code/test/node_modules/@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib.js:20244:11)
    at wasm://wasm/0070f84e:wasm-function[6036]:0x1a2159
    at wasm://wasm/0070f84e:wasm-function[6034]:0x1a213f
    at wasm://wasm/0070f84e:wasm-function[5194]:0x199add
    at PlutusList.len (/home/long/code/test/node_modules/@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib.js:9282:24)
    at Object.<anonymous> (/home/long/code/test/main.ts:17:20)
    at Module._compile (node:internal/modules/cjs/loader:1126:14)
    at Module.m._compile (/home/long/.nvm/versions/node/v16.17.0/lib/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
    at Object.require.extensions.<computed> [as .ts] (/home/long/.nvm/versions/node/v16.17.0/lib/node_modules/ts-node/src/index.ts:1621:12)

longngn avatar Oct 19 '22 08:10 longngn

@longngn , yeah this is an unfortunately a "feature" of this API developed a long time ago. The datums parameter in that Rust function is of type Option<PlutusList> so it cannot be properly passed by reference and is getting passed by value, which consumes that value, by the Rust rules.

Since then we have already made it a rule to never have Option type in function arguments and are trying to solve it with alternative approaches, but this function still exists yet. It will be deprecated and replaced with a newer API in one of the next versions.

The best recommendation for using it is to clone the datum when you are passing it, e.g:

hash_script_data(
  Redeemers.new(),
  TxBuilderConstants.plutus_vasil_cost_models(),
  datums.clone(),
);

This will preserve the original reference.

Or if you are using the TransactionBuilder then it is recommended to use the .calc_script_data_hash function on the builder instead of calculating and setting the hash manually.

vsubhuman avatar Oct 19 '22 11:10 vsubhuman