# Table of Contents - [commonware](#commonware) - [commonware > Benchmarks](#commonware-benchmarks) - [commonware > The Simplest Database You Need](#commonware-the-simplest-database-you-need) - [commonware > Grafting Trees to Prove Current State](#commonware-grafting-trees-to-prove-current-state) - [commonware > Reducing Block Time (and Resource Usage) with Buffered Signatures](#commonware-reducing-block-time-and-resource-usage-with-buffered-signatures) - [commonware > Scaling Throughput with Ordered Broadcast](#commonware-scaling-throughput-with-ordered-broadcast) - [commonware > commonware-cryptography: Unlocking Seeds, Links, and Views](#commonware-commonware-cryptography-unlocking-seeds-links-and-views) - [commonware > Introducing Commonware](#commonware-introducing-commonware) - [commonware > Merkle Mountain Ranges for Performant Data Authentication](#commonware-merkle-mountain-ranges-for-performant-data-authentication) - [commonware > Welcome, Tempo](#commonware-welcome-tempo) - [commonware > Your p2p demo runs locally. Now what?](#commonware-your-p2p-demo-runs-locally-now-what-) - [commonware > commonware-runtime: The Foundation for Reliable and Performant Consensus](#commonware-commonware-runtime-the-foundation-for-reliable-and-performant-consensus) - [commonware > Commonware: the Anti-Framework](#commonware-commonware-the-anti-framework) - [commonware > Binding Timelock Encryption: Only Time Will Tell](#commonware-binding-timelock-encryption-only-time-will-tell) - [commonware > Fast Block Dissemination with Immediate Guarantees](#commonware-fast-block-dissemination-with-immediate-guarantees) - [commonware > Minimmit: Fast Finality with Even Faster Blocks](#commonware-minimmit-fast-finality-with-even-faster-blocks) - [commonware > Once a Validator, Not Always a Validator](#commonware-once-a-validator-not-always-a-validator) - [commonware > Hiring](#commonware-hiring) - [commonware > Many-to-Many Interoperability with Threshold Simplex](#commonware-many-to-many-interoperability-with-threshold-simplex) - [commonware > Podcasts](#commonware-podcasts) --- # commonware + ~ \- + \- + \- + \- ~ ~ \* | commonware \* ~ + + \- ~ \- + \- \* \- + Primitives ---------- ### [broadcast](https://docs.rs/commonware-broadcast) Disseminate data over a wide-area network. ### [codec](https://docs.rs/commonware-codec) Serialize structured data. ### [coding](https://docs.rs/commonware-coding) Encode data to enable recovery from a subset of fragments. ### [collector](https://docs.rs/commonware-collector) Collect responses to committable requests. ### [consensus](https://docs.rs/commonware-consensus) Order opaque messages in a Byzantine environment. ### [cryptography](https://docs.rs/commonware-cryptography) Generate keys, sign arbitrary messages, and deterministically verify signatures. ### [deployer](https://docs.rs/commonware-deployer) Deploy infrastructure across cloud providers. ### [p2p](https://docs.rs/commonware-p2p) Communicate with authenticated peers over encrypted connections. ### [resolver](https://docs.rs/commonware-resolver) Resolve data identified by a fixed-length key. ### [runtime](https://docs.rs/commonware-runtime) Execute asynchronous tasks with a configurable scheduler. ### [storage](https://docs.rs/commonware-storage) Persist and retrieve data from an abstract store. ### [stream](https://docs.rs/commonware-stream) Exchange messages over arbitrary transport. Examples -------- ### [alto](https://alto.commonware.xyz/) A minimal (and wicked fast) blockchain built with the Commonware Library. ### [battleware](https://battleware.xyz/) An onchain battle secured by a VRF, Timelock Encryption, and MMRs. ### [bridge](https://docs.rs/commonware-bridge) Send succinct consensus certificates between two networks. ### [chat](https://docs.rs/commonware-chat) Send encrypted messages to a group of friends. ### [estimator](https://docs.rs/commonware-estimator) Simulate mechanism performance under realistic network conditions. ### [flood](https://docs.rs/commonware-flood) Spam peers deployed to AWS EC2 with random messages. ### [log](https://docs.rs/commonware-log) Commit to a secret log and agree to its hash. ### [reshare](https://docs.rs/commonware-reshare) Reshare a threshold secret over an epoched log. ### [sync](https://docs.rs/commonware-sync) Synchronize state between a server and client. ### [vrf](https://docs.rs/commonware-vrf) Generate bias-resistant randomness with untrusted contributors. Blogs ----- ### [Welcome, Tempo](https://commonware.xyz/blogs/welcome-tempo.html) By [Patrick O'Grady](https://x.com/_patrickogrady) November 7, 2025 Today, we're thrilled to share that Tempo is building with the Commonware Library, supporting our growth as a new core contributor, and accelerating our research and engineering with a strategic investment. ### [Fast Block Dissemination with Immediate Guarantees](https://commonware.xyz/blogs/zoda.html) By [Lucas Meier](https://x.com/cronokirby) November 4, 2025 You can come to consensus over a mere fingerprint of the block---a hash for example---but doing anything interesting with that fingerprint, like processing transactions or updating state, requires disseminating (a lot of) data. ### [Once a Validator, Not Always a Validator](https://commonware.xyz/blogs/reshare.html) By [Ben Clabby](https://x.com/vex_0x) and [Patrick O'Grady](https://x.com/_patrickogrady) October 31, 2025 Many consensus protocols, from Tendermint and HotStuff to our own Minimmit, are defined under a permissioned model where the validator set is fixed and known ahead of time. Safely transitioning from one committee to the next, where validators can be added and removed, is left as an exercise to the implementer. ### [Binding Timelock Encryption: Only Time Will Tell](https://commonware.xyz/blogs/only-time-will-tell.html) By [Patrick O'Grady](https://x.com/_patrickogrady) September 11, 2025 As your parents insisted when you were growing up, good things come to those who wait. It turns out recent advances in cryptography have proven them right. ### [Grafting Trees to Prove Current State](https://commonware.xyz/blogs/adb-current.html) By [Roberto Bayardo](https://x.com/roberto_bayardo) July 9, 2025 While proving you had a lot of money at some time in the past might go over well at a party, what's often far more useful is proving how much money you have _right now_. In database terms, this comes down to proving the _current state_ of a key in a database, which is what we take on in this third article from our series on applying the Merkle Mountain Range (MMR) for efficient data authentication. ### [Minimmit: Fast Finality with Even Faster Blocks](https://commonware.xyz/blogs/minimmit.html) By [Patrick O'Grady](https://x.com/_patrickogrady) and [Brendan Chou](https://x.com/B_Chou) June 24, 2025 Over the last few months, there has been renewed interest in developing _propose-and-vote_ consensus protocols that reach finality after just one round of voting (~100-200ms). "Two-Phase" protocols, not without tradeoffs, only remain safe if a Byzantine adversary controls less than ~20% of stake (rather than the ~33% tolerance typically considered). ### [Reducing Block Time (and Resource Usage) with Buffered Signatures](https://commonware.xyz/blogs/buffered-signatures.html) By [Patrick O'Grady](https://x.com/_patrickogrady) May 28, 2025 A few months ago, we launched Alto, a minimal (and wicked fast) blockchain for continuously benchmarking the Commonware Library. Today, I'm thrilled to share that this benchmarking drove a 20% reduction in block time (to ~200ms), a 20% reduction in block finality (to ~300ms), and a 65% reduction in CPU usage. ### [The Simplest Database You Need](https://commonware.xyz/blogs/adb-any.html) By [Roberto Bayardo](https://x.com/roberto_bayardo) and [Patrick O'Grady](https://x.com/_patrickogrady) April 9, 2025 The primary limitation of the MMR compared to a more typical Merkle tree structure is its lack of support for removing elements from the list over which inclusion proofs can be provided. This restriction, at first glance, might appear to prohibit an MMR from being used to build a mutable database where keys take on values that change over time. However, append-only MMRs are a natural fit for authenticating log data. Instead of viewing our database as only a snapshot in time, the basic idea we'll build on is to maintain an MMR over the historical log of all database operations performed up until the present state. ### [Your p2p demo runs locally. Now what?](https://commonware.xyz/blogs/commonware-deployer.html) By [Patrick O'Grady](https://x.com/_patrickogrady) March 6, 2025 You've built a peer-to-peer (p2p) demo that hums along on your local machine. Peers connect, messages flow, and for a moment, you're basking in localhost bliss. Then comes the inevitable question: how do you migrate this from your laptop to the cloud? ### [Scaling Throughput with Ordered Broadcast](https://commonware.xyz/blogs/commonware-broadcast.html) By [Brendan Chou](https://x.com/b_chou) February 20, 2025 Blockchains require replicating data, like transactions, across nodes in the network—but doing it efficiently and reliably is a challenge. For the last decade, best-effort broadcast has been the norm, relying on consensus to guarantee delivery. The result? Wasted bandwidth by sending the same data multiple times, bottlenecked throughput by routing messages through a single node (the leader in consensus), and degraded performance whenever that node is unresponsive. ### [Merkle Mountain Ranges for Performant Data Authentication](https://commonware.xyz/blogs/mmr.html) By [Roberto Bayardo](https://x.com/roberto_bayardo) February 13, 2025 Decentralized systems require the ability to prove authenticity of data received from potentially untrustworthy sources. The most well known data structure for this task is the Merkle tree, which allows one to efficiently prove inclusion of an element within a list without having to obtain the entire list from a trusted source. ### [Many-to-Many Interoperability with Threshold Simplex](https://commonware.xyz/blogs/threshold-simplex.html) By [Patrick O'Grady](https://x.com/_patrickogrady) January 16, 2025 Starting with the launch of the second blockchain, connecting any blockchain to any other blockchain without additional trust assumptions has been an elusive dream. Ten years later, application developers must still settle for some version of this. ### [Commonware: the Anti-Framework](https://commonware.xyz/blogs/commonware-the-anti-framework.html) By [Patrick O'Grady](https://x.com/_patrickogrady) December 11, 2024 Today’s blockchain stack is designed to be a jack of all trades, but master of none. Modeled after virtual machines (VM) and kernels, it exposes a balanced interface through a one-size-fits-all framework instead of molding to the needs of any specific application. ### [commonware-runtime: The Foundation for Reliable and Performant Consensus](https://commonware.xyz/blogs/commonware-runtime.html) By [Patrick O'Grady](https://x.com/_patrickogrady) September 24, 2024 In blockchain engineering, there are few moments more stressful than the production release of a new mechanism (whether a novel consensus optimization or a tweak to peer discovery). ### [commonware-cryptography: Unlocking Seeds, Links, and Views](https://commonware.xyz/blogs/commonware-cryptography.html) By [Patrick O'Grady](https://x.com/_patrickogrady) August 28, 2024 When I chat with a developer about launching their own onchain application (as a specialized blockchain), the same questions always come up. ### [Introducing Commonware](https://commonware.xyz/blogs/introducing-commonware.html) By [Patrick O'Grady](https://x.com/_patrickogrady) August 8, 2024 Like many of you, I started working in the crypto space because I believe the internet will be a better place if (a lot) more of it is onchain. --- # commonware > Benchmarks [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Benchmarks ========== Last Updated: expand all --- # commonware > The Simplest Database You Need [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) The Simplest Database You Need ============================== By [Roberto Bayardo](https://x.com/roberto_bayardo) and [Patrick O'Grady](https://x.com/_patrickogrady) April 9, 2025 In a [previous article](https://commonware.xyz/blogs/mmr.html) , we detailed the unique properties of the Merkle Mountain Range (MMR) that make it an excellent fit for authenticating data in high-performance blockchains. Recall that MMRs are an authenticated data structure (ADS) from which an untrusted server can efficiently prove inclusion of any element within a growing ordered list, as depicted below: ![Appending new elements to an MMR](https://commonware.xyz/imgs/mmr.png) Figure 1: Appending new elements to an MMR Here, we'll dive into how the construction can be extended to create a lightweight _authenticated database_ (ADB) capable of storing and proving mutable blockchain state with minimal amplification. We call the first of these MMR-powered ADBs [adb::any](https://docs.rs/commonware-storage/latest/commonware_storage/adb/any/index.html) , and are excited to share that it is now available under an MIT/Apache-2 license. The primary limitation of the MMR compared to a more typical Merkle tree structure is its lack of support for removing elements from the list over which inclusion proofs can be provided. This restriction, at first glance, might appear to prohibit an MMR from being used to build a mutable database where keys take on values that change over time. However, append-only MMRs are a natural fit for authenticating log data. Instead of viewing our database as only a snapshot in time, the basic idea we'll build on is to maintain an MMR over the _historical log_ of all database _operations_ performed up until the present state. Let us consider two basic operations, _assigning_ a key a value and _deleting_ a key's value. Each operation applied to the database gets added to a persistent log, and its digest added to an MMR. To provide efficient lookups of a key's value, we employ a [memory-efficient index](https://docs.rs/commonware-storage/latest/commonware_storage/index/index.html) that maps a compressed representation of each key to its latest value in the log. The figure below depicts a small example of this kind of ADB, showing only the updates for key “foo” which is assigned value 5 in log operation 3, deleted at operation 6, and later updated to value 6 at operation 9, which contains its active state. While the contents of the log are durably persisted to disk, the index depicted to the right is memory resident, mapping a key to the location of its currently active operation. Because keys in some applications may be large (e.g. 32 byte hashes), keys are transformed by a user-provided function into a more compact representation (e.g. an 8 byte hash prefix) for memory efficiency. (There is some additional complexity we don't describe here required for handling a small but non-negligible chance of collisions among these transformed keys.) ![Appending new elements to adb::any](https://commonware.xyz/imgs/adb-any.png) Figure 2: Appending new elements to adb::any One challenge with this solution is the endlessly growing log of data which needs to be replayed to derive the current state of the database. Consider the MMR in the diagram above: it stores the old value for key "foo" in operation 3 even though its value is later reassigned in operations 6 and 9. To overcome this, we apply a _compaction_ process that advances the inactivity floor, the index before which all operations are _inactive_ (and therefore don't need to be stored to compute the current state). Starting from the old inactivity floor, we advance over the next n operations, where n is configurable. If the operation is already inactive, we simply drop the data. If it's active, we make it inactive by reapplying the same key-value in a new operation. This process guarantees that the number of inactive operations remaining ahead of the floor is never more than a small constant multiple of the number of active operations. Operations preceding the inactivity floor can be efficiently discarded from disk while still retaining the ability to authenticate any historical operation against the current root. Much as the log supports re-derivation of the database's state, it also allows us to re-derive the state of the pruned MMR as long as we durably persist (aka _pin_) a small (logarithmically sized) set of historical nodes. A variety of designs are possible within this general framework for an authenticated database, each involving differing trade-offs between performance, memory efficiency, and authentication expressivity. Our initial release, [adb::any](https://docs.rs/commonware-storage/latest/commonware_storage/adb/any/index.html) , implements the minimal construction described above over the existing [mmr::journaled](https://docs.rs/commonware-storage/latest/commonware_storage/mmr/journaled/index.html) primitive. To limit the IO of both updates and deletes to a minimum, adb::any **only** supports proving that some key was assigned to a specific value at some point in its history (not that a key has some value now nor that a key has no value). This (lack of capability) achieves a unique balance between performance and functionality that we believe applications will find just useful enough. For example, adb::any can be used to power efficient state sync over the active range (indicated by the inactivity floor), drive message-based interoperability (where emitted messages are forever persisted), and equip users to verify the balance served to them by centralized infrastructure (constraining any future proof to be at an index higher than the last). Another variant, which remains under development, augments this construction with [an authenticated bitmap](https://docs.rs/commonware-storage/latest/commonware_storage/mmr/bitmap/index.html) over the activity status of each operation. This extension allows the ADB to additionally authenticate that a specific value is a key's _current_ value – useful for applications requiring, for example, proving someone's account contains some balance, or that a user currently has the permission to execute some contract. [QMDB](https://arxiv.org/abs/2501.05262) , the primary inspiration for this work, extends these concepts even further, adding the ability to prove _exclusion_ (that some key is not currently assigned any value). In addition to _assign_ and _delete_ over keys, our implementation offers one additional database operation, _commit_, that synchronizes the compaction process with each batch update. In the context of a blockchain, the set of updates from executing all transactions in a block can be atomically committed to the database along with raising the inactivity floor a number of times necessary to prevent it from falling indefinitely behind (a useful marker in the log to inform state syncing clients where to start fetching from the log). This compaction process could be extended to charge any rewritten (still active) account at the inactivity floor some rent or to drop said accounts altogether from “hot” storage (requiring a proof to resurrect when needed again). [adb::any](https://docs.rs/commonware-storage/latest/commonware_storage/adb/any/index.html) is available today with work ongoing to deliver both additional feature variants and a benchmarking suite to evaluate the impact of said variants. Like other primitives, adb::any is exhaustively tested with [runtime::deterministic](https://docs.rs/commonware-runtime/latest/commonware_runtime/deterministic/index.html) over a number of failure scenarios (like unclean shutdown). We look forward to releasing a production-ready version of adb::any later this year. --- # commonware > Grafting Trees to Prove Current State [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Grafting Trees to Prove Current State ===================================== By [Roberto Bayardo](https://x.com/roberto_bayardo) July 9, 2025 While proving you had a lot of money at some time in the past might go over well at a party, what's often far more useful is proving how much money you have _right now_. In database terms, this comes down to proving the _current state_ of a key in a database, which is what we take on in this third article from our series on applying the Merkle Mountain Range (MMR) for efficient data authentication. Recall that our [first article](https://commonware.xyz/blogs/mmr.html) described the basics of the MMR and what makes it special: updates are _fast_ (compared to a more standard Merkle Tree) because they only append new data without modifying any historical data. Our [second article](https://commonware.xyz/blogs/adb-any.html) described how one might use an MMR to authenticate the simplest database you need for state sync and interoperability, even though at first glance the MMR might appear inapplicable to the task. The idea here was to view a database as the result of applying a sequential list of operations, over which the MMR is then constructed. We called this structure _adb::any_ because it allows for a compact proof (from an untrusted server, of course) that a specific key had taken on _any one_ of its historical values at some point in its history. ![Log operations and status bits over the key named 'foo'.](https://commonware.xyz/imgs/adb-activity.png) Figure 1: Log operations and status bits over a key named "foo". Only the last update of each key has a 1 for its activity status, indicating its current value (6). Authenticating Current Values ----------------------------- In this post, we show how to extend adb::any to prove that a key _currently_ holds a specific value. If you recall from our second article, the adb::any already tracks an activity status for each operation in the log (figure 1), allowing it to serve only the most recent value (if any) associated with each key. Imagine then pulling out this information into a separate list (or bit vector), where each element is a single bit indicating the corresponding operation's activity status. Unfortunately, unlike the list of operations which changes only through appending new ones, the vector of activity bits requires historical updates. Specifically, each time a key's value is updated, the operation corresponding to its last update flips from active to inactive. Reflecting that state change therefore requires we modify a historical bit rather than simply appending a new bit corresponding to the latest update. If we wish to make authenticable claims over activity status, we'll (disappointingly) need to use a new data structure to handle these types of updates. Instead of replacing the MMR entirely, we keep the MMR over the operations log as is, and augment it with a _separate_ Merkle tree of _identical_ structure built over just the activity status bits. Conveniently, the only difference between an MMR and this kind of Merkle tree [is the ability to modify previous elements and recompute the digests of its ancestors in the tree](https://github.com/commonwarexyz/monorepo/blob/8174f10c6e17e762d1393ef38b2282cf70da024a/storage/src/mmr/mem.rs#L288-L333) . By tying these two structures together with a root over the peaks of each (figure 2), a proof derived from only two paths (one to the operation and one to its corresponding activity state) delivers exactly the functionality we are looking for. ![A combined MMR + Merkle Tree (MT) of identical structure allows proving which value for a given key is current.](https://commonware.xyz/imgs/adb-naive.png) Figure 2: A combined MMR + Merkle Tree (MT) of identical structure allows proving which value for a given key is current. In this figure the siblings along the two paths from root highlighted in red provide the necessary digests for proving “foo currently has value 6”. Making Updates Fast ------------------- We've taken a bit of a step backwards by introducing a Merkle tree, since updates are no longer purely append-only. But, we can limit the performance impact of this tweak by pinning the Merkle tree portion of the structure entirely in RAM (compared to the log of operations, the size of the activity status bit vector is quite compact). Furthermore, we can divide the bit vector into _chunks_ over which we build the [tree](https://github.com/commonwarexyz/monorepo/blob/8174f10c6e17e762d1393ef38b2282cf70da024a/storage/src/mmr/bitmap.rs#L7) . The bottom line is, with a suitable choice of N, this structure is small enough to keep entirely memory resident even over very large databases (and worth doing so to avoid random, small writes over disk). We won't review it here but both trees, like with the “single tree” adb::any, can be regularly pruned to keep their sizes in check. ![The combined tree structure with the Merkle tree built over chunks of 4 bits each (N=2).](https://commonware.xyz/imgs/adb-chunked.png) Figure 3: The combined tree structure with the Merkle tree built over chunks of 4 bits each (N=2). Making Proofs Small ------------------- As described above, a _current-value proof_ would be up to 2x larger than an _any-value proof_ because it requires digests from the path of the second tree (the one to the relevant activity status chunk). As long as the number of bits in each chunk is a power of 2, however, the structure of the Merkle tree over activity status remains _compatible_ with the structure of the MMR over database operations. That is, for a chunk size of 2^N, the Merkle tree matches exactly that of the MMR with its bottom N levels removed (figure 3). Instead of maintaining two completely independent trees tied together at a new root, we can instead _graft_ each leaf of the Merkle tree onto its corresponding internal node of the MMR (figure 4). ![Grafting each Merkle tree leaf onto its corresponding node in the MMR.](https://commonware.xyz/imgs/adb-current.png) Figure 4: Grafting each Merkle tree leaf onto its corresponding node in the MMR. Generating a proof over this grafted structure produces a current-value proof that contains the same node digests as a corresponding any-value proof and a bitmap chunk containing an operation's activity bit. Our implementation defaults to a chunk size of 256 bits (the same size as most hash digests) so that a current-value proof includes _just one_ extra digest-worth of data compared to an any-value proof of the same value. _Our grafting technique draws inspiration from [QMDB](https://arxiv.org/abs/2501.05262) 's novel “twig” abstraction but opts for smaller, configurable chunks (to minimize proof size) and, as noted previously, relies exclusively on RAM to store all unpruned chunks (to avoid random writes)._ Marching Towards Production --------------------------- [adb::current](https://github.com/commonwarexyz/monorepo/blob/main/storage/src/adb/current.rs) is available today in the Commonware Library, along with several new storage extensions (that have delivered [significant performance gains](https://commonware.xyz/benchmarks.html) over the past month). This includes a flexible [caching layer](https://github.com/commonwarexyz/monorepo/tree/main/runtime/src/utils/buffer) that provides write-ahead and random-access caching through a shared [buffer pool](https://github.com/commonwarexyz/monorepo/blob/main/runtime/src/utils/buffer/pool.rs) , [parallelized merkleization](https://github.com/commonwarexyz/monorepo/blob/8174f10c6e17e762d1393ef38b2282cf70da024a/storage/src/mmr/mem.rs#L460) via batched updates, and an [io\_uring storage implementation](https://github.com/commonwarexyz/monorepo/blob/main/runtime/src/storage/iouring.rs) (for operating systems that support it). We remain on-schedule to release a production-ready version of [commonware-storage](https://docs.rs/commonware-storage) later this year. --- # commonware > Reducing Block Time (and Resource Usage) with Buffered Signatures [+ ~ \- + \- ~ \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Reducing Block Time (and Resource Usage) with Buffered Signatures ================================================================= By [Patrick O'Grady](https://x.com/_patrickogrady) May 28, 2025 A few months ago, we launched [Alto](https://x.com/_patrickogrady/status/1901645720823935341) , a minimal (and wicked fast) blockchain for continuously benchmarking the [Commonware Library](https://github.com/commonwarexyz/monorepo) . Today, I'm thrilled [to share](https://alto.commonware.xyz/) that this benchmarking drove a 20% reduction in block time (to ~200ms), a 20% reduction in block finality (to ~300ms), and a 65% reduction in CPU usage. It turns out procrastinating, even in the world of consensus, can be a great strategy. Laying the Foundation --------------------- [Last August](https://commonware.xyz/blogs/introducing-commonware.html) , we released the first [Commonware Library](https://github.com/commonwarexyz/monorepo) primitive: [p2p::authenticated](https://docs.rs/commonware-p2p/latest/commonware_p2p/authenticated/index.html) . Unlike traditional p2p libraries that specialize in gossip-based messaging over a subset of peers (typically identified by randomly generated IDs), _p2p::authenticated_ provides point-to-point messaging between a swarm of fully-connected and authenticated peers (identified by some public key on an externally synchronized list, like a staking registry). ![Comparing gossip models](https://commonware.xyz/imgs/gossip-models.png) Figure 1: Comparing gossip models The consensus primitives we released in [December](https://commonware.xyz/blogs/commonware-the-anti-framework.html) ([consensus::simplex](https://docs.rs/commonware-consensus/latest/commonware_consensus/simplex/index.html) ) and [January](https://commonware.xyz/blogs/threshold-simplex.html) ([consensus::threshold-simplex](https://docs.rs/commonware-consensus/latest/commonware_consensus/simplex/index.html) ) built on top of _p2p::authenticated_ but didn't do anything particularly clever with it (the point-to-point messaging alone was enough of an improvement to reach the ~250ms block time in the original Alto launch). So, what would something clever look like? Buffered Signature Verification ------------------------------- Seeking to progress through consensus as fast as possible, most consensus implementations verify signatures as soon as they are available (often in parallel to avoid slowing down the consensus state machine). This eager verification makes intuitive sense—you want to either enter a new view or finalize a block as soon as possible (and verifying a signature is a prerequisite for either). When peers are tasked with forwarding messages in traditional p2p, the recipient of a message can never be sure what they have (and what they have from whom) until verification. A malicious peer could forward a message with a valid signature, tamper with a signature over a message that someone did send (invalid signature), or even fabricate messages to impersonate a different peer (invalid signature). ![Block peers that send invalid signatures](https://commonware.xyz/imgs/invalid-signature-gossip.png) Figure 2: Block peers that send invalid signatures With _p2p::authenticated_, we have the necessary functionality to do something novel: dedicated peer slots. Instead of verifying each peer signature individually as it arrives, we now buffer messages in slots dedicated to each authenticated peer. When we collect a quorum (_2f+1_) of signatures over some message, we perform a single multi-signature verification (with plans to support batch verification if not using BLS12-381 signatures) instead of verifying each signature individually ([dramatically reducing the time spent verifying each signature](https://commonware.xyz/benchmarks.html) ). ![Buffer signatures until a quorum is reached](https://commonware.xyz/imgs/buffering.png) Figure 3: Buffer signatures until a quorum is reached Handling Invalid Signatures --------------------------- Now that we aren't verifying each message when it arrives over the wire, however, one bad apple can spoil the whole bunch. Fortunately, we have one more capability in _p2p::authenticated_ to make this safe: identity blocking. When verification fails, a binary search is run over all buffered signatures to identify the offender(s). In the worst case (where _f_ signatures are invalid), this can lead to more verifications than the original eager approach in a given view. However, once identified as malicious, that peer is blocked by its staking identity, unable to send more invalid messages to us from any network address until the binary restarts. Without this blocking, it would be trivial for a set of malicious peers to undermine this optimization (and make it worse than the original eager approach on every view). With identity-based blocking, however, bisection will only be triggered on a very small number of views over the course of a typical 7-day epoch (3,000,000 views). Specifically, a validator set of 1000 could at most cause disruption in ~333 views (0.011% of views). ![Search for invalid signatures via repeated bisection](https://commonware.xyz/imgs/bisection.png) Figure 4: Search for invalid signatures via repeated bisection Reducing Block Time (and Resource Usage) ---------------------------------------- By transitioning from individual signature verifications to aggregate signature verification, the performance of [Alto](https://alto.commonware.xyz/) improved significantly (while using less resources): * **Block time**: 255ms → 200ms (20% reduction) * **Finality**: 375ms → 300ms (20% reduction) * **CPU usage**: 26% → 9% on a [c7g.xlarge](https://github.com/commonwarexyz/alto/tree/main/chain#create-artifacts-1) (65% reduction) The footprint of _p2p::authenticated_ and _consensus::threshold-simplex_ is now less than half a core, leaving plenty of compute available for your application to do more of whatever it does best. Reproduce our results (and start building your own blockchain) with the free and open-source [code](https://github.com/commonwarexyz/alto) today. Consensus is often the main attraction. At Commonware, we've been working hard to ensure it is a sideshow. --- # commonware > Scaling Throughput with Ordered Broadcast [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Scaling Throughput with Ordered Broadcast ========================================= By [Brendan Chou](https://x.com/b_chou) February 20, 2025 Blockchains require replicating data, like transactions, across nodes in the network—but doing it efficiently and reliably is a challenge. For the last decade, best-effort broadcast has been the norm, relying on consensus to guarantee delivery. The result? Wasted bandwidth by sending the same data multiple times, bottlenecked throughput by routing messages through a single node (the leader in consensus), and degraded performance whenever that node is unresponsive. Enter _commonware-broadcast_. Our latest primitive provides a common interface for data dissemination, with multiple “dialects” tailored around different tradeoffs and types of data. The first dialect, [consensus::ordered\_broadcast](https://docs.rs/commonware-consensus/latest/commonware_consensus/ordered_broadcast/index.html) , uses a concurrent, ordered, and fault-tolerant approach to replication that efficiently integrates with consensus mechanisms using threshold cryptography. Let's break it down. This dialect specifies two roles in the network: **sequencers** who initiate and order messages, and **validators** who verify and acknowledge messages. Membership in the sets is arbitrary; the set of sequencers and validators may overlap or be completely distinct. When used in a blockchain setting, the set of broadcast validators may or may not match the set of block validators. Validators acknowledge receipt and validate messages by emitting partial signatures. These partial signatures are aggregated into threshold signatures once a quorum is reached. For sequencers, each new message must also carry the threshold signature of the previous message in the sequencer's history. By induction, a single threshold signature provides cryptographic proof of the existence of the entire history of linked messages. That is, each previous message is guaranteed to have been validated by a quorum of validators. Credit goes to [Autobahn](https://arxiv.org/abs/2401.10369) , which introduces the idea that certified messages—when linked—imply a complete, valid, and well-replicated history of messages. ![Sequencer broadcasting messages, linking each to the previous one using threshold signatures.](https://commonware.xyz/imgs/ordered-broadcast.png) Figure 1: A diagram of a sequencer broadcasting messages, linking each to the previous one using threshold signatures. Multiple validators are contributing partial signatures. The formation of threshold signatures over each message has powerful implications. 1. With just the latest message (i.e. the tip) of each sequencer, participants know that all previous messages have been broadcast and validated. This lets them begin syntactic verification of any new messages, while backfilling all missing messages in parallel. This enables efficient recovery from node failures or temporary network disruption, or efficient startup for nodes coming online for the first time. 2. Broadcast is decoupled from consensus. Consensus can finalize—in “one shot”—the entirety of all unfinalized messages by including the certified tip of each sequencer. This results in massive throughput. Broadcast can be parallelized with multiple sequencers without being blocked by consensus—even by a single-leader mechanism. Finalization via consensus then requires only a tiny amount of data per sequencer. 3. The threshold signature serves as a pre-consensus receipt of inclusion. Partial signatures are broadcast to all other validators as well as the sequencer, allowing any of these parties to construct the threshold signature. The threshold signature guarantees that the message becomes an immutable part of the sequencer's history, and thus that it will eventually be included in consensus. ![Every block references a set of sequencer tips, each with a threshold signature.](https://commonware.xyz/imgs/broadcast-in-consensus.png) Figure 2: A diagram showing how broadcast messages may be used in consensus. Every block references a set of sequencer tips, each with a threshold signature. _consensus::ordered\_broadcast_ also handles set reconfiguration. It is robust in the face of changing participants across epochs—distinct periods when the set of validators and sequencers may change. During changes, the aggregate set of validators must still be able to produce a threshold signature using the same threshold public key. Meanwhile, the set of sequencers may change arbitrarily. For example, the system might modify the number of active sequencers or remove and later reinstate them. Sequencer tips are stored robustly in a write-ahead log, ensuring consistency even in the face of unexpected node shutdown. This prevents honest sequencers from broadcasting conflicting messages and also prevents honest validators from signing conflicting messages from dishonest sequencers. Conflicting messages are messages with the same sequencer and height that contain different data. As with other primitives, this dialect is tested for resilience using Commonware's [deterministic simulator](https://commonware.xyz/blogs/commonware-runtime.html) . It reproducibly simulates complex scenarios such as packet loss, complete node failure, and temporary network partitions. For developers building decentralized applications, _consensus::ordered\_broadcast_ unlocks high-throughput replication using multiple sequencers and a simple, easily verifiable structure over message dissemination. Its use of threshold signatures proves the integrity of an entire history of messages, allowing for fast, succinct validation by external nodes ingesting network activity and can serve as early confirmation for users (and a slashable commitment for the sequencer). Scalability is no longer a differentiator—it's a requirement. _consensus::ordered\_broadcast_ is your shortcut. --- # commonware > commonware-cryptography: Unlocking Seeds, Links, and Views [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) commonware-cryptography: Unlocking Seeds, Links, and Views ========================================================== By [Patrick O'Grady](https://x.com/_patrickogrady) August 28, 2024 When I chat with a developer about launching their own onchain application (as a specialized blockchain), the same questions always come up: * Where can I source bias-resistant randomness? _(ensure fair and unpredictable outcomes in onchain games)_ * Will my application be able to interact with other applications? _(transfer tokens between blockchains and gate experiences with external token ownership)_ * Can users verify data fetched from an API is correct? _(supermajority of validators indicate whether a payment was finalized, not an API provider)_ Today, we're excited to share how @commonwarexyz is answering these questions with [commonware-cryptography](https://docs.rs/commonware-cryptography) (now in ALPHA). commonware-cryptography is an open (Apache-2 and MIT) implementation of BLS12-381 Distributed Key Generation (DKG), Resharing, and Threshold Signatures in Rust. Unlike most implementations, our construction does not employ a "board" for share distribution (that requires dealers to broadcast encrypted shares over a public channel). Rather, dealers distribute shares over encrypted connections directly with each player and players broadcast an acknowledgement when they receive a correct share (no share material posted). With an eye towards consensus integration (natively emitting Threshold Signatures during finalization), this interactive DKG/Resharing construction requires 2f + 1 players (of 3f + 1 players where any f are Byzantine) to generate a valid threshold signature. Resharing can be run to introduce/remove contributors and/or proactively on a regular interval to bound the age of any shares. You can read more about this construction [here](https://docs.rs/commonware-cryptography/latest/commonware_cryptography/bls12381/dkg/index.html) . So, how does this answer any of a developer's questions? * **Seeds _(Randomness)_:** BLS12-381 Threshold Signatures are deterministic and can be used as a bias-resistant source of randomness. No contributor knows the value of a signature until collecting at least "threshold" partial signatures. * **Links _(Connectivity)_:** With BLS12-381 DKG/Resharing, a group of contributors (like a validator set) maintain a static public key over time (even as participants are added/removed). If this set of contributors signs over a finalized block, anyone can verify that block (or anything provable from its header) is included in the canonical history using the static public key of the group (48 bytes) and a Threshold Signature (96 bytes). A blockchain can support verification of BLS signatures in the execution layer (many already do) and read finalized data from another blockchain without following its consensus or tracking its validator set (as a lite client). * **Views _(Access)_:** "Links" can be extended beyond blockchain execution environments to wallets and explorers to provide trust-minimized access to onchain activity. Like a blockchain, all a user requires to verify that a blockchain included/emitted some data is its static public key (can be hardcoded) and a Threshold Signature over a block (or whatever artifact a developer wants to emit) referencing said data. To showcase how "Seeds" will work, we implemented a [Proof-of-Concept Verifiable Random Function (VRF) CLI](https://docs.rs/commonware-vrf) with a trusted Arbiter and untrusted Contributors. Contributors to this VRF connect to each other over commonware-p2p (using ED25519 identities), perform an initial DKG (to generate a static public key), and then perform a proactive refresh every 10 seconds. After a successful DKG and/or Reshare, contributors generate partial signatures over the round number and gossip them to others in the group (again using commonware-p2p). These partial signatures, when aggregated, form a bias-resistant source of randomness that was not knowable to any contributor prior to signing. To demonstrate how malicious contributors are tolerated, the CLI also lets you behave as a "rogue" dealer that generates invalid shares, a "lazy" dealer that distributes the minimum number of shares to other contributors, or a "forger" dealer that produces fake acknowledgements. Next up, commonware-consensus! _To support contributors and developers working with the Commonware Library, we activated [GitHub Discussions](https://github.com/commonwarexyz/monorepo/discussions) . We look forward to seeing you there soon!_ --- # commonware > Introducing Commonware [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Introducing Commonware ====================== By [Patrick O'Grady](https://x.com/_patrickogrady) August 8, 2024 Like many of you, I started working in the crypto space because I believe the internet will be a better place if (a lot) more of it is onchain. I am launching a new company, [@commonwarexyz](https://x.com/commonwarexyz) , because I think the communities that will lead this transition over the next decade will take a different path than the ones already paved. At Commonware, we believe that the best onchain experiences will develop a sustained edge through specialization. Like the Web 2.0 era that came before, we believe unbundling blockchains (tailoring networking, consensus, storage, and execution to amplify the unique aspects of an application) will create a lasting advantage and unlock performance that can rival the centralized websites where most users spend their time. ![Craigslist unbundling](https://commonware.xyz/imgs/craigslist-unbundling.jpeg) Source: ["Unbundling Craigslist – $8.87 Billion Raised to Date by Startups"](https://www.cbinsights.com/research/craigslist-unbundling/) To accelerate developers that share this perspective, Commonware is building an open set of Rust-based blockchain primitives architected for excessive throughput, tractable modification, and embedded interoperability. Handle surging load with [Decoupled State Machine Replication (DSMR)](https://hackmd.io/@patrickogrady/rys8mdl5p#Making-the-Case-for-Decoupled-State-Machine-Replication-DSMR) , inject novel low-level functionality without maintaining a fork, and communicate with external deployments using static identities + efficiently verifiable consensus artifacts. Today, we are taking the first step towards launching the Commonware Library. [commonware-p2p](https://docs.rs/commonware-p2p) , our first primitive, is now available (in ALPHA) under both Apache-2 and MIT. See you on [GitHub](https://github.com/commonwarexyz/monorepo) (for now)! _Want to help? Commonware is looking for a small group of founding engineers (1-10% equity). If you enjoy the never-ending challenge of building performant distributed systems, reach out to [@commonwarexyz](https://x.com/commonwarexyz) or hiring@commonware.xyz with a link to some of your most interesting work!_ --- # commonware > Merkle Mountain Ranges for Performant Data Authentication [+ \- \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Merkle Mountain Ranges for Performant Data Authentication ========================================================= By [Roberto Bayardo](https://x.com/roberto_bayardo) February 13, 2025 Decentralized systems require the ability to prove authenticity of data received from potentially untrustworthy sources. The most well known data structure for this task is the [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) , which allows one to efficiently prove inclusion of an element within a list without having to obtain the entire list from a trusted source. A Merkle tree is a [binary tree](https://docs.rs/commonware-storage/latest/commonware_storage/bmt/index.html) whose leaves represent the list elements by storing the hash of the element, and whose internal nodes store the hash of their children. The only trusted piece of data required to validate a Merkle proof is a single hash value (~32 bytes) corresponding to the root of the Merkle tree. And the Merkle proof is itself quite small, consisting of a single value from each node along the path from root to the leaf element (logarithmic in the size of the list _N_) as illustrated in Figure 1. ![Example Merkle tree over a list of 7 elements](https://commonware.xyz/imgs/merkle-tree.png) Figure 1: Example Merkle tree over a list of 7 elements Because of these powerful properties, it's no surprise that the Merkle tree and its variants (such as [Ethereum's Merkle Patricia Trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) ) are fundamental components of most blockchains. And making these data structures performant is among today’s primary challenges to scaling blockchains further. One particularly interesting variant of the Merkle tree, [now available in the Commonware Library](https://docs.rs/commonware-storage/latest/commonware_storage/mmr/index.html) , is the [Merkle Mountain Range](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md) (MMR). A MMR differs from a Merkle tree in that it is append-only. While Merkle trees support element updates and insertions at arbitrary list positions, MMRs only allow new elements to be added to the end of the list. The append-only restriction may appear burdensome, but it turns out updates can still be simulated through re-appending data (as in [QMDB](https://arxiv.org/pdf/2501.05262) ). What this restriction yields, however, is extreme performance. When adding an element to the MMR, (1) very little data needs to be read in from storage (typically cached), and (2) new data generated by the addition can be persisted to storage with one contiguous write. Contrast this to a standard Merkle tree, where adding or updating an element can require reading and updating a logarithmically sized amount of data scattered randomly across storage. A [perfect binary tree](https://www.geeksforgeeks.org/perfect-binary-tree/) is a binary tree that is both balanced and has a full set of leaves. A MMR is a list of perfect binary trees, called _mountains_, each of strictly decreasing height. The leaves of the MMR store the (positioned) hash of each element in the order of their insertion. We won't cover all the details here, but note that this structure is easy to maintain: if you add a new element to the end of the list, you need only generate at most a _log2(N)_ number of new internal nodes to re-impose the required properties without modifying any existing nodes, as depicted in Figure 2 below. ![Appending new elements to an MMR](https://commonware.xyz/imgs/mmr.png) Figure 2: Appending new elements to an MMR The root nodes of each mountain are called the _peaks_ of the MMR. The _root hash_ of the MMR is computed by hashing the total number of nodes in the MMR together with the set of all peak hashes, a process called _bagging the peaks_. The amount of trusted data for MMR data authentication thus remains a single hash. A MMR inclusion proof consists of hashes derived from the path connecting its leaf element to the peak of its mountain, along with the hashes of the peaks of all other mountains. Both sets of hashes are bounded by _log2(N)_ in number. Because elements are all written sequentially, there is no need for intensive free space recovery techniques such as garbage collection or compaction. As soon as we no longer require proving the inclusion of any element older than a certain point in time, we can drop nearly all of those elements (and most of their ancestor nodes) from the MMR without losing the ability to generate new roots. ![Wrapping the MMR root with a consensus certificate](https://commonware.xyz/imgs/mmr-certificate.png) Figure 3: Wrapping the MMR root with a consensus certificate MMRs and [threshold consensus signatures](https://commonware.xyz/blogs/threshold-simplex.html) make for a powerful combination. Consider, for example, using an MMR to store successfully executed blockchain transactions in the order of their execution. If the MMR root is included in the block digest, then a user (or external blockchain) running a lite client can prove successful execution of any historical transaction from a consensus certificate and the latest MMR root. Have a proof from an old MMR root? The latest MMR root (effectively) includes references to all previous roots and can be combined with some recent intermediate hashes to verify it. Generating a lot of data but need a proof of inclusion (and order)? Reach for the MMR. --- # commonware > Welcome, Tempo [+ ~ \- + \- + \* \- + \- ~ ~ \*\ \ | commonware\ \ ~ \* + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Welcome, Tempo ============== By [Patrick O'Grady](https://x.com/_patrickogrady) November 7, 2025 Today, we're thrilled to share that [Tempo](https://tempo.xyz/) is building with the [Commonware Library](https://github.com/commonwarexyz/monorepo) , supporting our growth as a new core contributor, and accelerating our research and engineering with a strategic investment. I started Commonware because I believe that [the best onchain experiences will develop a sustained edge through specialization](https://commonware.xyz/blogs/introducing-commonware.html) and [the one-size-fits-all frameworks available today](https://commonware.xyz/blogs/commonware-the-anti-framework.html) prevent ambitious teams from doing exactly this. Rather than prioritizing balanced performance and functionality across all applications, the Commonware Library provides a collection of standalone primitives across network, storage, and consensus that can be remixed as engineers see fit. ![Rather than prioritizing balanced performance and functionality across all applications, the Commonware Library provides a collection of standalone primitives across network, storage, and consensus that can be remixed as engineers see fit.](https://commonware.xyz/imgs/commonware-primitives.png) The Commonware Library has no explicit layering or hierarchy. No specific security assumption. No hardcoded block format, state layout, definition of finality, mempool policy, execution rules, nor fee metering. It should be no surprise then that collaborating with Tempo, “the blockchain designed for payments,” made a lot of sense. Tempo is directing their research towards mechanisms that unlock differentiated payment experiences and Commonware is supplying state-of-the-art primitives for everything else. When live, Commonware will collect invaluable telemetry from real-world environments to improve the Commonware Library for all other users. To accelerate Commonware's work to make (wicked good) blockchain infrastructure accessible to all developers, Tempo is both supporting the Commonware Library as a core contributor and leading a $25M strategic investment into Commonware. We look forward to collaborating with Tempo and releasing hundreds of new and free primitives in the years to come. Read more [here](https://tempo.xyz/commonware) . _Think you could design a useful primitive? We're actively [hiring](https://commonware.xyz/hiring.html) engineers to join our remote team of 7._ --- # commonware > Your p2p demo runs locally. Now what? [+ ~ \- + \- \* + \- + \- ~ ~ \*\ \ | commonware\ \ \* \- + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Your p2p demo runs locally. Now what? ===================================== By [Patrick O'Grady](https://x.com/_patrickogrady) March 6, 2025 You've built a peer-to-peer (p2p) demo that hums along on your local machine. Peers connect, messages flow, and for a moment, you're basking in localhost bliss. Then comes the inevitable question: how do you migrate this from your laptop to the cloud? Enter [deployer](https://docs.rs/commonware-deployer) , a CLI and library that bridges the gap between localhost and remote host. Roll custom binaries and configurations to instances in multiple regions, configure networking policies that allow peers to talk to each other, automatically collect metrics and logs, and clean up when you're done. Spend your time coding, not tweaking CIDR blocks. From Localhost to the Cloud --------------------------- Deploying a p2p application isn't as straightforward as spinning up a web server. You'll need to reckon with: * **Networking**: How do your nodes discover each other across regions? * **Deployment**: How do you push unique binaries and configs to each instance? * **Observability**: When a node in Brazil starts acting up, how do you know? * **Cleanup**: When you're done, how do you ensure you don't leave a mess behind? You could spend weeks configuring VPC peering, wrestling with IAM roles, and praying that your Grafana dashboard actually shows something. Or, you could use [deployer](https://docs.rs/commonware-deployer) . Introducing deployer -------------------- _deployer_ is your one-stop shop for deploying p2p applications in the cloud. It's both a CLI for quick wins and a Rust library when you need to get custom. Think of it like a high-level abstraction over infrastructure APIs with sane defaults and observability built-in. The first _deployer_ dialect, [deployer::ec2](https://docs.rs/commonware-deployer/latest/commonware_deployer/ec2/index.html) , is focused on reproducible benchmarking. With a single YAML config, it performs: * **Automated Provisioning**: Spins up EC2 instances in multiple regions, sets up VPCs, internet gateways, route tables, subnets, security groups, SSH keys, and connects everything together with VPC peering. * **Code Deployment**: Uploads custom binaries and configs (specified uniquely for each instance), installs everything as a systemd service, and starts everything up. Pushes updates in-place. * **Configured Monitoring**: Launches a dedicated monitoring instance (running Prometheus, Grafana, and Loki) configured to ingest data from all deployed instances. * **1-Command Cleanup**: Destroys everything when you're done, protecting you from surprise charges from that box you forgot to shutdown. ![Deployment of custom binaries across multiple AWS regions](https://commonware.xyz/imgs/deployer-architecture.png) Figure 1: Deployment of custom binaries across multiple AWS regions Try it Out: flood ----------------- To demonstrate how to use _deployer_, we build a [p2p::authenticated](https://docs.rs/commonware-p2p/latest/commonware_p2p/authenticated/index.html) benchmarking tool called [flood](https://docs.rs/commonware-flood) . _flood_ does one thing: spam peers with as many random messages as possible. _flood_ leverages _deployer_ to transform a local stress test into a global one. Here's how it works: 1. **Setup**: The _setup_ binary (included in the _flood_ crate) generates a _deployer::ec2_ config.yaml file and peer-specific configs from user-specified peer, bootstrapper, region, and performance parameters (like message size and message backlog). 2. **Compile**: _flood_ uses Docker to compile the _flood_ binary for ARM64 (_deployer::ec2_ uses Graviton EC2 instances). 3. **Deploy**: _deployer ec2 create_ spins up instances across regions, wires them together, and starts the flood binary on each peer. The custom Grafana dashboard is started at _http://monitoring-ip:3000/d/flood_. 4. **Tweak**: _deployer ec2 update_ deploys new binaries and configs on each peer. 5. **Cleanup**: _deployer ec2 destroy_ tears down all provisioned infrastructure. _Step through the full walkthrough in the [README](https://github.com/commonwarexyz/monorepo/blob/main/examples/flood/README.md) ._ ![Automatically deployed Grafana dashboard for flood running on c7g.xlarge (4 vCPU, 8GB RAM)](https://commonware.xyz/imgs/flood-grafana.png) Figure 2: Automatically deployed Grafana dashboard for _flood_ running on _c7g.xlarge (4 vCPU, 8GB RAM)_ A local demo is a proof of concept; _deployer::ec2_ makes it a proving ground. --- # commonware > commonware-runtime: The Foundation for Reliable and Performant Consensus [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + + ~ \- + \- \* \- +](https://commonware.xyz/index.html) commonware-runtime: The Foundation for Reliable and Performant Consensus ======================================================================== By [Patrick O'Grady](https://x.com/_patrickogrady) September 24, 2024 In blockchain engineering, there are few moments more stressful than the production release of a new mechanism (whether a novel consensus optimization or a tweak to peer discovery). While Twitter fame invariably awaits the successful, failure too often means nights and weekends parsing thousands of log lines (on top of whatever is required to unhalt a borked network). The sting of wayward improvements has deterred many engineers, reasonably so, from modifying well-behaved code with emergent (and difficult to test) stability. ![Working through a consensus fault](https://commonware.xyz/imgs/consensus-fault.jpeg) At [@commonwarexyz](https://x.com/commonwarexyz) , we believe the relationship between engineers and mechanism iteration must be (substantially) advanced for onchain applications to achieve widespread adoption. If developers are forced to shy away from frequent and aggressive iteration, the onchain future we all hope for will remain just that ... an onchain future. commonware-runtime: 1 Trait, 2 Dialects --------------------------------------- As an early step towards this goal, we are excited to release [commonware-runtime](https://docs.rs/commonware-runtime) (Apache-2 and MIT), a new primitive for the configurable execution of concurrent Rust. The _commonware-runtime::deterministic_ dialect enables code to be deterministically simulated (from a user-provided seed) without kernel-level virtualization. The _commonware-runtime::tokio_ dialect allows for the same code (without modification) to be executed in production (using Tokio). Want to develop your own simulator or novel production executor? No worries! Just implement the [exported traits from commonware-runtime](https://docs.rs/commonware-runtime/latest/commonware_runtime/#traits) and you can drop in your runtime to any of the Commonware Library primitives. Want to employ _commonware-runtime_ in your own application? Confirm your application behaves deterministically using _commonware-runtime::deterministic::Auditor_. What is Deterministic Simulation and Why Does it Help? ------------------------------------------------------ Consider a not so uncommon test where 100 different agents send unique messages to each other. The way those messages are constructed (from external randomness, clocks, and storage) and the order that messages are sent has a significant impact on outcome. Sending a message before an agent is initialized means it is dropped. Delaying the delivery of a message until after some timeout leads to the sender being penalized. ![Controlling time and space with deterministic simulation](https://commonware.xyz/imgs/neo-deterministic.jpeg) What if you could control the order in which these agents interact and the external sources they depend on? With integrated deterministic simulation, you can run the same test with different sources of entropy to shuffle the order of agent execution (broadening exploration of the state space) and, critically, can reproduce any failing result (no more waiting for that random flake to occur again). Introducing Deterministic Simulation to _commonware-p2p_ -------------------------------------------------------- To demonstrate how to use _commonware-runtime_ (and for our own sanity), we upgraded _commonware-p2p_ to this new runtime. We can now deterministically simulate a collection of peers discovering each other and exchanging encrypted messages (from initialization to shutdown) all locally. In fact, we now run _commonware-p2p::authenticated_ connectivity tests (25 peers) with ~10 different seeds during each run of CI (leading to different sequences of peer discovery, message passing, and ultimately simulation termination). Basic unit testing is just the start of what we have planned for _commonware-runtime_. On the path to the production launch of the Commonware Library (and after), we will continuously test the stability of _commonware-p2p_ and _commonware-consensus_ with random topologies (honest/byzantine behavior, and network conditions) to ensure compatibility across versions and to test for regressions (as measured by observed bandwidth + number of steps required to complete). Here's to one less Saturday night spent debugging.🍻 _Want to help? Commonware is looking for a small group of founding engineers (1-10% equity). If you enjoy the never-ending challenge of building performant distributed systems, reach out to @commonwarexyz or hiring@commonware.xyz with a link to some of your most interesting work!_ Acknowledgements ---------------- Our love of deterministic simulation stems from [Will Wilson's (Antithesis) solution to Mario](https://www.youtube.com/watch?v=m3HwXlQPCEU) and [TigerBeetle's "Viewstamped Replication Made Famous" challenge](https://github.com/tigerbeetle/viewstamped-replication-made-famous) . Thanks to both for doing an incredible job explaining how advanced simulation leads to more reliable distributed systems. --- # commonware > Commonware: the Anti-Framework [+ ~ \- + \- + \- + \- ~ ~ \*\ \ \* commonware\ \ \* ~ + + ~ ~ \- \* \- \* \- +](https://commonware.xyz/index.html) Commonware: the Anti-Framework ============================== By [Patrick O'Grady](https://x.com/_patrickogrady) December 11, 2024 Today’s blockchain stack is designed to be a jack of all trades, but master of none. Modeled after virtual machines (VM) and kernels, it exposes a balanced interface through a one-size-fits-all framework instead of molding to the needs of any specific application. We built a new kind of stack for those spending their time working around this interface rather than leveraging it. With the support of Haun Ventures, Dragonfly Capital, and an experienced group of angels, we are excited to unveil [Commonware: the Anti-Framework](https://github.com/commonwarexyz/monorepo) . Outgrowing the Virtual Machine ------------------------------ Increasingly, the best builders spend their time working against the general-purpose abstractions provided by today’s blockchain stacks. ![Blockchain stacks are modeled after the kernel](https://commonware.xyz/imgs/kernel-vs-blockchain.png) Whether [incorporating sidecars and relayers](https://eips.ethereum.org/EIPS/eip-4337) to augment them or [breaking them altogether with a fork](https://github.com/celestiaorg/celestia-core/blob/v0.34.x-celestia/README.md) , using these interfaces to transform a crypto app into a great app rapidly veers off the “happy path” with only a few moderate feature requests: * Building an exchange and need to offer dedicated transaction gossip for market makers and power traders? * Launching a game and need to order transactions in a certain way to deter manipulation? * Generating tons of application data for a social network and want to employ a CDN to distribute data? * Shipping payments and need to modify the block format to make it easier for a user to verify their payment went through? * Simplifying onchain interactions and need to replace a user’s address with a native username? Much of what leading developers are building today isn’t unlocked with “more framework,” it is solved with less. Instead of building around more of the same blockspace, they want to ship insightful customizations that make sense for their users (and don’t for yours). Drop the Framework. It's Cleaner. --------------------------------- [We think](https://commonware.xyz/blogs/introducing-commonware.html) blockchain applications should be designed differently. Rather than prioritizing standardization and balanced performance across all applications, specialization should be our guide. We think the best developers can build better blockchain applications when they can pick-and-choose the right primitives for the right functions. Over the last few months, [we built a new type of “blockchain stack”](https://github.com/commonwarexyz/monorepo) designed from the ground up for those who aren’t getting what they need from the frameworks available today. This stack has no explicit layers. No specific security assumption. It is [neither monolithic nor modular](https://usa.visa.com/solutions/crypto/monolithic-vs-modular-blockchain.html) . There is no hardcoded block format, state layout, definition of finality, mempool policy, execution rules, nor fee metering. What we do provide is an open collection of “state-of-the-art” primitives that, while designed to work well together, can be rearranged, augmented, and even rebuilt (without forking everything). We call this growing collection of primitives “commonware”. ![Assemble commonware however you want](https://commonware.xyz/imgs/commonware-primitives.png) Just like there are no specific features an application must have, there is no specific set of primitives that must be used to create an application. You can build from scratch or even inject these primitives into an existing blockchain. Commonware: Now Including Consensus ----------------------------------- How far along are we? In early August, we released [p2p::authenticated](https://commonware.xyz/blogs/introducing-commonware.html) to provide authenticated and encrypted communication directly between public keys. In late August, we released [cryptography::bls12381](https://commonware.xyz/blogs/commonware-cryptography.html) (with DKG and Resharing Support) to unlock verifiable randomness, connectivity, and trusted access for users. In late September, we released [runtime::deterministic](https://commonware.xyz/blogs/commonware-runtime.html) to provide a foundation to deterministically test and optimize any primitive (internal or external). Today, we are excited to share our biggest release yet: [consensus::simplex](https://docs.rs/commonware-consensus) (our first consensus primitive). consensus::simplex provides Byzantine Fault Tolerant (BFT) agreement via a new construction inspired by [Simplex Consensus](https://eprint.iacr.org/2023/463) . Unlike other “off-the-shelf” consensus implementations, consensus::simplex is refreshingly minimal. It delivers simple agreement over opaque “blobs”. Functions that have historically motivated developers to create forks, like block broadcast and state sync, are abstracted as interfaces that can be externally implemented. Here are a few nice features: * **Fast Blocks and Optimal Finalization Latency:** Generate a new block after 2 network hops (propose -> notarize ->) and finalize a block after 3 network hops (propose -> notarize -> finalize ->) with authenticated multicast (implemented by p2p::authenticated). With an [average network latency](https://www.cloudping.co/grid/p_50/timeframe/1M) between participants of ~150ms, this would mean ~300ms block times and ~450ms finality. Faster network? It moves faster. * **Unrestricted Execution:** Deploy an existing execution environment (like [reth](https://github.com/paradigmxyz/reth) ) or develop something from scratch with your own blocks, transactions, and whatever else you come up with. Consensus runs over opaque hashes rather than some prescribed block format you must comply with. * **Externalized Uptime and Fault Proofs:** Track and slash validators defined on another blockchain (like an [AVS](https://app.eigenlayer.xyz/avs) ). Determine how and when validators are rewarded for participating in consensus. * **Decoupled Broadcast and Mempool:** Scale throughput with custom logic to propagate application data before, during, and after consensus. Use a proprietary algorithm or even employ the cloud. To maintain reliability, we run consensus::simplex through a suite of deterministic simulations on every commit. This suite enforces correct behavior during mock network partitions, Byzantine faults, slow/lossy link performance, and cluster-wide unclean shutdown. [With deterministic simulation](https://www.youtube.com/watch?v=m3HwXlQPCEU) , we can guarantee each simulation covers novel interactions (never running the same order of concurrent events) and yet fully-reproducible, even in a step-by-step debugger. As a result of this focus on testing, consensus::simplex has >90% coverage. You can see what it looks like to build with consensus::simplex in [examples::log](https://docs.rs/commonware-log) , p2p::authenticated in [examples::chat](https://docs.rs/commonware-chat) , and cryptography::bls12381 in [examples::vrf](https://docs.rs/commonware-vrf) . Accelerating Development: $9M Fundraise --------------------------------------- ![$9M Fundraise](https://commonware.xyz/imgs/commonware-raise.png) We’re excited to share that [Haun Ventures](https://www.haun.co/) and [Dragonfly Capital](https://www.dragonfly.xyz/) are co-leading a $9M investment in Commonware to accelerate our work and to equip us to better support the developers who leverage it. We are also fortunate to have the support of an experienced group of friends, mentors, and builders pushing the limit of what’s possible onchain: * [Mert Mumtaz (@0xMert\_)](https://x.com/0xMert_) * [Nick White (@nickwh8te)](https://x.com/nickwh8te) * [Viktor Bunin (@ViktorBunin)](https://x.com/viktorbunin) * [Sreeram Kannan (@sreeramkannan)](https://x.com/sreeramkannan) * [Andrew Huang (@KAndrewHuang)](https://x.com/kandrewhuang) * [Dan Romero (@dwr)](https://x.com/dwr) * [Smokey The Bera (@SmokeyTheBera)](https://x.com/smokeythebera) * [Kevin Sekniqi (@kevinsekniqi)](https://x.com/kevinsekniqi) * [Jonathan Claudius (@claudijd)](https://x.com/claudijd) * [Zaki Manian (@zmanian)](https://x.com/zmanian) * [Marko Baricevic (@MarkoBaricevic\_)](https://x.com/MarkoBaricevic_) * [Scott Sunarto (@smsunarto)](https://x.com/smsunarto) * [Felix Wilhelm (@\_fel1x)](https://x.com/_fel1x) * [Nemil Dalal (@nemild)](https://x.com/nemild) * [Jeff Schroeder (@SEJeff)](https://x.com/SEJeff) Going from 0 to 1 isn’t the same as going from 1 to 100. What makes it easy to deploy onchain at the start isn’t the same thing that allows you to push the frontier next. That’s what commonware is for. Let’s Build Something Together ------------------------------ If you can’t build what you want onchain, reach out to us at partners@commonware.xyz. We’re looking for 3 ambitious teams to collaborate with that want to leverage commonware to build unique applications across a variety of security configurations (L0, L1, L2, restaked security, or somewhere between). --- # commonware > Binding Timelock Encryption: Only Time Will Tell [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Binding Timelock Encryption: Only Time Will Tell ================================================ By [Patrick O'Grady](https://x.com/_patrickogrady) September 11, 2025 As your parents insisted when you were growing up, good things come to those who wait. It turns out recent advances in cryptography have proven them right. When competing head-to-head, revealing your move before your opponent gives them an obvious advantage. If I know you're playing rock, I'll play paper. Whether it's rock-paper-scissors or a keyword auction for search results, competitive applications need to hide submissions until everyone has committed. That's why they typically run on centralized infrastructure where moves can be blinded until resolution. Blockchains don't yet offer this "temporal privacy". Transactions are public the moment they hit the mempool. Look no further than the meteoric rise of MEV bots that monitor mempools, frontrun trades, and sandwich transactions to see the value of this information leakage. What if blockchains could run fair competitions? The Missing Primitive: Binding Timelock Encryption (BTLE) --------------------------------------------------------- Enter [Practical Timelock Encryption (TLE)](https://eprint.iacr.org/2023/189) . TLE lets you encrypt data that cannot be decrypted until a future moment (specifically, when validators generate a threshold signature over a known message). Once that signature exists, anyone can use it as a decryption key to reveal the encrypted data. Simply put, if you know the static public key of some threshold set and you know a message it will sign at some point, you can encrypt data that can be decrypted when a signature is generated over that message. It turns out we already have such a signature generation mechanism in the [Commonware Library](https://github.com/commonwarexyz/monorepo) : [threshold-simplex](https://docs.rs/commonware-consensus/latest/commonware_consensus/simplex/index.html) 's Verifiable Random Function (VRF). At each view (every ~200ms on a global network), validators produce a threshold signature over the view number (a message that can be known ahead of time by anyone looking for a timelock encryption target). TLE, a standalone cryptographic primitive, however, lacks the ability to enforce commitments to encrypted data. Nothing in the TLE scheme prevents a user from sharing different encrypted data to different people or encrypting updated data if they change their mind. Embedded into a blockchain, TLE commitments become "Binding Timelock Encryption" (BTLE). Submit an encrypted move before the end of a contest, and you can't back out or change your mind (your move is stored in state and can't be changed). Anyone possessing the VRF output associated with the end of the contest can decrypt the committed ciphertext. With BTLE, blockchains can finally offer temporal privacy. Good things (or fair contests onchain), as your parents said, come to those who wait (for timelock decryption). BATTLEWARE: Proving BTLE is Practical ------------------------------------- To demonstrate how to use Binding Timelock Encryption, we built [BATTLEWARE](https://battleware.xyz/) . BATTLEWARE is an onchain game where players duel each other to climb a global leaderboard (sorted by ELO score). If you've played Pokémon, you'll feel right at home. ![A battle between two trainers on BATTLEWARE](https://commonware.xyz/imgs/battleware-duel.png) Figure 1: A battle between two trainers on BATTLEWARE. The opponent (DEVOTE RITUAL) has locked their move for this round but we can't see it yet. It all starts when you submit a transaction to generate your "creature". The same signature generation mechanism used to power BTLE decryption doubles as the VRF used to randomly generate your creature's appearance, name, and moves. ![Creature generation process](https://commonware.xyz/imgs/creature-generation.png) Figure 2: A creature's traits are derived from the hash of your address, nonce, and a seed by the embedded VRF. The output of a VRF is only known after a block has been notarized (or nullified), so a player can't compute the outcome of the generation prior to their transaction's inclusion in a canonical block (under healthy network conditions). With a creature generated, you can enter the arena for matchmaking. Again using the same VRF, we randomly pair you with some other player (making it a bit more difficult to play yourself to boost your ELO). ![Matchmaking process](https://commonware.xyz/imgs/matchmaking.png) Figure 3: Players submit match requests onchain and after a configurable amount of time has passed or the arena is full, players are paired and battles started. Once in a battle, you have 15 rounds to defeat your opponent. During each round, both players submit moves encrypted to the view at which the current round will resolve (50 views after matching or the end of the previous round). Once that view is reached, either player can submit the VRF output to decrypt both players' moves and resolve the round. If a player has won, the battle resolves and each player's ELO score is updated. If not, the battle continues to the next round. ![Move submission and settlement](https://commonware.xyz/imgs/timelock-decryption.png) Figure 4: Any player can submit a settle transaction with the VRF output from the end of the round. To make decryption performant enough for BATTLEWARE, we perform parallel decryption of moves during execution using a BATTLEWARE-specific execution environment. The entire implementation is [open source](https://github.com/commonwarexyz/battleware) under both an MIT and Apache-2 license. The code is still a bit rough around the edges, but we were able to reach 77% test coverage (on ~11.2k lines of code). Consider it your opportunity to become a contributor. Securing Player Access ---------------------- Instead of trusting our API to provide access to game state, we opted to build a pipeline to provide visitors with authenticated access (like we did with [alto](https://alto.commonware.xyz/) ). The big difference here being that BATTLEWARE players need to verify state and events against consensus outputs (rather than just consensus outputs directly). To accomplish this, we inject state changes and execution events into our [ADBs](https://docs.rs/commonware-storage/latest/commonware_storage/adb/index.html) . We then use [consensus::aggregation](https://docs.rs/commonware-consensus/latest/commonware_consensus/aggregation/index.html) to generate a threshold signature over the computed roots of each ADB. Because execution relies on the output of a VRF not available during verification, we cannot just use the threshold signature emitted by threshold-simplex (unfortunately). ![MMR state management](https://commonware.xyz/imgs/threshold-roots.png) Figure 5: After execution, the State ADB and Events ADB is updated and once wrapped by a threshold signature are pushed to Exoware. Once a threshold signature is generated, validators then push these computed artifacts to [Exoware](https://exoware.xyz/) . On-the-fly, Exoware generates Multi-Proofs over the events that each websocket subscriber is interested in to save bandwidth (the events for your account or the battle you're in). ![Multi-proof generation](https://commonware.xyz/imgs/multi-proof.png) Figure 6: Instead of sending a full proof and all events for each block, Exoware dynamically generates Multi-Proofs over only the events that matter to the subscriber. These updates are processed by your browser where you both verify the threshold signature attesting to some set of roots was valid and that there exists a valid proof of your events in the provided root. Wrapping Things Up ------------------ At Commonware, [we believe that the best onchain experiences will develop a sustained edge through specialization](https://commonware.xyz/blogs/introducing-commonware.html) . Whether it a game, a trading application, a social network, or something only you know how to build, building a blockchain around a product provides differentiated capability that can't be bolted on to existing blockchains. We will (finally) have capacity to onboard our next Commonware design partner on October 1st. If you want to collaborate on a blockchain application that doesn't feel like one, reach out now (our next slot opens in 2026). --- # commonware > Fast Block Dissemination with Immediate Guarantees [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Fast Block Dissemination with Immediate Guarantees ================================================== By [Lucas Meier](https://x.com/cronokirby) November 4th, 2025 You can come to consensus over a mere fingerprint of the block—a hash for example— but doing anything interesting with that fingerprint, like processing transactions or updating state, requires disseminating (a lot of) data. We’ve invested some effort in this part of the [Commonware Library](https://github.com/commonwarexyz/monorepo) recently, and I’d like to share some fruits of that effort in this post. As an outline, we’ll cover: * data dissemination, naively, * how to increase efficiency with coding, * and, finally, how to get quicker guarantees about the data with [ZODA](https://eprint.iacr.org/2025/034) . ZODA is particularly exciting, because it achieves the guarantees of something like Reed-Solomon + KZG, without requiring a trusted setup, and while being more performant, and having less data transmission overhead. In a future post we will cover lower-level details of [our implementation](https://github.com/commonwarexyz/monorepo/blob/main/coding/src/zoda.rs) , like the field we use for Reed-Solomon coding, and the optimizations needed for fast fourier transforms, but this one will stick to an overview. Naive Dissemination ------------------- We assume a _leader_ has some data, DDD bytes worth, to be disseminated. They want mmm followers to receive it. The simplest approach is to have the leader send the data to every follower. The leader’s transmission cost is m⋅Dm \\cdot Dm⋅D bytes, and the followers’ cost is 000 bytes, since they send nothing. ![Figure 1: A leader transmits a block of data to 4 followers](https://commonware.xyz/imgs/zoda-000.png) Figure 1: A leader transmits a block of data to 4 followers Networked protocols are often bottlenecked by sending data, since moving bits around the planet, a country, or a building is hopelessly slow compared to moving it within an integrated circuit. Some back-of-the-napkin math: if our leader has a 1 Gb / s link, and needs to send a 1 MB block to 50 followers, we would expect this to take at least 400 ms, assuming no overhead at all in transmitting. The [commonware-estimator](https://docs.rs/commonware-estimator/latest/estimator/) can be used to test out [this example](https://github.com/commonwarexyz/monorepo/blob/main/examples/estimator/simplex_large_block.lazy) . This protocol is bottlenecked more so, with all of its communication going through the single leader node. While the leader sends the entire data mmm times, the followers sit idle, wasting their resources. We can do better. Towards Coding -------------- We want the followers to participate in sending the data as well. Imagine, after our naive protocol, that a follower crashes, losing their data. This is no big problem: the data is present among the other followers, and our lost node can communicate with them to recover it. In fact, every other node has all of the data, so you have more information than required on the network. If one node had one half of the data, and some other node the other half, you would still be able to recover it, by combining their halves. We could extend the logic further still: each of the mmm participants could hold 1m\\frac{1}{m}m1​ of the data. All together, the participants hold it all, distributed as thinly as possible. (They do still need to communicate to recover the data, of course, but it is recoverable). ![Figure 2: A leader splits data into 4 chunks, each sent to 1 follower](https://commonware.xyz/imgs/zoda-001.png) Figure 2: A leader splits data into 4 chunks, each sent to 1 follower In this case, the leader’s transmission cost is now just m⋅Dm\=Dm \\cdot \\frac{D}{m} = Dm⋅mD​\=D, quite the improvement. If the participants want to recover the whole data, each of them will need to send their shard to the others, at a cost of (m−1)⋅Dm(m - 1) \\cdot \\frac{D}{m}(m−1)⋅mD​ bytes. The total amount of data sent by the leader, and then the followers, is D+m⋅(m−1)Dm\=m⋅DD + m \\cdot \\frac{(m - 1) D}{m} = m \\cdot DD+m⋅m(m−1)D​\=m⋅D. Compared to the naive approach, the total amount of data sent is the same. However, it is sent much more efficiently, spreading the load evenly across all the links in the network. Each node sending (m−1)m⋅D\\frac{(m - 1)}{m} \\cdot Dm(m−1)​⋅D bytes worth of data to others can operate in parallel, whereas in the original case, the leader must send m⋅Dm \\cdot Dm⋅D bytes sequentially. ### Dealing with Loss One flaw in our scheme, so far, is that the data is spread so thinly, that even one node missing out results in it being lost completely. This might happen by accident—a node crashing is not impossible, after all— but we also want to tolerate malicious nodes. One follower being able to block transmission is not acceptable. From here, we reach to using a _coding scheme_. This scheme takes in a message of nnn _symbols_—we shall revisit the term, but think of it like a small, consistently sized piece of data, e.g. a byte—and produces m≥nm \\geq nm≥n symbols. A useful coding scheme has the property that given any nnn of these mmm symbols, we can recover the original message. As an example, a _Reed-Solomon_ code consists of treating the data as a list of nnn field elements (essentially, elements of some set where addition, multiplication, and division make sense) which define the polynomial: d(X)≔a0+a1X+⋯+an−1Xn−1 d(X) \\coloneqq a\_0 + a\_1 X + \\cdots + a\_{n - 1} X^{n - 1} d(X):\=a0​+a1​X+⋯+an−1​Xn−1 We can then consider the evaluation of this polynomial at mmm distinct points: d(ω0),d(ω1),…,d(ωm−1) d(\\omega\_0), d(\\omega\_1), \\ldots, d(\\omega\_{m - 1}) d(ω0​),d(ω1​),…,d(ωm−1​) as forming our encoded message. With some algebra, any nnn of these evaluations can be interpolated back into the original polynomial d(X)d(X)d(X), whose coefficients spell out our message. We have an implementation of this scheme [here](https://github.com/commonwarexyz/monorepo/blob/main/coding/src/reed_solomon/mod.rs) . These details are not essential: what matters is that we take nnn symbols, encode them into mmm, such that any nnn of the encoded symbols are good enough to recover the originals. ### Dissemination with Coding This naturally suggests a scheme in which followers receive encoded symbols, allowing recovery with partial information. To flesh this out further, we want to accommodate data which may not consist of precisely nnn symbols. Instead, we assume a matrix of n×cn \\times cn×c symbols (which may be padded). This matrix can be encoded columnwise, producing a result of size m×cm \\times cm×c. Each shard can be a row of this matrix. Given nnn shards, the original matrix can be recovered, proceeding columnwise once more. ![Figure 3: Data is encoded, growing from 2 pieces into 4, and split across the followers](https://commonware.xyz/imgs/zoda-002.png) Figure 3: Data is encoded, growing from 2 pieces into 4, and split across the followers The cost of this scheme is now: - m⋅Dnm \\cdot \\frac{D}{n}m⋅nD​ for the leader, - (m−1)⋅Dn(m - 1) \\cdot \\frac{D}{n}(m−1)⋅nD​ for each follower, - m2n⋅D\\frac{m^2}{n} \\cdot Dnm2​⋅D in total. As the redundancy decreases, with m→nm \\to nm→n, we get the same cost as before. We want some redundancy though, with m≫nm \\gg nm≫n, so the total cost will be _higher_ than before. Nevertheless, it is distributed far more fairly than the naive case, so we should expect data to be disseminated more quickly all else being equal. Integrity --------- We’ve described coding schemes as being able to tolerate erasure: missing pieces of data. This fits naturally in the model of crash faults: if a node crashes, their piece is lost, but we can tolerate this. What do we do in the case of malicious faults, where data is intentionally changed, rather than merely omitted? Some coding schemes can tolerate random errors. For example, bit flips, or adding a random field element. Unfortunately, this comes at the cost of at least doubling the amount of redundancy in order to correct the same number of errors. There’s also a significant jump in algorithmic complexity, mathematically, and cognitively, to the point where implementations often don’t contain procedures for decoding with errors at all. To avoid the need to correct errors, we can use a trick: instead of decoding with bad shards, we could detect that they’ve been corrupted, and treat them as missing instead. If the followers received a hash of each shard, then they could tell whether some data is actually the shard it claims to be, by hashing it. This comes at a penalty of transmitting m⋅2λm \\cdot 2^\\lambdam⋅2λ bits of data (guaranteeing no collisions up to a probability of 2−λ2^-\\lambda2−λ requires 2λ2 \\lambda2λ bit hashes). We can improve this a bit by having the leader use a vector commitment over the mmm hashes. Each shard would then come with an opening, demonstrating that the iiith hash in the vector is that of the shard. A binary Merkle Tree is an example of such a scheme (but others might work better, e.g. playing with arity, or using a Polynomial Commitment Scheme). ![Figure 4: The encoded rows are hashed into a tree](https://commonware.xyz/imgs/zoda-003.png) Figure 4: The encoded rows are hashed into a tree As a side-effect, our scheme now produces a fingerprint, attesting uniquely to the encoded data. This could be used for consensus, like the hash of the data itself often is. ### Bad Leaders So far, our leader encodes the data into shards, distributes them, and given a large enough subset of them, we can recover the data. We also know that a malicious follower cannot tamper with the data, because they must prove that their shard is what the leader committed to. But, what if the leader is malicious? What if instead of encoding data into shards, they simply made the shards up themselves? In that case, honest followers might successfully reconstruct something, but each of them sees a different result, based on the particular shards they chose to use. It’s also easy to get different honest followers to pick different shards, by selectively withholding them. Proceeding with different data is very bad, so we want to avoid this. Something we can do is to check that re-encoding the data produces what the leader claimed. If encoding is: - _deterministic_, producing, always, the same result, - _injective_, with different data producing different results, then this works out. A malicious leader shares one commitment, and there can be at most one original piece of data that commits to that value. One drawback is that now we can only know that the data exists _after_ we’ve reconstructed it. If we’re tying this process to consensus, it would be nice to avoid coming to agreement on a piece of data which will turn out to never have existed, producing an empty block. There’s also, more plainly, a cost to re-encoding, which it might be nice to avoid. ZODA ---- At a high level, [ZODA](https://eprint.iacr.org/2025/034) allows us to avoid this issue. We can be convinced that our shard comes from a valid encoding of some unique piece of data, as soon as we receive our shard. (For ZODA afficionados, what we describe subsequently is the application of the “Hadamard” variant from section D of the paper). This involves sending, along with the shard, some additional data, of use not in recovering it, but in providing assurance that our shard results from an encoding of it. ### Some Details and Intuition The inner workings of the protocol are not necessary to understand its utility nor application, but are simple enough to be understood at a high level of operation. We continue in modelling our data, XXX, as a matrix of dimension n×cn \\times cn×c, with elements in some field FFF. We can encode it, using a matrix GGG of dimension m×nm \\times nm×n, producing Y≔GXY \\coloneqq G XY:\=GX, of dimension m×cm \\times cm×c. The rows of YYY are committed to, and this commitment can serve as a source of randomness in what follows, according to the _Fiat-Shamir_ paradigm. Whereas in the plain coding scheme, we received one particular row of YYY, here we receive SSS rows, sampled at random. (We may modify mmm and nnn to accomodate this fact). We also receive proofs of inclusion for each row. In order to convince us that our rows YSY\_SYS​ came from GXG XGX, a random matrix HHH of dimension c×S′c \\times S'c×S′ is sampled from a (potentially) larger field F′⊇FF' \\supseteq FF′⊇F. Then, we are given Z≔XHZ \\coloneqq X HZ:\=XH, of dimension n×S′n \\times S'n×S′. Because encoding is linear, we can check that: YSH\=?(GZ)S Y\_S H \\overset{?}{=} (G Z)\_S YS​H\=?(GZ)S​ which should hold for an honest encoder, since: G(XH)\=(GX)H G (X H) = (G X) H G(XH)\=(GX)H for any matrices GGG, XXX, HHH. ### Some Intuition You can show, as the paper does, that given enough samples SSS, S′S'S′, and a large enough F′F'F′, any desirable level of security can be achieved. We can, however, reason intuitively about why this might work. For a given row YiY\_iYi​, checking: (YiH)j\=?(GZ)ij (Y\_i H)\_j \\overset{?}{=} (G Z)\_{i j} (Yi​H)j​\=?(GZ)ij​ is the same as checking that a random linear combination of (alleged) encoded symbols is equal to GxG xGx, for some symbol xxx. In other words, that this combination is an encoded symbol. This is true if YiY\_iYi​ is correct, and likely to be false if not. By sampling S′S'S′ check columns, we perform this check many times, with different randomness, making it more likely to be false for a fake encoding. Furthermore, by sampling SSS rows at random, rather than having a row assigned to use by the leader, we make it very difficult to find some clever data which will slip through our checks, since the cheater will not know where they need to fake the outcome. ### Completing the Protocol To complete the sketch of the protocol let’s look at how we handle the shards, collectively. Rather than have each follower sample SSS rows at random, we instead shuffle the rows, and partition it into chunks of size SSS. This guarantees no overlap between shards, while still giving us the randomness to convince us of a valid encoding. When receiving shards, we check inclusion, and that: YSH\=?(GZ)S Y\_S H \\overset{?}{=} (G Z)\_S YS​H\=?(GZ)S​ as for our own shard. Comparisons with KZG -------------------- Another approach to verifiable dissemination is to lean into Polynomial Commitment Schemes. This is, in essence, how [Danksharding](https://ethereum.org/roadmap/danksharding/) works. In the case of Reed-Solomon coding, each shard is the evaluation of some polynomial d(X)d(X)d(X) at a given point. The problem of checking that our shard is an evaluation of a claimed polynomial is exactly that solved by a PCS. Such a scheme produces a succinct commitment to d(X)d(X)d(X), such that we can also prove that some data is the result of evaluating d(X)d(X)d(X) at a given point, which is what we need. The [ZODA paper](https://eprint.iacr.org/2025/034) has some comparison numbers with such a scheme, using KZG commitments, but they should be taken with a fairly large grain of salt, since they analyze things from a data availability stand point, where you have a large number of samplers (around 1000), with a rate (i.e. n/mn / mn/m) of 1/21/21/2. For the use-case of data dissemination, you’d likely have fewer nodes (around 100, or however many validators you have), with a higher rate (something like 2/32/32/3, allowing you to recover if byzantine validators omit their shards). Nonetheless, you can compare the claimed performance for different data sizes. For each scheme, the original block size, the size of each shard, and the total size of all shards is reported. The inefficiency—how much data is needed compared to just sending all of the data naively–is also reported. | Block size | ZODA Node | ZODA Network | Zoda Inef. | 2D KZG Row/Col Node | 2D KZG Row/Col Net. | 2D KZG Row/Col Inef. | | --- | --- | --- | --- | --- | --- | --- | | 32MiB | 1.04 MiB | 72 MiB | 2.3x | 12 MiB | 271 MiB | 8.5 | | 256MiB | 2.84 MiB | 560 MiB | 2.2x | 35 MiB | 2.0 GiB | 8.2 | | 1GiB | 7.68 MiB | 2.1 GiB | 2.1x | 70 MiB | 8.1 GiB | 8.2 | | 32GiB | 43.2 MiB | 66 GiB | 2.1x | 394 MiB | 258 GiB | 8.1 | | 1TiB | 244 MiB | 2.1 TiB | 2.1x | 2.2 GiB | 8.1 TiB | 8.1 | In any case, we can see a claimed improvement in the context of Data Availability, and we should expect this to extend to our slightly different use-case of data dissemination. Another factor in the cost of KZG is that it requires many operations over a _group_ (in this case, an elliptic curve) which is at least an order of magnitude more expensive than a field operation. ZODA, on the other hand, performs only field operations, and inexpensive hashing. We should also expect the _latency_ to be improved as well, requiring less time to compute the checking data for the shards. Summary ------- A leader wants to send some data to followers. In the naive case, the leader simply sends all of the data to everyone. To optimize distribution, we encode the data into shards, with each follower receiving one shard. The data can be recovered from a subset of shards. The leader commits to the shards, so that we can easily check if purported shards actually belong. Unfortunately, we can’t know if the data is uniquely recoverable until re-assembling it, and re-encoding it to see if it matches our commitment. [ZODA](https://eprint.iacr.org/2025/034) alleviates this by guaranteeing that a shard originates from a valid encoding of the data, by adding additional checksums to each shard. Some more advanced schemes, like [Ligerito](https://eprint.iacr.org/2025/1187) can pave the way for verifying arbitrary properties of the sharded data, which we’re excited about. Our initial implementation of this scheme can be found [in the Commonware Library](https://github.com/commonwarexyz/monorepo/blob/main/coding/src/zoda.rs) . Looking to develop a better intuition for ZODA? Check out our [podcast](https://www.youtube.com/watch?v=eOGQOaqvgnI) with [Guillermo Angeris](https://x.com/GuilleAngeris) and [Alex Evans](https://x.com/alexhevans) from [Bain Capital Crypto](https://baincapitalcrypto.com/) . --- # commonware > Minimmit: Fast Finality with Even Faster Blocks [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Minimmit: Fast Finality with Even Faster Blocks =============================================== By [Patrick O'Grady](https://x.com/_patrickogrady) and [Brendan Chou](https://x.com/B_Chou) June 24, 2025 _Update(8/14/2025): A formal specification of Minimmit and a proof of its correctness is now published on [arXiv](https://arxiv.org/abs/2508.10862) ._ Over the last few months, there has been renewed interest in developing _propose-and-vote_ consensus protocols that reach finality after just one round of voting (~100-200ms). "Two-Phase" protocols, not without tradeoff, only remain safe if a Byzantine adversary controls less than _~20%_ of stake (rather than the _~33%_ tolerance typically considered). Concerned primarily with addressing this drop in fault tolerance, recent constructions propose augmenting Byzantine fault tolerance with crash fault tolerance to retain some path to finality under a "blended" _~33%_ assumption. Minimmit, a new _propose-and-vote_ construction below, optimizes for a different goal: minimizing block time. ![Phase Comparison](https://commonware.xyz/imgs/phase-comparison.png) Figure 1: Two-Phase protocols commit after just one round of voting. Background ---------- In March, Matter Labs released [ChonkyBFT: Consensus Protocol of ZKsync](https://arxiv.org/abs/2503.15380) . In May, Offchain Labs released [Kudzu: Fast and Simple High-Throughput BFT](https://arxiv.org/abs/2505.08771) and Anza Labs released [Alpenglow](https://www.anza.xyz/blog/alpenglow-a-new-consensus-for-solana) at [Solana Accelerate](https://youtu.be/x1sxtm-dvyE?) . And just a few days ago, Supra Research and Espresso Systems released [Hydrangea: A Fast and Simple Consensus Protocol for High-Throughput Blockchains](https://eprint.iacr.org/2025/1112) . All capable of _propose-and-vote_ confirmation in ~100-200ms, this cohort of new constructions primarily differs in the technique employed to finalize blocks if faults exceed _~20%_ of stake (when comprised of at most _f_ Byzantine faults **and** _p_ crash faults). Finalizing quickly via some "fast path" when replicas are honest and online, these constructions fallback to a "slow path" that resembles the "Three-Phase" protocols commonly deployed today. ![Alpenglow Fallback](https://commonware.xyz/imgs/alpenglow-fallback.png) Figure 2: Alpenglow supports a "slow-finalization" path ([source](https://drive.google.com/file/d/1y_7ddr8oNOknTQYHzXeeMD2ProQ0WjMs/view) ). Minimmit: Fast Finality with Even Faster Blocks ----------------------------------------------- Today, we are excited to share a different take on _propose-and-vote_ consensus: [Minimmit: Fast Finality with Even Faster Blocks](https://github.com/commonwarexyz/monorepo/tree/main/pipeline/minimmit/minimmit.md) . Like the constructions above, Minimmit delivers minimal confirmation latency under the _~20%_ Byzantine fault assumption. Unlike those constructions, however, it optimizes for view latency instead of _f+_ confirmation robustness. In an [alto-like configuration](https://alto.commonware.xyz/) (with 50 uniformly distributed validators), we expect a Minimmit-powered blockchain to reach 130ms block time and 250ms finality. In a regionally-biased configuration, we expect Minimmit to deliver 50ms block time and 100ms finality. ![Faster Blocks](https://commonware.xyz/imgs/faster-blocks.png) Figure 3: On a real network, messages can arrive at very different times and advancing to the next view after observing a _40%_ quorum can be much faster than observing an _80%_ quorum. While not yet peer-reviewed or fully implemented, we are releasing Minimmit under both an MIT and Apache-2 license for others to build with and build upon. Below, we provide a high-level summary of the specification and share some intuition about its correctness: 1\. Introduction ---------------- Minimmit is a responsive, leader-based consensus protocol designed for simplicity and speed, tolerant of a Byzantine adversary that controls fewer than `20%` of replicas. Minimmit advances to the next view when a `40%` quorum is reached and finalizes blocks when an `80%` quorum is reached (after only a single round of voting). Minimmit can be instantiated with a number of practical optimizations to improve performance when deployed in production. 2\. Model & Parameters ---------------------- * Byzantine replicas: `≤ f` * Total replicas: `n ≥ 5f + 1` * Partial synchrony: every message arrives within `Δ` after an unknown global stabilization time (GST). 3\. Quorums ----------- * `L = n - 3f` (`2f + 1`) * `Q = n - f` (`4f + 1`) _There exists `≥ 1` honest replica in any `Q`\-set and `L`\-set intersection._ 4\. Message Types ----------------- | Message | Purpose | | --- | --- | | `genesis` | The genesis block. | | `propose(c, v, (c', v'))` | Leader's proposal `c` for view `v` with parent `c'` in view `v'`. | | `notarize(c, v)` | Vote to finalize block `c` in view `v`. | | `nullify(v)` | Vote to advance to view `v + 1`. | | `notarization(c, v)` | Certificate of ≥ `L` `notarize(c, v)` messages for `(c, v)`. | | `nullification(v)` | Certificate of ≥ `L` `nullify(v)` messages for view `v`. | | `proof(v)` | Either a `notarization(*, v)` or a `nullification(v)` certificate. | 5\. Initial Replica State ------------------------- view = 0 notarized = ⊥ # the proposal this replica has notarized nullified = false # whether this replica has nullified this view timer = None # time until nullify if not yet nullified or notarized messages = [] # list of messages this replica has seen proofs = [] # list of proofs this replica has collected 6\. External Functions ---------------------- // Select the leader for view `v` fn leader(v) -> L; // Build a block on top of `c'`. This should pass `verify(c, c')`. fn build(c') -> c; // Verify whether `c` is valid given the parent `c'`. Anything produced by // `build(c')` should pass `verify(c, c')`. fn verify(c, c') -> bool; 7\. Helpers ----------- // Find a valid parent to build on fn select_parent(v) -> (c', v') { let i = v - 1; while i >= 0 { if notarization(c', i) ∈ proofs[i] { // If there are multiple, pick any. return (c', i); } if nullification(i) ∈ proofs[i] { i -= 1; continue; } return ⊥; } return genesis; } // Ensure there are proofs for all views between `v` and `v'` fn valid_parent(v, (c', v')) -> bool { let i = v - 1; while i > v' { if nullification(i) ∈ proofs[i] { i -= 1; continue; } return false; } return notarization(c', v') ∈ proofs[v'] } // Enter view `next` fn enter_view(next) { if view >= next { return; } view = next; notarized = ⊥; nullified = false; timer = 2Δ; } // Record a message from a `replica` fn record_message(replica, message) -> bool { if replica ∉ messages[message.view] { messages[message.view][replica] = []; } if message ∉ messages[message.view][replica] { messages[message.view][replica].add(message); return true; } return false; } // Prune data less than `view` fn prune(view) { messages.remove(m => m.view < view); proofs.remove(p => p.view < view); } 8\. Protocol for View `v` ------------------------- ### 8.1. Propose _If the leader, propose._ 1. Upon entering view `v`, if identity is equal to `leader(v)`: 1. `(c', v') = select_parent(v)` (if `⊥`, return). 2. `c = build(c')`. 3. `notarized = c`. 4. Broadcast `propose(c, v, (c', v'))`. _Treat `propose(c, v, (c', v'))` as a leader `l`'s `notarize(c, v)`._ ### 8.2. Notarize _Upon receipt of a first valid block proposal from leader, broadcast `notarize(c, v)`._ 1. On receiving first `propose(c, v, (c', v'))` from `leader(v)`: 1. If `notarized != ⊥` or `nullified`, return. 2. If `!valid_parent(v, (c', v'))`, return. 3. If `!verify(c, c')`, return. 4. `notarized = c`. 5. Broadcast `notarize(c, v)`. ### 8.3. Nullify by Timeout _If `timer` expires, broadcast `nullify(v)` if not yet broadcasted `notarize(c, v)`._ 1. On `timer` expiry: 1. If `notarized != ⊥` or `nullified`, return. 2. `nullified = true`. 3. Broadcast `nullify(v)`. ### 8.4. Notarization & Finalization _After `L` messages, create and broadcast a `notarization(c, v)` certificate. After `Q` messages, finalize._ 1. On receiving `notarize(c, v)` from replica `r`: 1. If `!record_message(r, notarize(c, v))`, return. 2. On observing `≥ L` `notarize(c, v)` messages: 1. Assemble `notarization(c, v)`. 2. Add `notarization(c, v)` to `proofs`. 3. Broadcast `notarization(c, v)`. 4. `enter_view(v + 1)`. 3. On observing `≥ Q` `notarize(c, v)` messages: 1. Finalize `c` and all of its ancestors. 2. `prune(v)`. ### 8.5. Nullification _After `L` messages, create and broadcast a `nullification(v)` certificate._ 1. On receiving `nullify(v)` from replica `r`: 1. If `!record_message(r, nullify(v))`, return. 2. On observing `≥ L` `nullify(v)` messages (or a single `nullification(v)` message): 1. Assemble `nullification(v)`. 2. Add `nullification(v)` to `proofs`. 3. Broadcast `nullification(v)`. 4. `enter_view(v + 1)`. ### 8.6 Nullify by Contradiction _If you have already broadcast `notarize(c, v)` for a `c` that cannot be finalized directly, broadcast `nullify(v)` to ensure some `proof(v)` will exist in view `v`._ 1. On observing messages from `≥ L` replicas of either `nullify(v)` or `notarize(*, v)` (where `notarized != ⊥` and `notarized != *`): 1. `nullified = true`. 2. Broadcast `nullify(v)`. 9\. Intuition ------------- ### 9.1 General * A leader selected in `v + 1` may propose any block `c` that extends some known `notarization(c', v')` as long as there exist `nullification(j)` proofs for all views in `(v', v]`. Notably, this means that leaders are never required to re-propose a block from an earlier view and can only skip some block proposed in an earlier view `v` if there exists some `nullification(v)`. ### 9.2 Safety * Honest replicas may not broadcast a `notarize(c, v)` after first broadcasting a `nullify(v)`. * Honest replicas may broadcast a `nullify(v)` after first broadcasting a `notarize(c, v)`. * To broadcast both a `notarize(c, v)` and a `nullify(v)` message, a replica must first see that it is impossible for the proposal that it notarized to reach a quorum of `Q` `notarize(c, v)` messages. Otherwise, the replica is forbidden from broadcasting `nullify(v)`, no matter how much time has passed. * A replica knows it is impossible for its notarized proposal `c` to reach the finalization quorum `Q` once it has observed `L` other replicas that conflict. A conflicting replica has broadcast either a `nullify(v)` message or a `notarize(*, v)` message for a different proposal `*`. * If a replica has seen `L` conflicting votes, at least `L - f` (i.e. `f + 1`) are from honest replicas. Therefore, the maximum number of `notarize(c, v)` it can receive is `n - (f + 1)`, or `4f` (strictly less than `Q`). * Suppose a correct leader broadcasts a block `c` and, after honest replicas broadcast `notarize(c, v)`, message delivery is disrupted, preventing any replica from receiving `L` such messages. In this state, replicas have locked on `c` for view `v` and cannot broadcast some `nullify(v)`. Progress is stalled until network conditions improve, allowing a `notarization(c, v)` to be assembled, which in turn allows replicas to enter view `v + 1`. * In any given view `v`, there may be multiple `notarization(*, v)` messages and one `nullification(v)`. If there are multiple `notarization(*, v)`s, no block `*` referenced by a `notarization(*, v)` can be finalized in `v`. If there exists some `nullification(v)`, no block can be finalized in `v`. ### 9.3 Liveness * There exists at least one `proof(v)` for every view `v`. * After GST, all views with honest leaders will emit a `notarization` message before the timer of any honest replica expires. To see this is true, consider the following: * The first honest replica broadcasts some `proof(v - 1)` message to all replicas and enters view `v` at time `t_0`. * The leader of view `v` will receive said `proof(v - 1)` message by `t_0 + Δ` and broadcast some `propose(c, v, (c', v'))` message to all replicas. * All honest replicas will receive said `propose(c, v, (c', v'))` message by `t_0 + 2Δ` and broadcast some `notarize(c, v)` message. * Replicas enter `v + 1` as soon as they see some `proof(v)` (as fast as `L` messages). If the network is partitioned in two, replicas in each half of the partition may continue to enter successive views (on different `proof(v)`s) but will never finalize conflicting blocks. To bound the depth of forks in a partition, replicas can wait to enter some view `v + k` until they have seen `Q` messages in view `v`. * A Byzantine leader could equivocate, sending a distinct proposal to each replica and causing them to broadcast a `notarize(*, v)` for different blocks. After a replica observes `≥ L` `notarize(*, v)` messages for some `* != c`, it will then choose to broadcast a `nullify(v)` message. Eventually, `L` `nullify(v)` messages will be received and honest replicas will enter `v + 1` (within `Δ` of the first honest replica). * Since at most `f` nodes are Byzantine or faulty, once an honest leader is assigned, it is possible for at least `Q` correct replicas to finalize a block (including all of its ancestors). 10\. Extensions --------------- Minimmit can be instantiated in several different ways to tune performance when deployed to production. Some examples are below: * Use block digests (i.e. `c = hash(block)`) in `propose(c, v, (c', v'))`, `notarize(c, v)`, and `notarization(c, v)` messages. * Employ BLS multi-signatures or BLS threshold signatures, like [Threshold Simplex](https://docs.rs/commonware-consensus/latest/commonware_consensus/simplex/index.html) , to cap `notarization(c, v)` and `nullification(v)` messages at a constant size regardless of the number of replicas. * Attach some recent set of `proof(v)` messages to each `propose(c, v, (c', v'))` message (to ensure honest replicas that are not yet aware of recent proofs can still broadcast a `notarize(c, v)` message for valid blocks). * If `≥ f + 1` `notarize(c, v)` messages are observed for some `proposal(c, v, (c', v'))` considered invalid, request the missing `notarization(c, v')` or `nullification(v')` not found in our `proofs` (that prohibited us from broadcasting a `notarize(c, v)`) from the peers that consider it valid. * If stuck in the same view `v` for time `t_s`, re-broadcast some `proof(v - 1)` (to ensure all correct replicas enter `v`) and re-broadcast `notarized` (if not `⊥`) and `nullified` (if not `false`). * Assemble and broadcast a `finalization(c, v)` message after finalizing some `c` (i.e. `≥ Q` `notarize(c, v)` messages). This can both help lagging replicas catch up to the finalized tip and make it easier for downstream services to integrate. * Disseminate blocks using `(k,d)`\-erasure codes, like [DispersedSimplex](https://eprint.iacr.org/2023/1916) , [Kudzu](https://arxiv.org/abs/2505.08771) , and [Alpenglow](https://drive.google.com/file/d/1y_7ddr8oNOknTQYHzXeeMD2ProQ0WjMs/view) , to avoid a leader broadcast bottleneck. Each `notarize` message would be augmented with the relevant fragment. `k` would be set to the number of replicas, and `d` can be set as `f+1` so that the replicas only have a bandwidth requirement of about ~5 times the size of the full block. If a `notarization` exists, then at least `f+1` honest nodes have been distributed a fragment. This prevents `Byzantine` nodes from constructing a `notarization` without honest nodes being able to reconstruct the block among themselves. `d` can be set at higher values like `2f+1` to halve the required bandwidth, but replicas would have to ignore any gossiped `notarization` messages, instead making sure to gather the `2f+1` `notarize` messages themselves. * To punish equivocating leaders, treat `propose` messages for different blocks in the same view as a slashable offense. To incentivize performant leaders, issue a reward for any block `c` included in the canonical chain. Have an idea to simplify, improve, or extend Minimmit? [Open a PR](https://github.com/commonwarexyz/monorepo/tree/main/pipeline/minimmit/minimmit.md) or reach out at [minimmit@commonware.xyz](mailto:minimmit@commonware.xyz) . --- # commonware > Once a Validator, Not Always a Validator [+ ~ \- + \- + \- + \- ~ ~ \*\ \ | commonware\ \ \* ~ + + \- ~ \- + \- \* \- +](https://commonware.xyz/index.html) Once a Validator, Not Always a Validator ======================================== By [Ben Clabby](https://x.com/vex_0x) and [Patrick O'Grady](https://x.com/_patrickogrady) October 31, 2025 Many consensus protocols, from [Tendermint](https://arxiv.org/abs/1807.04938) and [HotStuff](https://arxiv.org/abs/1803.05069) to our own [Minimmit](https://arxiv.org/abs/2508.10862) , are defined under a "permissioned" model where the validator set is fixed and known ahead of time by all participants. Safely transitioning from one committee to the next, where validators can be added and removed, is left as an exercise to the implementer. Tendermint-style protocols make the transition straightforward: replicas only start voting on height `h + 1` once height `h` is finalized, so modifying the validator set between heights is safe. New faster-than-finality protocols (i.e. `commonware-consensus::simplex`), however, begin casting votes for the next height immediately after the previous height is notarized (when 2f+1 `PREVOTE`s exist but before 2f+1 `PRECOMMIT`s exist, in [Tendermint parlance](https://decentralizedthoughts.github.io/2025-06-18-simplex/) ). While this approach minimizes block time (and thus transaction confirmation latency), it complicates reconfiguration because there is no point at which validators have a synchronized view of the finalized tip. If validators use their "local view" of the finalized tip to determine who is eligible to notarize a block, the network risks a halt or a safety failure (as participants may consider votes from different validators to be useless). What do? [From Permissioned to Proof-of-Stake Consensus](https://arxiv.org/pdf/2506.14124) —a new paper by Jovan Komatovic, Andrew Lewis-Pye, Joachim Neu, Tim Roughgarden, and Ertem Nusret Tas—offers an elegant, consensus-agnostic solution. Treat the replicated log (i.e. the blockchain) as a sequence of segments broken into epochs where we simply "ignore" blocks that exceed some configured epoch length, whether finalized or not. Practically speaking, the validator enters a new epoch as soon as they process a finalized block at the epoch boundary (entering the next epoch with a synchronized view of the finalized state where they can update the validator set safely). ![Epoching](https://commonware.xyz/imgs/epoching.png) Figure 1: After some configurable number of blocks is finalized, a new epoch begins. If more blocks than desired are finalized, they are dropped. Epochs require direct finalization of the last block to advance. If this hasn't happened yet, we re-propose the same block. The last block of some epoch is treated as the genesis block of the next epoch. To avoid reinventing the wheel each time a new consensus protocol is added to the Commonware Library, we opted to implement this reusable technique. This means you can now implement any permissioned consensus protocol, as described, and not worry about how to uniquely extend it for reconfiguration (including not having to implement mechanisms required to synchronize missing blocks across epochs, update peer sets, etc.). Check out [`commonware-reshare`](https://github.com/commonwarexyz/monorepo/tree/main/examples/reshare) for a concrete example of how to incorporate reconfiguration into your application. Resharing: Piggybacking on Consensus ------------------------------------ When maintaining a threshold secret, changing the validator set requires more than updating a list. Whenever participants are added or removed, a new dealing of the secret must be performed to ensure new participants receive a share to participate in consensus and existing participants can't use multiple shares from old epochs to induce a safety failure (i.e. each player must not be able to use shares across dealings or else it is trivial for a single malicious participant to acquire _f_ shares over _f_ epochs). Our original [`commonware-vrf`](https://github.com/commonwarexyz/monorepo/tree/main/examples/vrf) demonstrated how to perform proactive resharing but relied on a trusted [Arbiter](https://docs.rs/commonware-cryptography/latest/commonware_cryptography/bls12381/dkg/arbiter/struct.Arbiter.html) to ensure all participants received the same set of commitments. Removing that trusted coordinator requires some form of reliable broadcast such that all participants can each run their own arbiter (and all arrive at the same output). Fortunately, we get that out-of-the-box with a replicated log. Our new [`commonware-reshare`](https://github.com/commonwarexyz/monorepo/tree/main/examples/reshare) example marries the DKG implementation from [`commonware-cryptography::bls12381::dkg`](https://docs.rs/commonware-cryptography/latest/commonware_cryptography/bls12381/dkg/index.html) with threshold `commonware-consensus::simplex`'s (implicit) replicated log. Validators proactively refresh their key material every epoch, a configurable interval of blocks, and derive new shares for incoming participants. Each epoch begins with a set of **dealers**, the validators currently signing blocks, and **players**, the validators who will hold shares in the next epoch. Dealers generate shares for all new players (based on their share from the current epoch to maintain the same shared secret across epochs) and send them to players over [`commonware-p2p::authenticated`](https://docs.rs/commonware-p2p/latest/commonware_p2p/authenticated/index.html) 's encrypted, point-to-point channels. Players validate the received shares and, if correct, send acknowledgements back to dealers. After some number of blocks, dealers construct an outcome containing their commitment, acknowledgements from players who received shares against that commitment, and any revealed secret shares for players that didn't acknowledge receipt. They publish that outcome to the log. ![Actor Interactions](https://commonware.xyz/imgs/reshare_actors.png) Figure 2: Dealers and Players interact with each other and the replicated log to derive the new shares and group polynomial. At the epoch boundary, all participants derive a new group polynomial from the submitted commitments and a share they can use to participate in the next epoch from the selected dealings. Because `commonware-consensus::simplex` already ensures all participants see the same log, we know all participants will derive the same group polynomial and a correct share that can be used to participate. Generating a Threshold Secret ----------------------------- The example ships with two bootstrap strategies. A trusted participant can derive all shares for the initial set of participants, or the validators can run a one-time DKG ceremony to generate the initial shares collectively (where no participant ever has full knowledge of the secret). ![DKG bootstrap](https://commonware.xyz/imgs/dkg_bootstrap.png) Figure 3: The DKG ceremony is performed once, and the resulting shares are used to bootstrap the initial epoch. The trusted path is great for local testing and CI: the setup tool deterministically samples the group key, splits it into shares, and writes configs for each validator. The DKG ceremony is more complex but should be used for any production deployment (recall whoever has the shared secret can trivially undermine threshold `commonware-consensus::simplex`). A bootstrap committee uses the non-threshold dialect of `commonware-consensus::simplex` (powered by `commonware-cryptography::ed25519`) to agree on the transcript produced by `commonware-cryptography::bls12381::dkg`, and the generated shares are used by the initial participants in the first epoch. From there, the built-in resharing mechanism handles all future key material updates. With an end-to-end solution for bootstrapping and maintaining a threshold secret over a dynamic validator set, the road is now paved for integrating [Seeds, Links, and Views](https://commonware.xyz/blogs/commonware-cryptography.html) into applications building on the Commonware Library. Trying It Locally ----------------- You can run the example by generating participant configurations and launching the validators with the command emitted by the setup step: $ git clone git@github.com:commonwarexyz/monorepo.git && cd monorepo # Trusted Setup $ cargo run --bin commonware-reshare setup # DKG Setup $ cargo run --bin commonware-reshare setup --with-dkg # Execute the `mprocs` command(s) emitted by the previous step The setup step writes per-validator configuration files under the chosen `--datadir` (default `./data`) and prints one or two `mprocs` invocations. For the DKG flow, run the first command to complete the ceremony, shut everything down, and then run the second command to launch the threshold committee that was just minted. Next up, [`commonware-constantinople`](https://x.com/_patrickogrady/status/1973859090016395621) ! --- # commonware > Hiring [+ ~ \- + \- \- \- ~ ~ ~ \*\ \ | commonware\ \ \* ~ + \- \- \- \- + \- \* \- +](https://commonware.xyz/index.html) --- # commonware > Many-to-Many Interoperability with Threshold Simplex [+ ~ + \- + ~ + \- ~ ~ \*\ \ | commonware\ \ ~ + + + ~ \* \- + \* \* \- \*](https://commonware.xyz/index.html) Many-to-Many Interoperability with Threshold Simplex ---------------------------------------------------- By [Patrick O'Grady](https://x.com/_patrickogrady) January 16, 2025 Starting with the launch of the second blockchain, connecting any blockchain to any other blockchain without additional trust assumptions has been an elusive dream. Ten years later, application developers must still settle for some version of this. Techniques that enable consensus-secured messaging between independent blockchains (like lite clients and/or ZKPs) impose high per-message and per-connection overhead that bounds the number of external connections a single blockchain can handle to a few dozen. To go beyond this scale, some have created networks of networks to amortize the cost of any pairwise connection by storing all peer validator sets in a single location (where each blockchain trusts this overlay to provide the correct set of validators to verify any incoming message). Others have sought to provide a single execution environment where blockchains can settle to, using the settled state as a means of communication (requiring ZKPs that are prohibitively expensive to run at high throughput and/or introduce significant latency). Some have given their sequencing rights to a single builder to allow any set of chains under the purview of said builder to interact with each other. The largest group of connecting blockchains, however, have opted to employ external relayers to attest to the validity of exchanged messages because the consensus of interoperating blockchains can’t be efficiently proven on each other (or at all) in the first place. Today, we are excited to empower application developers to take one step closer to this dream of many-to-many, consensus-secured interoperability between independent blockchains with [consensus::threshold\_simplex](https://docs.rs/commonware-consensus/latest/commonware_consensus/simplex/index.html) . This new consensus dialect provides [Simplex](https://eprint.iacr.org/2023/463) \-like BFT agreement and emits succinct consensus certificates for each finalized view. In a nutshell, consensus::threshold\_simplex natively embeds BLS12-381 threshold cryptography into agreement to recover threshold signatures whenever 2f+1 messages are collected during any part of a view (zero message overhead compared to the previously released [consensus::simplex](https://commonware.xyz/blogs/commonware-the-anti-framework.html) dialect). This same technique, conveniently, also enabled us to embed a VRF (for leader election and post-facto execution randomness). So, how does this help? Prior to initialization, the validators of a new consensus::threshold\_simplex network run a DKG to generate a shared threshold secret (that no individual validators knows the value of). Each validator then uses their share of this secret to sign consensus messages, recovering threshold signatures that can be verified using the public key of the shared secret. With resharing, a network utilizing consensus::threshold\_simplex can retain the same BLS12-381 public key across arbitrary reconfiguration (i.e. validator set changes). These recovered threshold signatures are then packaged into ~240-byte certificates (roughly the size of an average transaction) and then broadcast to any other consensus instance interested in the latest finalized output. With this certificate (just a single BLS12-381 signature verification) and the open block format of consensus::threshold\_simplex, arbitrary data can be exchanged and proven about an external blockchain (e.g. state referenced by a state root in a finalized block). Threshold DKG and resharing in Byzantine environments is still relatively novel (with massive advancements introduced even over the last 3 years). To ensure consensus::threshold\_simplex can be paired with the latest, greatest, and safest ideas, DKG and resharing are decoupled from the consensus construction itself. To help developers get off the ground, however, we [released our own construction](https://commonware.xyz/blogs/commonware-cryptography.html) that scales to hundreds of participants (favoring a synchrony bound over ZKPs and a “public board”). If you want to use your own technique, plug it in! To demonstrate how consensus::threshold\_simplex can be used, we implemented a proof-of-concept bridge between two independent consensus instances called [examples::bridge](https://docs.rs/commonware-bridge) . In this demo, each consensus instance exchanges succinct consensus certificates about the other (and checks their validity during block verification). Block election is driven by the embedded VRF (the leader of view v+1 is only known at the conclusion of view v). You can run this demo yourself or watch the walkthrough: If your application could benefit from exchanging succinct consensus certificates with other blockchains that can verify BLS12-381 signatures (looking at you [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) ), [reach out!](https://github.com/commonwarexyz/monorepo/discussions) --- # commonware > Podcasts [+ \* \- + \- + \* \- + \- ~ \* +\ \ + commonware +\ \ \* \- \- ~ ~ ~ \* \- +](https://commonware.xyz/index.html) How Things Work =============== Exploring how blockchains (and the mechanisms that power them) work. How Things Work #5: TEEs All The Way Down On this episode of "How Things Work", we chat with Jack Kearney, Arnaud Brousseau, and Zeke Mostov from Turnkey about architecting secure TEE-based applications (yes, there are insecure ones). We start by discussing why and where TEEs are used (and how they can play a role even when MPC and ZK are employed). Next, we explore the foundations you need to build before deploying a TEE (assuming you don't want to use Turnkey's OSS tools for doing so). Last, we cover how to safely update code running in TEEs and how to safely interact with external state. **Guests:** [Jack Kearney](https://x.com/whojackjones) , [Arnaud Brousseau](https://x.com/arnaudbrousseau) , [Zeke Mostov](https://x.com/ZekeMostov) - [Turnkey](https://www.turnkey.com/) **Find on:** [YouTube](https://youtu.be/1SDGJjQyM8U) , [Spotify](https://open.spotify.com/episode/7KPi3BEY2ICdMKKd6jrbjA) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-5-tees-all-the-way-down/id1794554748?i=1000724796584) How Things Work #4: The Quick Merkle Database and Fast Ahead-of-Formation Optimization On this episode of "How Things Work", we chat with Ryan Zarick (raz), Isaac Zhang, and Thomas Kim from LayerZero about scaling blockchain throughput with their new authenticated database (QMDB) and a new approach to pre-block packing (FAFO). We first discuss the Quick Merkle Database (QMDB) and the insights that drive it state-of-the-art performance. Next, we discuss why the proof structure of QMDB works great with ZK and how to extend the (optional) compaction algorithm to apply changes to state. Last, we cover how Fast Ahead-of-Formation Optimization (FAFO) leverages QMDB to hit the mythical 1M TPS mark on a single machine. **Guests:** [Ryan Zarick](https://x.com/ryanzarick) , [Isaac Zhang](https://x.com/IsaacN0tNewton) , [Thomas Kim](https://x.com/Thomas_S_Kim) - [LayerZero](https://layerzero.network/) **Find on:** [YouTube](https://www.youtube.com/watch?v=ozu5suhWK70) , [Spotify](https://open.spotify.com/episode/1UT0EXpIrNPf6lUSUiBytl) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-4-the-quick-merkle-database-and/id1794554748?i=1000717528307) How Things Work #3: Scaling Broadcast with Raptor Codes On this episode of "How Things Work", we chat with Kushal Babel and Babak Gilkalaye from Category Labs (the team building the Monad reference client) about their research into scaling blockchain broadcast. We first discuss the techniques existing blockchains (like Bitcoin, Ethereum, and Solana) use to disseminate data across p2p networks. Next, we dive into the "broadcast stack" (Data Transmission, Encoding, System and Broadcast Strategy) and explore how Monad is employing Raptor Codes to balance low latency with high throughput. Last, we discuss the tradeoffs (and open questions) of deploying pre-consensus broadcast instead of "in the hot path" broadcast. **Guests:** [Kushal Babel](https://x.com/KushalBabel) , [Babak Gilkalaye](https://www.linkedin.com/in/babak-poorebrahim-gilkalaye-a5a20810a) - [Category Labs](https://www.category.xyz/) **Find on:** [YouTube](https://www.youtube.com/watch?v=0m2DgfyCi0w) , [Spotify](https://open.spotify.com/episode/67ZEmaEJhXK2qDkz5hU7Uw) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-3-scaling-broadcast-with-raptor-codes/id1794554748?i=1000711050270) How Things Work #2: Executable Semantic Frameworks and K In this episode of "How Things Work", we chat with Grigore Rosu about the 20+ year history of runtime verification and how his latest project, Pi Squared, is using Executable Semantic Frameworks (via K) to create a new type of blockchain execution environment that supports any programming language (including ones you write yourself). **Guests:** [Grigore Rosu](https://x.com/rosugrigore) - [Pi Squared](https://pi2.network/) **Find on:** [YouTube](https://www.youtube.com/watch?v=Gpx1xuz6oMM) , [Spotify](https://open.spotify.com/episode/7dKAiY191hK8YXLvmoGwqn) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-2-executable-semantic-frameworks-and-k/id1794554748?i=1000704512020) How Things Work #1: Partially Ordered Datasets For the second episode of "How Things Work", we chat with Shresth Agrawal about pod's recent work into Partially Ordered Datasets and how they can be used to deploy low-latency blockchain applications. We first discuss where pod originated and how different applications can be built without relying on total order. Then, we discuss how pod's recent work (Pod: An Optimal-Latency, Censorship-Free, and Accountable Generalized Consensus Layer) can provide the properties most applications want without running traditional consensus. Lastly, we explore how pod can be used as the backbone of complex gadgets that rely on censorship-resistant auctions. **Guests:** [Shresth Agrawal](https://x.com/shresth3103) - [pod](https://pod.network/) **Find on:** [YouTube](https://www.youtube.com/watch?v=5Rb2oo_MsmY) , [Spotify](https://open.spotify.com/episode/5o3VDHAHkusN4J6UmDw3DZ) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-1-partially-ordered-datasets/id1794554748?i=1000699564054) How Things Work #0: ZODA and The Accidental Computer For the pilot episode of "How Things Work", we chat with the Alex Evans and Guillermo Angeris (from Bain Capital Crypto) about their research into blockchain scaling. We first pull back the curtain on Data Availability Sampling (DAS) and explore how systems today encode data for light client sampling. Then, we discuss how their recent work, ZODA (Zero-Overhead Data Availability), promises to make this process more (or even optimally) efficient by transforming the encoding of some data into a proof of its correctness. After that, we dive into a discussion about The Accidental Computer (Polynomial Commitments from Data Availability), a surprising result that shows that succinct proof systems can reuse work already done during data availability encoding to reduce (or wholly remove) work associated with the proof system's polynomial commitment scheme. Last, we chat about implementation progress (in Julia) and how blockchains could be designed to take advantage of this work. **Guests:** [Alex Evans](https://x.com/alexhevans) , [Guillermo Angeris](https://x.com/GuilleAngeris) - [Bain Capital Crypto](https://baincapitalcrypto.com/) **Find on:** [YouTube](https://www.youtube.com/watch?v=eOGQOaqvgnI) , [Spotify](https://open.spotify.com/episode/4miKEaz7QcnIjLZ40ZKKf4) , [Apple](https://podcasts.apple.com/us/podcast/how-things-work-0-zoda-and-the-accidental-computer/id1794554748?i=1000689657448) ---