Skip to content

fix(evolution): scope reference UTxOs per transaction in batch signing (#483) - #644

Open
Kshot3000 wants to merge 1 commit into
IntersectMBO:mainfrom
Kshot3000:fix/batch-signing-scope-reference-utxos
Open

Kshot3000 wants to merge 1 commit into
IntersectMBO:mainfrom
Kshot3000:fix/batch-signing-scope-reference-utxos

Conversation

@Kshot3000

Copy link
Copy Markdown

Fixes #483.

The bug

signTxsWithAutoFetch collected the reference inputs of every transaction in the batch, fetched them into one combined referenceUtxos list, and passed that same list to each transaction's signing call. computeRequiredKeyHashesSync then derived native-script key hashes from those reference UTxOs regardless of which transaction they belonged to — so a native script referenced by one transaction caused an unrelated transaction in the batch to be signed. The single-transaction path (signWithAutoFetch) scopes reference UTxOs to that transaction's own inputs; the batch path did not.

The fix

Two layers, both in packages/evolution/src/sdk/client/internal/Signing.ts:

  1. Batch path — the combined fetch is kept (one provider round trip), but each transaction is now signed with only its own reference UTxOs, filtered by its referenceInputs, matching the single-transaction path.
  2. Signer — computeRequiredKeyHashesSync only counts a reference UTxO's native script when the transaction actually references that UTxO. This also closes the same hole for a direct signTx call handed an over-wide referenceUtxos context, instead of relying on every caller to scope the list.
const referenced = new Set(
  (params.tx.body.referenceInputs ?? []).map((ref) => `${TransactionHash.toHex(ref.transactionId)}#${ref.index}`)
)
for (const utxo of params.referenceUtxos) {
  if (!referenced.has(CoreUTxO.toOutRefString(utxo))) {
    continue
  }
  // …native-script key hashes as before
}

Tests

New file Signing.BatchReferenceUtxos.test.ts (5 tests), each run one at a time against main first:

  • batch [tx1, tx2] where only tx2 references a native script naming the wallet's payment key hash — on main, tx1's witness set wrongly contained the wallet's vkey witness (4eefc6f3…); after the fix it is empty and tx2's contains it. RED on main, GREEN after.
  • the same batch in reverse order — RED on main, GREEN after.
  • direct signTx with an over-wide referenceUtxos context for a transaction that does not reference the script UTxO — RED on main, GREEN after.
  • controls that pass on both sides: signTx signs for a reference UTxO the transaction does reference, and the single-transaction auto-fetch path signs for its own reference script.

Full suite: 1683 passed / 75 skipped / 0 failed (files 102 passed / 1 skipped of 103 — exactly main's 1678 baseline + 5 new). tsc --noEmit and eslint clean; the touched source file's prettier diff count is unchanged from main (10 = 10). A changeset is included (patch).


@Kshot9000 (https://x.com/kshot9000) · ADA donations: addr1q8hnl6vl5a6k3rw3n5g3jtte696zcl76kfatzv7gpswa9r0dj7fma6klq55y4ffm7tf0em09udnyhuk4ah92pl5x9jpqjae44v

cc @cardano-foundation @IntersectMBO — independent builder, not affiliated with the Cardano Foundation, IOG or Intersect.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Batch signing shares reference UTxOs across all transactions

1 participant