Add `transaction validate` command (online phase 1 + phase 2)
Maintainers usually reply within 1 day
Assessment
This issue has not been assessed yet.
Description
Context
Follow-up from investigation in #1367. This issue scopes the first implementation step: an online transaction validate command that runs phase 1 (ledger rules via applyTx) and phase 2 (Plutus scripts via evaluateTransactionExecutionUnits) against the current ledger state, without submitting the transaction.
Scope
- New command:
cardano-cli latest transaction validate --tx-file signed.tx --socket-path node.socket - Phase 1 and phase 2 run independently — user sees all errors even if phase 1 fails
- Online only (requires node connection)
- Text output for now (structured JSON is a follow-up)
Key design decisions
Getting Globals for applyTx
constructGlobals needs ShelleyGenesis + EpochInfo. The existing QueryGenesisParameters returns GenesisParameters which contains all the fields needed for Globals.
We need to add a mkGlobalsFromGenesisParameters :: GenesisParameters era -> EpochInfo (Either Text) -> Globals function in cardano-api that constructs Globals from these fields (with minor type conversions: Int → Word64, Rational → ActiveSlotCoeff, Coin → Word64) and calls computeStabilityWindow/computeRandomnessStabilisationWindow for the derived fields.
Getting the ledger state for applyTx
mkMempoolEnv and mkMempoolState both only access nesEs (the EpochState inside NewEpochState). So we don't necessarily need the full NewEpochState.
Provisional approach: Use QueryCurrentEpochState — returns EpochState directly. Construct MempoolEnv/MempoolState from it manually (mirroring what mkMempoolEnv/mkMempoolState do, but skipping the NewEpochState unwrap). This is lighter than QueryDebugLedgerState.
Problem: On mainnet, transferring the full EpochState over the socket and deserializing it is slow.
Potential solution: Run applyTx inside the node — add a new query (or a validate-only variant of the LocalTxSubmission mini-protocol) in ouroboros-consensus / cardano-node that takes a Tx, runs applyTx server-side against the in-memory ledger state, and returns Either ApplyTxError () without adding the tx to the mempool. This avoids transferring state entirely, gives the same performance as submit, and guarantees state consistency. Requires changes in ouroboros-consensus, ouroboros-network, cardano-node, cardano-api, but each change is small and well-defined.
Independent phase 1 + phase 2
Phase 2 (evaluateTransactionExecutionUnits) already exists and works standalone. We run it alongside phase 1 and merge results. Phase 2 gives richer script errors (per-script traces, execution units) than applyTx's ValidationTagMismatch (PlutusFailure Text ByteString).
Output format
# Both pass:
Transaction is valid.
Phase 1: passed
Phase 2: passed (3 scripts evaluated)
SpendingScript 0: passed (mem: 234000, steps: 89000000)
MintingScript 0: passed (mem: 120000, steps: 45000000)
SpendingScript 1: passed (mem: 180000, steps: 67000000)
# Phase 1 fails, phase 2 passes:
Transaction validation failed.
Phase 1: FAILED
FeeTooSmallUTxO: minimum fee is 300000 lovelace, transaction specifies 170000
Phase 2: passed (1 script evaluated)
SpendingScript 0: passed (mem: 234000, steps: 89000000)
# Both fail:
Transaction validation failed.
Phase 1: FAILED
ValueNotConservedUTxO: consumed 5000000, produced 6000000
Phase 2: FAILED
SpendingScript 0: FAILED
ScriptErrorEvaluationFailed: ...
Known limitations
- No offline mode: This is online-only. Offline validation is a follow-up (see #1367).
- Text output only: Structured JSON output is a follow-up.
- No hints: cquisitor-style advisory warnings are a follow-up.
- Dominant language
- Haskell
- Stars
- 72
- Forks
- 25
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 8
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from IntersectMBO/cardano-cli
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
IntersectMBO/cardano-cli#1306 · 2 comments ·
Maintainers usually reply within 1 day
-
Ensure Plutus V4 scripts can be deserialised by cardano-cliPossibly taken @carbolymer claimed this 19 days ago. Openenhancement
IntersectMBO/cardano-cli#1448 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
Upstream non-Leios commits from the Leios integration branch to masterMay be free again @palas claimed this 61 days ago, and no pull request is open. Openrefactor
IntersectMBO/cardano-cli#1414 · 1 assignee ·
Maintainers usually reply within 1 day
-
Investigate incorporating cquisitor-style local tx validation (phase 1 + phase 2) into cardano-cliMay be free again @palas claimed this 168 days ago, and no pull request is open. Open
IntersectMBO/cardano-cli#1367 · 6 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
build-raw does not compute script_data_hash when using reference scriptsMay be free again A pull request for this issue was closed without being merged. OpenStale
Difficulty 4/5 3-5 days Newbie friendliness 45/100
IntersectMBO/cardano-cli#1363 · 1 comment ·
Maintainers usually reply within 1 day
All issues in IntersectMBO/cardano-cli
Similar issues
-
enhancement
Difficulty 1/5 Under an hour Newbie friendliness 82/100
alunduil/siren-json.hs#247 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 1/5 Under an hour Newbie friendliness 85/100
alunduil/network-arbitrary#196 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 1/5 Under an hour Newbie friendliness 82/100
alunduil/collection-json.hs#402 ·
Maintainers usually reply within 1 day
-
`--margin` still counts code points when it measures the last line of a call in `Margin.hs`Possibly taken @sherenkov claimed this today. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
objectionary/phino#1871 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 6 days