Skip to main content

Performance & Tracing Update

· 7 min read
Michael Karg
Performance and Tracing Team Lead

High level summary​

  • Benchmarking: Van Rossem HF: Created and performed benchmarks for new Plutus execution budgets and internals; PlutusV3 baseline shift.
  • Development: Hermod package restructre completed; cardano-config support in trace-dispatcher.
  • Infrastructure: Genesis cache overhaul / Protocol Version 11 overlay have landed.
  • Tracing: Alert manager feature for cardano-tracer in design phase; native support for spans in Hermod.
  • Leios: Major new beacon feature to impose memory limits; on-disk LedgerDB tx validation times benchmark in the works.

Low level overview​

Benchmarking​

The P&T team has been safeguarding the now enacted Van Rossem hard fork, which brings Protocol Version 11 with new Plutus internals and a bump to the execution budgets to mainnet. Our benchmarking automation framework, the performance workbench, gained new chain-fragment-creation profiles as well as new plutuscall-* profiles, targeting those new Plutus features specifically (cardano-node PR#6627 and cardano-node PR#6440). The former PR also adds a wb chain-fragment export op, which packages a profile run's node database, genesis files and a path-patched node config into a chain fragment consumable by beacon tool — the tooling behind the on-disk benchmarks described under Leios below.

The benchmarks performed using those new profiles have shown that the execution budget raise leads to a reasonable, predictable and expected increase in Block Adoption times. For the new PlutusV3 internals, they've also shown that they're consistently priced relative to the existing internals, and that, even when executed up to full budget exhaustion, there were no performance regressions in their implementation.

To enable those benchmarks, work has been well underway on extending plutus-scripts-bench with PlutusV3 variants of the existing scripts, and adding two new PV11 scripts targeting the new execution internals: MultiScalarMulG1 (BLS12-381 multi-scalar multiplication based on CIP-0133), and ExpModInteger, exercising the new expModInteger builtin (cardano-node PR#6440). The PR wires these through to tx-generator, and gives our analysis tool locli a new PlutusBudgetSummary module to output Plutus workload calibration data as part of comparison reports. The PR is currently under review.

Development​

The long-planned restructuring of trace-dispatcher into separate Hermod packages, which we reported as underway last month, is now complete (hermod-tracing PR#16). The stable API surface — trace types, LogFormatting/MetaTrace instances, and the structural/annotation combinators — now lives in a lightweight hermod-tracing-api package, itself split into an internal and a public sublibrary, so that packages which only need to instrument their own code no longer pull in EKG, Prometheus, CBOR forwarding or the YAML config parser as dependencies. The full backend stack remains in hermod-tracing-core, while the Prometheus TCP server has been carved out into its own optional hermod-tracing-prometheus package. All modules and identifiers were renamed from Cardano.Logging.*/TraceDispatcherMessage and friends to their Hermod.Tracing.* equivalents, and trace-dispatcher itself has been kept around as a backward-compatible mirror so existing pinned consumers keep building unchanged until they migrate.

Last but not least, we've added compatibility with the cardano-config library to trace-dispatcher (hermod-tracing PR#18).

Infrastructure​

The genesis cache overhaul and full Protocol Version 11 overlay for our performance workbench, close to merging as of last month, have now landed (cardano-node PR#6544). Beyond the split-cache "ripper" backend and the restoration of non-default Plutus cost models via the Alonzo genesis extraConfig field reported previously, the merged PR also standardises genesis creation on cardano-cli's create-testnet-data (retiring the old create-staked path and the separate byron genesis step), makes the era an explicit, validated input to wb start and wb run allocate via a new --era-name flag, and simplifies the workbench CLI to named flags only. A handful of breaking changes ship alongside: WB_BACKEND is renamed to WB_BACKEND_NAME, --relays and the genesis "spec" sub-command are removed, and non-default Plutus cost models must now be supplied through extraConfig. Analysis of older runs is unaffected, as wb analyse falls back to the previous genesis layout when the new one is absent.

Tracing​

We've begun designing a central alarm system for cardano-tracer (alarm system concept). Today, operators typically rely on third-party tooling for this — something built on top of Grafana, the Prometheus Alertmanager, or Loki log analysis — but there's no solution native to the tracing and metrics stack, and none that takes a unified approach across trace messages and metrics. The idea is to instead give cardano-tracer a single place that collects alarms from multiple sources — our hermod-recon verifier flagging a violated property, a rule evaluated against the metrics cardano-tracer already stores, or simply a trace message severe enough to warrant attention — and forward them to wherever operators want to be notified — typically a paging service's webhook API, but custom webhooks, email, and plain logging are supported too — while keeping a queryable history of past alarms. It deliberately stays a one-shot notification layer rather than a full incident tracker: there's no acknowledgement or resolution workflow, that's left to whatever tooling operators already use for that. This is still an early design and not yet reflected in any implementation work.

On the Hermod side, we're also exploring native support for nested spans, in the spirit of tracing systems like OpenTelemetry. A span represents a bounded unit of work — say, processing a single transaction or forging a block — and the point is to let automated log analysis reconstruct not just individual events, but how long an operation took and how it decomposes into sub-operations, by pairing up an opening and a closing trace message that share a unique identifier. The tricky part is Haskell's laziness: without care, an expression's evaluation, and the trace events it triggers, can end up happening after its enclosing span has already been closed, so a fair amount of the design work goes into guaranteeing that no trace event ever escapes the span it logically belongs to. There's no branch to point to yet — this is still exploratory work.

Leios​

Building on the chain-fragment export tooling introduced above, beacon — the ledger ops benchmarking tool in ouroboros-consensus-tools — gained a memory-limiting feature aimed squarely at tx validation times using an on-disk LedgerDB backend and forcing disk I/O at the same time (beacon PR#12, currently under review).

A new flag forces the LSM (on-disk) backend to genuinely exercise disk I/O, rather than being served invisibly out of the OS page cache; --mem-limit/--heap-limit cgroup caps serve as a fallback for past db-analyser builds without support for that new flag. Every run now records peak RSS and block I/O counts. A representative "sweet spot" using those new mechanisms has been determined empirically for the chain fragments used in this year's April measurements. This finally gives us concrete on-disk LedgerDB metrics by determining the overhead of I/O-backed validation times vs. pure ones, closing a gap in our Leios throughput benchmarking. A new beacon/docs/METHODOLOGY.md documents the overall approach; benchmarks are currently being performed on our benchmarking cluster, to obtain measurements on the same hardware as we did in April for the in-memory backend — but now with LSM backend forced to perform disk I/O.

Mithril Team Update

· 2 min read
Jean-Philippe Raynaud
Mithril Tech Lead

High level overview​

This week, the Mithril team completed benchmarks for the IVC SNARK recursive circuit and analyzed and optimized the testing strategy for the STM SNARK modules. They also worked on encoding the aggregate signature of the certificate message as bytes, which significantly reduces the size of the certificates.

The team also continued implementing the aggregator CLI commands and the runbook for on-chain configuration parameters, and began creating a local IPFS network for a proof-of-concept distribution of Cardano database artifacts.

Finally, they completed the repository transfer to the IntersectMBO organization. They also continued working on shipping the Mithril signer node binary in the Cardano node bundle, preparing the 2630 distribution release, upgrading to Cardano node v.11.1, updating the DMQ node to 0.7.0.0, and upgrading the documentation website to Docusaurus 3.10.2 and tailwind v4.

Low level overview​

Features​

  • Completed the issue Add benchmarks for the IVC SNARK recursive circuit #3412
  • Completed the issue Analyze and optimize the testing strategy of the STM SNARK modules #3405
  • Worked on the issue Use bytes encoding for aggregate signature in certificate message #3379
  • Worked on the issue Implement aggregator CLI commands for configuration parameters #3392
  • Worked on the issue Create a local IPFS network #3434

Protocol maintenance​

  • Completed the issue Transfer repository to IntersectMBO organization #3276
  • Worked on the issue Ship Mithril signer node binary in Cardano node bundle in GitHub #3011
  • Worked on the issue Release 2630 distribution #3271
  • Worked on the issue Upgrade to Cardano 11.1 #3346
  • Worked on the issue Update DMQ node to 0.7.0.0 #3358
  • Worked on the issue Create runbook for on-chain configuration parameters #3399
  • Worked on the issue Update documentation website to docusaurus stable version 3.10.2 #3413
  • Worked on the issue Update documentation website to tailwind v4 #3414

Plutus Core Team Update

· 3 min read
Ziyang Liu
Software Engineering Lead

High level summary​

In the past weeks the Plutus team has added new built-in functions, improved Value support in the ledger API, broadened the conformance test suite, and continued working on Plutus V4 script context and Plutus V4 language features like casing on Data.

Two built-ins from recent CIPs have landed: multiIndexArray (CIP-0156), which reads several elements of an array in one call, and policies (CIP-0168), which returns the currency symbols in a Value. Both are gated behind a future protocol version and not yet costed, so they cannot be used on-chain until Dijkstra.

The conformance test suite now ships .flat files alongside the textual test cases, making it much easier to consume for implementations that do not parse the textual format. The asData pattern synonyms now use built-in list casing. The Value built-in type has been added to the metatheory as postulates, along with a fix to decEq that removed a normalization blowup consuming over 128GB of memory when checking certificates.

We've merged the Plutus V4 script context definition (though it is subject to change), and recently discussed its Data encoding during a Plutus Working Group meeting. You can find the meeting notes here. Implementers of alternative node clients, UPLC interpreters, and compilers targeting UPLC are encouraged to review the notes and contribute to the discussion.

Key Pull Requests Merged​

Notable Pull Requests In Progress​

Consensus Team Update

· 2 min read
Damian Nadales
Consensus Team Lead

High level summary​

  • Leios prototype and testnet (Treasury Funding Initiative 4: Ouroboros Leios Implementation):
    • Cut a new prototype release, prototype-2026w29, carrying this fortnight's work across the node and the Leios repository (#6621, #996).
    • Landed the change that lets the node certify and announce endorser blocks inside the forging loop, so it no longer misses chances to certify. This is expected to raise the certification rate and throughput (#2105).
    • Added CallTrace instrumentation to the Forge thread, making it easier to trace and profile block production in the prototype (#2126).
    • Taught the LeiosNotify mini protocol to accept but ignore the proper MsgLeiosBlockAnnouncement message, a step towards the full block-announcement flow (#2142, integrated into the node in #6624).
    • Enriched typed-protocols to give more precise back pressure for pipelined mini protocols, motivated by the new LeiosNotify protocol (#93).
    • Improved testnet stability by stopping the node from mangling some Dijkstra blocks, a quick workaround while a ledger issue is fixed (#2140, for cardano-ledger#5937).
    • Updated the prototype dashboards and added a graph of recent endorser-block events, making the testnet easier to observe (#990, #992).
  • Mempool design for Leios (Treasury Funding Initiative 4: Ouroboros Leios Implementation):
    • Wrote up Mempool design considerations for Leios (#997).
    • Took part in discussions on how the Mempool should work: its current requirements, a "high-throughput mempool", and a "tiered-pricing mempool" in which transactions that pay more can queue ahead of normal-paying ones when they do not conflict.
  • Storage and snapshots (Treasury Funding Initiative 10: LSM including UTXO-HD):
    • Set the node's default snapshot policy to match Mithril's snapshot policy, so the two stay aligned (#2149).
    • Added a new LSMExportPath configuration option, letting operators control where LSM data is exported (#6629).

Ledger Team Update

· 4 min read
Alexey Kuleshevich
Ledger Team Software Engineer

High level summary​

Leios support in the ledger continued to take shape this cycle. Building on the block body work from the previous updates, a Leios.BlockHeader was added along with an EraBlockHeader instance for Praos that consensus needs for its 11.1 integration, which together move the block header behind a common era-parametric abstraction. On the leios-prototype branch we also backported the addition of a LeiosKey (a BLS12381 public key together with a possession proof) to StakePoolParams and StakePoolState, with the Dijkstra CDDL updated to carry the Leios key as an optional field in the pool registration certificate.

A good deal of governance and rules work landed as well. Following the introduction of the ENTITIES rule in the previous cycle, we implemented CIP-181 by removing the DRep-delegation requirement for reward withdrawals, which dropped the corresponding predicate failures from the entities and sub-entities rules. On the Plutus cost model side we followed up on the earlier argument-ordering bug fix with a more permanent safeguard: a new CostModelsUpdate newtype now wraps the update argument so the old and new cost models can no longer be swapped by accident, and the symmetric Semigroup/Monoid instances for CostModels that made that mistake possible were removed. We also adjusted the consumed/produced interface and fixed getProducedValue for the Dijkstra era, added an AccountBalanceExact constructor to AccountBalanceInterval, and switched the minor protocol version to Word32. We also fixed NoThunks instances in the Alonzo and Conway genesis types.

Several changes continued the ongoing push toward more era-parametric, abstract interfaces. SnapShots was made era parametric, and ToJSON/FromJSON instances were added for EraTxAuxData, extending the JSON serialisation coverage started last cycle for scripts. On the Canonical Ledger State front, export and import modules were introduced for handling canonical state, giving a first pass at reading and writing it through the CLS interface. On the testing side the Conway conformance tests were updated to protocol version 11 and tests were added for the newly introduced top-level guard requirement.

On the tooling and infrastructure side, the hackage index-state was bumped to pick up the latest cuddle release, which now validates that CBOR maps contain no duplicate keys per RFC 8949 and required a couple of generators to be adjusted accordingly, and the usual GitHub Actions bumps were applied.

Low level summary​

Features​

  • PR-5905 - Introduce CostModelsUpdate
  • PR-5853 - Add ToJSON/FromJSON instances for EraTxAuxData
  • PR-5869 - Add export/import modules for canonical ledger state
  • PR-5915 - Add EraBlockHeader instance for Praos
  • PR-5918 - Fix getProducedValue for Dijkstra
  • PR-5916 - Remove DRep requirement for reward withdrawals
  • PR-5919 - Adjust consumed and produced interface
  • PR-5935 - Switch minor protocol version to Word32
  • PR-5940 - [Backport] Add LeiosKey to StakePoolParams in leios-prototype branch
  • PR-5927 - Add Leios.BlockHeader
  • PR-5933 - Add AccountBalanceExact constructor to AccountBalanceInterval
  • PR-5944 - Make SnapShots era parametric
  • PR-5926 - Fix/allow thunks in Alonzo/Conway geneses

Testing​

  • PR-5900 - Update Conway conformance tests to PV 11
  • PR-5914 - Add tests for RequiredTopLevelGuards

Infrastructure and releasing​

  • PR-5917 - Bump slackapi/slack-github-action from 3.0.3 to 3.0.4 in the actions group
  • PR-5928 - Update hackage index-state version to get latest cuddle release
  • PR-5934 - Bump slackapi/slack-github-action from 3.0.4 to 4.0.0 in the actions group