Emurgo / cardano-serialization-lib

This is a library, written in Rust, for serialization & deserialization of data structures used in Cardano's Haskell implementation of Alonzo along with useful utility functions.
Other
231 stars 125 forks source link

Unchanged redeemer index when using `add_inputs_from` #592

Closed will-break-it closed 1 year ago

will-break-it commented 1 year ago

Hi, I am spending a script Utxo with a native asset and use the TransactionInputBuilder type. The goal is to return the native asset from the contract back to the user's wallet. The problem I am facing which I believe might be a bug or invalid way of using the Builder APIs from my end is the following:

After adding the contract utxo as transaction input, I later call add_inputs_from on the TransactionBuilder type in order to add a respective amount of lovelace to pay for fees and prepare for balancing. This call sometimes seems to change the order of the transaction inputs (most likely because alphanumeric sorting of transaction inputs by txid). In that case, the redeemer index I originally set for my contract transaction input won't match with the now reordered transaction inputs which leads to a PPViewHashesDontMatch error.

The TransactionBuilder type also does not allow me to inspect the current order of inputs once I've called add_inputs_from. Therefore, it becomes very cumbersome to get the redeemer index correct.

Am I building the transaction in the wrong way or is this a bug of TransactionBuilder#add_inputs_from function which should mutate the redeemer index in this case?

lisicky commented 1 year ago

Hi @will991 ! How did you add a contract utxo ?

will-break-it commented 1 year ago

Hi @lisicky , I am using an instance of TransactionBuilder and add inputs via a TxInputsBuilder where I added the contract utxo like below:

const txBuilder = Transaction.init(pp); // returns TransactionBuilder initialized with protocol params
const scriptInputs = TxInputsBuilder.new();
//...
const spendingScriptRefTxIn = TransactionInput.new(
    TransactionHash.from_bytes(Buffer.from(scriptRefTxId, 'hex')),
    parseInt(scriptRefTxIdx)
);
const plutusWitness = PlutusWitness.new_with_ref_without_datum(
    spendingScriptRef,
    redeemer
);
const contractTxInHex = Utxo.transactionInput(contractUtxo); // returns hex buffer of TransactionInput instance
scriptInputs.add_plutus_script_input(
     plutusWitness,
     TransactionInput.from_hex(contractTxInHex),
     Value.from_hex(Utxo.value(contractUtxo))
);
txBuilder.set_inputs(scriptInputs);
// ... adding tx outputs, collateral, cost model, and eventually:
txBuilder.add_inputs_from(inputs, 3); // I'd expect the method to adjust redeemer indices in case added wallet utxos change the order of previously added tx ins
// ... adding change/ balancing
lisicky commented 1 year ago

@will991 Do you call calc_script_data_hash after all changes in the tx builder and before add_change_if_needed ? You need to call calc_script_data_hash because it sets script_data_hash field in tx body. Also could you share cbor of tx ?

lisicky commented 1 year ago

Hey @will991 ! Do you still have the issue ?