zw3rk's Cardano full node implementation in Java, built with LLM tools without ever looking at its source code.
Measured on pragma-org/node-diversity-conformance across all four functional and non-functional scenarios. Only 7 rows out of 20,536 do not pass — and every single one is a documented dataset or harness vocabulary artifact where Bean matches upstream Haskell cardano-ledger / plutus semantics.
9,198 / 9,200 Conway CDDL samples decoded, strictly re-encoded, and verified against reference bytes.
↓ cbor-decoding.json275 / 277 raw-CBOR transaction fixtures across Phase-1 and Phase-2 validation rules.
↓ ledger-rules.json1,056 / 1,059 evaluation vectors and 752 / 753 exact CPU/memory execution budgets.
↓ uplc-conformance.json10,000 / 10,000 mainnet scripts within the 1.5× CPU & memory ceiling on both bases.
| Implementation | Language | CBOR Decoding (9,200) | Ledger Rules (277) | UPLC Conformance (1,059) | UPLC Turbo (10,000) | Overall (Mean) |
|---|---|---|---|---|---|---|
| Bean (cardano-bean) | Java 25 | 99.98% (9,198) | 99.28% (275) | 99.72% (1,056) | 100.00% (10,000) | 99.74% |
| Amaru (suite preview / live) | Rust | 96.46% / 93.46% | 97.11% (269) / — | 99.91% (1,058) / — | 83.39% (8,339) / — | 94.21% / 23.36% |
| Dingo (live site) | Go | 98.35% (9,048) | 98.92% (274) | 98.77% (1,046) | 2.61% (261 / 500 run) | 74.66% |
| Cardano node (reference) | Haskell | 100.00% (9,200) | 41.16% (114)* | 100.00% (1,059) | 53.60% (5,360) | 73.69% |
as-shipped and current-thread bases
A benchmark passes uplc-turbo only when (cpu_us + flat_us) ≤ 1.5 × budget_cpu_us (or within 100 μs), mem_bytes ≤ 1.5 × budget_mem, and the consumed CPU/memory budgets agree with the cross-node majority vote. Bean achieves 0 CPU failures, 0 memory failures, and 0 budget outliers across all 10,000 scripts:
Why doesn't Bean score 100.00% everywhere? Because in 7 edge cases out of 20,536, the test vector's expected label differs from what a real Cardano node actually does on mainnet — and we refuse to hardcode test IDs or weaken production rules just to turn a badge green.
Cardano has two CBOR decoders in its Haskell codebase: the strict wire decoder used by real nodes on the network, and a looser test-library decoder. For legacy [metadata, scripts] pairs encoded as an indefinite-length CBOR array (0x9f ... 0xff), the real node's wire decoder accidentally checks for the closing 0xff byte before reading the elements — meaning any non-empty indefinite array is rejected on mainnet. The test dataset was generated using the looser test-library decoder.
auxiliary_data array encoded with indefinite length:9f {..metadata..} [..scripts..] ff
ff.
9fff (empty) when indefinite encoding is used in Conway.
Samples: auxiliary_data/valid/00003-a457defa17a4ecca and auxiliary_data/valid/00025-756519256dadb3b0. Upstream production wire decoder: Alonzo/TxAuxData.hs:218-251 and Coders.hs:482 (RecD reads the break byte before the fields below decoder version 12); dataset generator: app/LedgerRules.hs:99 (uses non-Annotator DecCBOR).
When a Plutus transaction sets its upper validity bound to slot 500,000 (beyond the known epoch-forecast horizon of 432,000), the node cannot convert that future slot into a wall-clock POSIX time for the Plutus script context. Both Bean and the Haskell node reject the transaction at the exact same step — they just call the error by its real ledger name (BadTranslation), whereas the test harness rewrites that error message to OutsideForecast.
0, forecast horizon ends at slot 432,000, and a PlutusV3 transaction sets ttl = 500,000.
OutsideForecast — because the reference test runner intercepts "TimeTranslationPastHorizon" in the output string and renames it.
BadTranslation — Phase-1 linearly extends the slot, and Phase-2 fails building TxInfo with BadTranslation(TimeTranslationPastHorizon).
Fixture: 00088. In cardano-ledger (Alonzo/Rules/Utxo.hs:379-397), Phase-1 validateOutsideForecast wraps EpochInfo in unsafeLinearExtendEpochInfo (Cardano/Slotting/EpochInfo/Extend.hs:54-66), so OutsideForecast never fires in Conway. Instead, Babbage/Rules/Utxos.hs:179-193 raises CollectErrors [BadTranslation (TimeTranslationPastHorizon ...)], which the test harness (Run.hs:443-445) string-matches and renames to OutsideForecast.
Cardano has two separate size rules for transaction outputs: one checks whether the token value exceeds 5,000 bytes (OutputTooBigUTxO), and another checks whether a legacy Byron address's attributes exceed 64 bytes (BootstrapAddrAttrsTooBig). This test sends just 2 ADA (5 bytes) to a Byron address with 99 bytes of attributes. Bean and the Haskell ledger report the specific Byron attribute error, while the test fixture expects the generic output-size error name.
2 ADA (5 bytes CBOR) to a legacy Byron bootstrap address with 99 bytes of address attributes (limit is 64 bytes).
OutputTooBigUTxO — because the suite's error vocabulary folds Byron attribute size into the general output-size bucket.
BootstrapAddrAttrsTooBig — the specific Shelley/Conway rule for Byron address attributes over 64 bytes.
Fixture: 00280. Upstream Alonzo.validateOutputTooBigUTxO (Alonzo/Rules/Utxo.hs:425-444) checks serSize (getValue txout) > maxValSize (5000) and does not fire on a 5-byte coin. Upstream Shelley.validateOutputBootAddrAttrsTooBig (Shelley/Rules/Utxo.hs:551-563) checks bootstrapAddressAttrsSize addr > 64 and fires OutputBootAddrAttrsTooBig (Conway UtxoPredicateFailure Sum 10).
dropList with a Count of ±264
In Plutus, the CPU cost of dropList(n, list) is proportional to |n|, and the CEK machine charges the builtin's CPU cost before executing it. When a script asks to drop 264 elements, the cost calculation saturates to 263 − 1 CPU units (~9.22 quintillion), which immediately blows past the 10-billion transaction CPU limit. Bean, the Haskell Plutus evaluator, and Amaru's evaluator all stop with Out of Budget — but the small test wrapper that recorded these two regression files mapped every error to the string "evaluation failure".
[(force (builtin dropList)) (con integer 18446744073709551616) [7, 8]]10,000,000,000 CPU ceiling.
evaluation failure — because the secondary conformance_extra.rs test macro only has one failure string for any Err(_).
out of budget — spending 9,223,372,036,854,775,807 CPU before running dropList exhausts the 10,000,000,000 limit.
Vectors: builtin_semantics_droplist_v3_count_beyond_u64_regression and builtin_semantics_droplist_v3_negative_count_beyond_u64_regression. Upstream Plutus 1.67.0.0: ExMemoryUsage.hs:306 (IntegerCostedLiterally narrows |±264| to maxBound :: SatInt = 263 - 1) and Cek/Internal.hs:1064-1065 (spendBudgets runs before the builtin denotation). Note that on the main corpus's identical huge-count tests (dropList-09/10/14/15/16), the suite itself expects out of budget.
verifySignature
On the blockchain, compiled Plutus scripts are binary ("flat" encoding) and refer to builtins by numeric ID (builtin #5). In human-readable text files, builtin #5 was originally called verifySignature in early Plutus drafts, and was renamed years ago to verifyEd25519Signature once ECDSA and Schnorr signatures were added. One regression text file still uses the old name, which the official Plutus text parser and Bean both reject as an unknown builtin name.
.uplc text file containing:(builtin verifySignature) instead of (builtin verifyEd25519Signature)
success — testing a custom parser alias that accepts the pre-1.0 name verifySignature in text mode.
parse error — upstream plutus-core's textual parser only accepts verifyEd25519Signature. (Binary on-chain scripts are unaffected.)
Vector: builtin_semantics_verifysignature_legacy_alias_test_vector_25_regression. On-chain flat-encoded scripts decode builtin tag 5 directly to VerifyEd25519Signature; only the textual UPLC parser checks the identifier string.
The published formal specification, CDDL wire grammars, and network genesis files.
Used as black-box differential oracles at every milestone and across full mainnet history.
LLM agents write the code; the human never reads it. Tests and diagnostics replace reading.
Decades of build tooling, testing and libraries, and a very large pool of engineers and agents who can work with the runtime.
Profilers, JDK Flight Recorder and heap analysis that work on a running node out of the box, without a special build.
Validates the whole chain from genesis, using off-heap LSM storage and ideas from Turbo Daedalus.
Mithril built directly into the node, as client and server: start from a certified snapshot in minutes.
Drop old chain history the node no longer needs and keep disk footprint small.
Bean-forged blocks stamp 67 as the protocol-version minor in the header, the same way Dingo stamps 69.