Skip to main content

Plutus Core Team Update

· 2 min read
Ziyang Liu
Software Engineering Lead

High level summary​

The Plutus team has recently opened two CIPs and one CPS for review. We encourage everyone to read them and leave comments - we would like as much feedback as possible.

  • CIP-0194 adds a Match node to UPLC for matching on builtin constants (primarily Data). This will make consuming script contexts in validators much cheaper than the status quo.
  • CIP-0195 specifies the Data encoding of the Plutus V4 ledger types.
  • A new CPS aims to build community consensus on how to expose our property tests, and tests for older protocol and language versions, to alternative node and UPLC evaluator implementers with minimal integration effort.

Other than these, we've merged the CollapseCase pass, which rewrites list casing into dropList whenever applicable; the uplc tool now deduces input and output formats from file extensions; and the Plutus V4 ledger API types have been released in 1.67.0.0.

Key Pull Requests Merged​

Pull Requests In Progress​

Consensus Team Update

· 4 min read
Damian Nadales
Consensus Team Lead

High level summary​

  • Leios prototype and testnet (Treasury Funding Initiative 4: Ouroboros Leios Implementation):
    • Added endorser-block announcements to the node. The node now generates them and sends them to its peers. An announcement tells a peer that an endorser block exists, before the block itself arrives. The other Leios components do not use the announcements yet. This change is the first step (#2132, for ouroboros-leios#772).
    • Added announcements to the proto-devnet demo, with a new graph of the announcement age on arrival. The demo can now run a line topology. In that topology the first and third nodes have no direct link. This makes the announcement behaviour easier to watch (#1002).
    • Made the node reject malformed Dijkstra blocks. A block body must not carry both a Leios certificate and transactions. The header flag must also agree with the body content (#2178, for ouroboros-leios#932).
    • Released a new prototype, prototype-2026w32 (#6636).
    • Fixed the testnet visualizer. It lost events and reported send and receive counts that did not match. It now reads the log store with range queries instead of a live stream (#1000).
    • Corrected the units on the throughput dashboard. The certification graph now covers every node, not only the first (#1001).
  • Node performance (Treasury Funding Initiative 17: Maintenance and Support):
    • Removed the allocations from the comparison of transaction identifiers. The old code rebuilt a 32-byte hash on each comparison. The mempool and local queries use that code path heavily. Comparisons now run about five times faster and allocate nothing (#2125, for #2003).
    • Cut the allocations in the mempool snapshot code (#2195).
    • Simplified how the mempool moves a transaction into a newer era. The mempool now decodes the transaction straight into the target era. It no longer steps through each era in between (#2134).
  • Releases and the next hard fork (Treasury Funding Initiative 17: Maintenance and Support):
    • Released ouroboros-consensus 4.0.0.0 and 4.1 (#2161, #2189).
    • Allowed the node to hard fork into Dijkstra, the next Cardano era (#2167).
  • Storage and snapshots (Treasury Funding Initiative 10: LSM including UTXO-HD):
    • Changed the default snapshot policy. The node now takes a snapshot every 40*k slots, with no offset. On mainnet that is one snapshot a day. One snapshot in five lands on an epoch boundary. This keeps the node aligned with Mithril (#2194).
  • Documentation and tooling (Treasury Funding Initiative 17: Maintenance and Support):
    • Wrote a new page on hard forks and node-to-node versioning. A hard fork does not need a new node-to-node protocol version. Each block carries its own era tag. The protocol version holds back an era that is not yet active, not the wire format (#2117).
    • Corrected the db-analyser timing documentation and added two columns to its CSV output. A script that reads the CSV by column position needs an update (#2186).

Hydra Team Update

· 6 min read
Noon van der Silk
Software Engineering Lead

What did the team achieve?​

  • Released 2.3.0, headlined by the reapplyTx snapshot-processing speedup, node configuration via YAML file, native PaymentExtendedKey (HD wallet) key support #2583, and the batch of rotation, Blockfrost and network-layer resilience fixes from the last two updates. Note that all the subsequently listed work has not yet been released
  • Merged the performance stack #2776-#2780, in five reviewable pieces:
    • accumulator commitments are now computed through the rust-accumulator FFI (bit-identical, pinned by equivalence and golden tests) and updated incrementally from the previous confirmed snapshot, taking the 4k-UTxO commitment from 2.13s to 25ms #2780
    • BREAKING: broadcast messages are batched into a single etcd value, one Raft commit per batch over a reused gRPC connection. This bumps the network protocol version to 2, so all members of a head must upgrade together #2778
    • maxTxsPerSnapshot raised from 100 to 1000, leader-side only so no coordinated upgrade is needed #2777
    • SQLite event encoding moved onto the write-behind thread, keeping serialisation of large SnapshotRequested events off the node loop between processing a ReqSn and broadcasting the AckSn #2779
    • plus the measurement and benchmark infrastructure the whole stack was driven from #2776
  • Implemented selective partial fanout: a new PartialFanout client input lets you distribute a chosen subset of the closed head's UTxO, with a HeadPartiallyFannedOut server output telling clients whether the node keeps draining or awaits the next selection, a FanningOut head status, and a matching TUI flow. Only the node that issued the command drives the step, so observers can't steamroll UTxO another party deliberately left behind #2750, #2333, with a docs page to go with it #2794
  • BREAKING: --deposit-period is now embedded in the on-chain OpenDatum at Init time, so all nodes in a head must agree on it; a mismatch emits IgnoredHeadInitializing and the node ignores the head, the same way contestation period mismatches already worked #2734
  • Added --deposit-activation to decouple activation from the deadline calculation: it controls only the Inactive -> Active transition while --deposit-period keeps its deadline and expiry role, giving three independent windows (maturity, active, recovery). The default of 3600s reproduces the old behaviour exactly #2802, #2744
  • POST /commit now rejects deposits that could never be claimed. A dry-run increment is checked against the L1 maximum transaction and serialized value sizes, returning a new DepositTooLarge error. Previously the deposit would land on-chain and the increment claiming it could never be submitted, wedging further incremental commits and locking the funds until recovery after the deadline #2807
  • Fixed long-running nodes rejecting every layer 2 Plutus transaction carrying a validity bound: the era history queried at startup has a forecast horizon (36 hours on mainnet), and once past it those transactions failed with PastHorizon until restart. The last era is now unbounded for L2 ledger time conversions #2803, #2798
  • BREAKING (WebSocket API): removed the SyncedStatusReport server output, which the node pushed on every block. Sync status is now edge-triggered via NodeUnsynced/NodeSynced and Greetings.chainSyncedStatus, and the continuous drift value became a hydra_chain_drift_seconds metric alongside a new hydra_chain_last_block_timestamp_seconds so a stalled chain backend is detectable even while drift is frozen #2769, #2749
  • Made hydra-chain-observer version-aware: it detects which protocol version an observed transaction belongs to by matching head and deposit script hashes against a registry in networks.json covering 0.13.0 through 2.2.0, removing the compile-time coupling to a single version and the hydra-plutus dependency altogether #2740
  • Fixed pasting into hydra-tui text fields (bracketed paste mode, so a paste arrives as one event and typing c into an address no longer cancels the dialog) and stopped it submitting stale form values when the entered address or amount was invalid #2770
  • Made the mac release binaries runnable without nix: they were hard-linking libraries out of /nix/store and simply wouldn't launch on a plain machine #2795, #2461
  • Bumped Mithril to 2630.0 and switched to the v2 database backend, since the aggregator no longer certifies v1 #2808
  • Docs fixes: the transaction-cost benchmark page is now generated by the docs build instead of being dropped in as raw markdown afterwards, so it renders with the current theme and stops listing removed transactions #2799, and the fanout cost table now sweeps party counts #2796

What's next?​

  • Complete the typst + Agda specification work, split into a reviewable stack: a protocol fix forbidding a commit and a decommit in flight simultaneously #2784, the prose migration from LaTeX to Typst #2785, the Agda formalisation itself #2786, a hydra-agda package extracted via MAlonzo with a CI gate #2787, and differential tests checking the node and validator against that reference #2788
  • Switch the event store to CBOR #2767 and offer an opt-in binary encoding on the client API #2762
  • Iterate on ADR 34, covering the separation of hydra-chain-observer into a service shared by several nodes #2771
  • Make rejectLowDeposits a single pass rather than quadratic #2805
  • Get a release out with the performance stack and selective partial fanout

Ledger Team Update

· 4 min read
Alexey Kuleshevich
Ledger Team Software Engineer

High level summary​

Leios support in the ledger took another step forward this cycle: pool parameters now carry an actual BlsKey, replacing the placeholder types introduced previously. On the testing side, block-header serialization - Praos and Leios alike - is now covered by a dedicated round-trip test suite, giving early guard-rails on the wire format as the Leios header evolves.

Work on nested transactions in Dijkstra advanced as well: the withdrawal mechanism for sub-transactions was implemented. Predicate failures around this area were reworked to be more useful and consistent, moved into the layer the specification prescribes and given clearer names. We settled how UTxO state updates should behave under nested transactions and the AdaPots obligations invariant guard-rail was adapted accordingly. A field for the initial account balance was also added to the top-level transaction body.

On the Plutus side, a per-block script cache was introduced so that scripts decoded once for a transaction can be reused by later transactions within the same block. A related optimization now memoizes the computation of the script hashes a transaction needs.

Two CIPs advanced this cycle. CIP-50 (pledge-leverage-based staking rewards) was implemented, and groundwork for CIP-23 began with the addition of the minPoolMargin protocol parameter to the Dijkstra era.

Test coverage was expanded: the Conway conformance suite was enabled in Dijkstra, and new tests were added around stake calculations and sub-transactions - as far as the current test framework allows.

Low level summary​

Features​

  • PR-5945 - Fix JSON roundtrip for InjectionData
  • PR-5946 - Make AlonzoTx mempool decoder backwards compatible
  • PR-5942 - Optimize plutus script preparation
  • PR-5953 - Reuse script cache for script validation
  • PR-5952 - Add startingAccountBalanceInterval to TopTx body
  • PR-5930 - Fix deposits in AdaPots calculations
  • PR-5941 - Fix updating of UTxOState
  • PR-5947 - Add canonical ledger state CDDL spec and validation tests
  • PR-5938 - Rename isValid to isPhase2Valid
  • PR-5967 - Move network checks of deposits and withdrawals to (SUB)ENTITIES
  • PR-5961 - Remove unnecessary setup of the DRepPulser
  • PR-5960 - Memoize getScriptsHashesNeeded in StanTx
  • PR-5969 - Withdrawals rework in SubEntities
  • PR-5943 - CIP-50 Pledge Leverage-Based Staking Rewards
  • PR-5891 - Add BlsKey in StakePoolParams
  • PR-5854 - Add ToJSON/FromJSON instances for EraTxWits
  • PR-5949 - CIP-23 - Add minPoolMargin protocol parameter to Dijkstra era
  • PR-5950 - Drop EncCBORGroup BlockBody in Dijkstra
  • PR-5909 - Stable type for querySetSnapshotStakePoolDistr

Testing​

  • PR-5939 - Enable Conway conformance tests in Dijkstra
  • PR-5959 - Test collateral inputs are in utxo
  • PR-5971 - Add Imp test to test that DReps unregistered and reregistered in the same tx lose vote delegated stake
  • PR-5948 - Add serialization tests for block headers
  • PR-5975 - Add stake calculation tests for conway

Infrastructure and releasing​

  • PR-5874 - Update cardano-binary to 1.9.1.0
  • PR-5968 - Restore <2.6 bound for cardano-crypto-class
  • PR-5970 - Bump cardano-data version for release
  • PR-5976 - Correct a bad changlog entry

Mithril Team Update

· 4 min read
Jean-Philippe Raynaud
Mithril Tech Lead

High level overview​

This week, the Mithril team released the 2630 distribution. This version promotes the DMQ node 0.7.0.0 as beta on the release-mainnet and release-preprod networks, activates the testing phase of the Cardano blocks and transactions certification on the pre-release-preview and release-preprod networks, removes the support for the CardanoImmutableFilesFull certificate type in the Mithril signer and aggregator, and includes various bug fixes and improvements.

The team also completed the assessment of the catchup from the genesis certificate for a SNARK follower aggregator and the encoding of the aggregate signature of the certificate message as bytes, and stopped forcing the rustls TLS backend in the future_snark feature of the STM library. They continued combining the dual MSM and accumulator pairing checks in the IVC proof verification, and reusing the cached unsafe SRS in the SNARK test setups.

They also completed the creation of a local IPFS network for a proof-of-concept of decentralized delivery of Cardano database artifacts, and continued implementing the aggregator CLI commands and the new chain adapter for on-chain configuration parameters, as well as the runbook documenting them.

Finally, the team upgraded the documentation website to Docusaurus 3.10.2 and tailwind v4, completed shipping the Mithril signer node binary in the Cardano node bundle, and continued upgrading to Cardano node v.11.1 and fixing the flakiness of the end-to-end tests in the CI.

Low level overview​

Features​

  • Completed the issue Assess catchup from genesis certificate for SNARK follower aggregator #3389
  • Completed the issue Stop forcing rustls in the future_snark feature of STM #3423
  • Completed the issue Use bytes encoding for aggregate signature in certificate message #3379
  • Completed the issue Create a local IPFS network #3434
  • Worked on the issue Implement aggregator CLI commands for configuration parameters #3392
  • Worked on the issue Create new chain adapter to read on-chain configuration parameters #3393
  • Worked on the issue Combine the dual MSM and accumulator pairing checks in IVC proof verification #3420
  • Worked on the issue Reuse the cached unsafe SRS in the SNARK test setups #3433

Protocol maintenance​

  • Released the new distribution 2630.0
  • Published a dev blog post Distribution 2630 is now available
  • Published a dev blog post DMQ node beta on the release networks
  • Completed the issue Release 2630 distribution #3271
  • Completed the issue Update DMQ node to 0.7.0.0 #3358
  • Completed the issue Update documentation website to docusaurus stable version 3.10.2 #3413
  • Completed the issue Update documentation website to tailwind v4 #3414
  • Completed the issue Remove plausible from documentation website #3447
  • Completed the issue Admonitions are broken in blog posts #3455
  • Completed the issue Ship Mithril signer node binary in Cardano node bundle in GitHub #3011
  • Worked on the issue Upgrade to Cardano 11.1 #3346
  • Worked on the issue Create runbook for on-chain configuration parameters #3399
  • Worked on the issue Fix flakiness of e2e tests in the CI #3452