test: clarify M1-F-D-defer status + add LIVECBOR_DEBUG env

While checking whether last night's localUPLCEval: false fix unblocks
the 5 tx-submit-live tests skipped under TODO(M1-F-D-defer), found
that those tests still crash — but at a DIFFERENT spot than before.

Original UPLC issue (now fixed in production via 7ea7328 + fd24598):
- lucid's CML WASM UPLC interpreter falsely rejected our Plutus V3
  Submit/Claim/Accept txs. End-to-end chat + TTS lifecycle now works
  on Vector testnet by routing eval to Ogmios.

New / remaining test-side issue:
- Even with a proper evaluateTransaction mock response, lucid's
  applyUPLCEvalProvider → CML TransactionBuilder.set_exunits still
  panics with wasm "unreachable" inside the test fixture. The
  production path doesn't hit this (real Ogmios + real wallet UTxOs).
  Whatever the test-mock + CML interaction trips, it's separate from
  the original UPLC bug.

Refinements landed
- liveCbor.ts: opt-in LIVECBOR_DEBUG=1 env that prints the full inner
  err + WASM stack from rethrowAsTxError, so the next investigation
  doesn't need to re-add this scaffolding.
- tx-submit-live.test.ts:
  - setupSubmitHappyPath() now mocks "evaluateTransaction" with a
    proper EvalRedeemer-shaped response (useful baseline for any
    future un-skip attempt; not enough on its own to make the tests
    pass).
  - The first skipped test's TODO comment updated to record what's
    fixed in production vs. what remains as a test-infra bug.

Test counts unchanged (3 pass, 5 still skipped); production path
still verified end-to-end on testnet. Task M1-F-D-defer stays pending
but the original UPLC-interpreter blocker is gone.
This commit is contained in:
jelisaveta-talbot
2026-05-11 09:09:49 +02:00
parent 1f1a7d5a59
commit 0b93aee1ec
2 changed files with 39 additions and 4 deletions

View File

@@ -180,9 +180,25 @@ function chainUtxoToLucidScriptInput(
} }
/** TxConstructionError wrapping arbitrary lucid failures, surfacing /** TxConstructionError wrapping arbitrary lucid failures, surfacing
* collateral mismatches with a stable substring so tests can assert. */ * collateral mismatches with a stable substring so tests can assert.
*
* Set LIVECBOR_DEBUG=1 to see the full inner error + WASM stack — useful
* for diagnosing lucid 0.4.30 / CML edge cases (e.g. the set_exunits
* panic that affects test fixtures but not production). */
function rethrowAsTxError(err: unknown, fallback: string): never { function rethrowAsTxError(err: unknown, fallback: string): never {
const msg = err instanceof Error ? err.message : String(err); const msg = err instanceof Error ? err.message : String(err);
if (process.env.LIVECBOR_DEBUG) {
// eslint-disable-next-line no-console
console.error("[liveCbor] inner error:", err);
if (err instanceof Error && err.stack) {
// eslint-disable-next-line no-console
console.error("[liveCbor] stack:", err.stack);
}
if (err instanceof Error && "cause" in err) {
// eslint-disable-next-line no-console
console.error("[liveCbor] cause:", (err as Error & { cause?: unknown }).cause);
}
}
const lower = msg.toLowerCase(); const lower = msg.toLowerCase();
if ( if (
lower.includes("collateral") || lower.includes("collateral") ||

View File

@@ -85,6 +85,17 @@ function setupSubmitHappyPath(escrowDatumHex: string): void {
if (method === "queryNetwork/tip") { if (method === "queryNetwork/tip") {
return rpcOk({ slot: Math.floor((DELIVER_BY - 30_000) / 1000), id: "a".repeat(64) }); return rpcOk({ slot: Math.floor((DELIVER_BY - 30_000) / 1000), id: "a".repeat(64) });
} }
// localUPLCEval: false delegates exec-unit calc to Ogmios's
// evaluateTransaction. The provider has a fallback when this is missing
// but its synthesized budget can exceed lucid's bundled preset maxes
// → CML set_exunits WASM panic. Return conservative budgets that fit
// comfortably within PROTOCOL_PARAMETERS_DEFAULT's
// maxExecutionUnitsPerTransaction.
if (method === "evaluateTransaction") {
return rpcOk([
{ validator: { purpose: "spend", index: 0 }, budget: { memory: 100_000, cpu: 50_000_000 } },
]);
}
if (method === "submitTransaction") return rpcOk({ transaction: { id: "d".repeat(64) } }); if (method === "submitTransaction") return rpcOk({ transaction: { id: "d".repeat(64) } });
return rpcOk({}); return rpcOk({});
}); });
@@ -94,9 +105,17 @@ function setupSubmitHappyPath(escrowDatumHex: string): void {
describe("buildSubmitTx() [live] — CBOR shape", () => { describe("buildSubmitTx() [live] — CBOR shape", () => {
it.skip("returns real Cardano CBOR starting with 83 or 84", async () => { it.skip("returns real Cardano CBOR starting with 83 or 84", async () => {
// TODO(M1-F-D-defer): UPLC wasm crashes on this test's lucid cost-models setup. // TODO(M1-F-D-defer): the ORIGINAL UPLC-WASM crash (CML interpreting
// Production path uses real Ogmios cost models and works on testnet. // the Plutus V3 script ourselves) was fixed in production by passing
// Defer until we plumb usePresetProtocolParameters into the test-side LucidContext. // localUPLCEval: false to txBuilder.complete() — lucid now delegates
// eval to Ogmios. End-to-end chat + TTS lifecycle works on Vector
// testnet (commits 7ea7328 + fd24598). However this test still crashes
// at a DIFFERENT spot: lucid's applyUPLCEvalProvider → CML
// TransactionBuilder.set_exunits → wasm "unreachable" panic, even with
// a proper evaluateTransaction mock response. The test-side mock +
// CML interaction has its own bug separate from the production-path
// fix. Defer until we either (a) bisect the CML version or (b) rewrite
// these tests to assert at a layer above lucid's set_exunits.
const claimedUtxo = buildClaimedEscrowUtxo(); const claimedUtxo = buildClaimedEscrowUtxo();
setupSubmitHappyPath(claimedUtxo.datumHex!); setupSubmitHappyPath(claimedUtxo.datumHex!);
const chain = buildLiveChain(); const chain = buildLiveChain();