This post provides a curated list of use-cases that ABCI++ unlocks for application builders. To recall, ABCI++ is a codename for ABCI v2
, released in CometBFT v0.38, and integrated in Cosmos SDK v0.50.
This post is a direct follow-up to our previous story called “Intro to ABCI v2”. We will be reusing some the terminology and context from that post, and encourage reading that before proceeding here.
There are 3 broad use-cases we will cover today. This is not a deep dive into engineering aspects, but a high-level design of these uses. Our goal with this post is to encourage further innovation. We will describe:
Cross-chain coordination: This third use-case actually has three examples, all of which are highly interesting in their own right:
For later on, if this post proves to be valuable and stir conversations, we plan to also cover other important use-cases, for example threshold encryption for mempool privacy or tiablob.
Accurate pricing information is essential for the operation of any financial instrument, decentralized or traditional. In the context of decentralized financial instruments, such as DEX-es, token prices have been traditionally sourced from centralized actors, such as centralized exchanges.
In a network building with CometBFT v0.38 or newer, it is possible to source token prices using an in-protocol, decentralized approach. The basic sequence of actions is sketched in the diagram below. The general flow involves three steps: (1) validators perform external queries to various actors such as centralized services or decentralized exchanges, to obtain pricing information for certain token pairs; (2) each validator injects the pricing information they obtained into the block via ExtendVote
and verifies the information that other validators injected; and finally (3) the set of updated pricing pair information is then used in executing transactions in the subsequent block.
If you’d like to know more, we recommend reading about the Slinky production-ready implementation of a decentralized price oracle that the Skip team built using CometBFT.
Sketch of how a decentralized price oracle functions using CometBFT v0.38 (ABCI v2) or newer. For simplicity, in this description only the proposer is shown to verify vote extensions, but in reality all validators do.
This is one of the most straightforward applications of the powerful ABCI interface features introduced in newer CometBFT versions.
Briefly, this is the ability of the application to execute a block before Comet finalizes that block. Without optimistic execution, the normal flow is (1) CometBFT finalizes a block, then (2) the application executes that block, and finally (3) the application gives control back to CometBFT. These 3 steps execute in a sequence. With optimistic execution, roughly speaking, steps (1) and (2) can run in parallel with one another. This enables shorter block production times.
Optimistic block execution is an optimization, and is in the same spirit as speculative execution from conventional computing fields (eg databases or computer architecture).
The SDK team describes this feature in more detail here for SDK release v0.50. Notably, the Sei team have been pioneering this feature in production as far back as September 2022.
The use-cases we discussed above have been anticipated ever since ABCI++ was initially proposed in RFC 013, and we have been very excited to see teams building them out. This last category of use-cases, which we call “cross-chain coordination,” is completely novel and has emerged in the last several months.
First, let’s introduce the concept of a side transaction: a transaction that is special because it is not end-users that submit it, but validators themselves. The content, validity, and execution of a side transaction is contingent on state from a different blockchain network relative to the current application. This means that validating such transactions can be tricky, because their validity predicate is non-deterministic (i.e., depends on external state). Note that side transactions are not unlike transactions that update oracle prices in the first use-case we described above.
Second, the architecture here involves two systems: an L1 (Ethereum) and an L2. The L2 is the most interesting element for this discussion, and itself comprises two layers: (i) Bor, a fork of geth
which is called the "block production layer", and (ii) Heimdall, the "validation layer", a system built using CometBFT and Cosmos SDK, using vote extensions. We are interested in the validation layer of the L2. The data that goes into side transactions in the L2 comes from the L1 and concerns staking. The action of staking happens on the L1 and determines the voting power of validators in the L2, hence accurate staking data must somehow travel from the L1 to the L2, which is where side transactions — and vote extensions — come into play.
Armed with this knowledge, let’s describe the basic flow:
Suppose the L2 is constructing the block at height H
:
PrepareProposal
: the block proposer adds side transactions to the proposal. As mentioned before, these transactions include staking information data pulled from the L1.
ProcessProposal
: validators become aware and do basic validation of side transactions in the proposal. We call this step external validation of side transactions.
ExtendVote
: validators append a vote extension to their pre-commit; the extension includes the output of the external validation performed on the side transactions.
The L2 is now constructing block height H+1
:
PrepareProposal
: Proposer collects vote extensions (which include the output of external validation) from at least 2/3rd of validators (voting-power equivalent) and includes these in the proposal.
ProcessProposal
: Validators verify the vote extensions included in the proposal.
FinalizeBlock
: All full nodes tally up the extensions included in the decision (H+1
) and based on them execute the side transactions included in the previous decision (H
).
To recap, notice that validators cannot validate side transactions deterministically based purely on current L2 application state. Validators need input from some oracle, concretely the content of a contract in the L1. Reading from that contract may fail, or different validators may observe different states, hence they will have different views on the validity of side transactions, even without any Byzantine behavior at play. This arises from asynchrony or network failures, for example. Validators cannot simply accept/reject stake updates inside side transactions (inside vote extensions) from a block proposal. But once validators vote and the votes are tallied, they all accept the decision of the group regarding side transactions from height H
as that appears in ProcessProposal during height H+1
. This happens even if some validators voted against a side transaction in the initial proposal.
Both of the next two use-cases of ABCI v2 have emerged during the "ABCI++ track” of Hackmos Istanbul (Oct 2023).
The IBC-Sync project introduces an insightful new design to IBC packet relaying. In the current model, IBC relaying is a completely permissionless activity: Any user of an IBC-enabled blockchain can consume the IBC events from that blockchain and build appropriate IBC packets which they can subsequently submit to the counterparty IBC chain. This fully permissionless design can be an issue because relaying is performed ad-hoc by arbitrary actors, so no one in particular is responsible for this task. (This is not entirely accurate, as in practice there are professional teams operating relayers. Also, for a more detailed explanation of IBC relaying, see here.)
Instead of this current model, the IBC-Sync design ensures that validators themselves perform the task of IBC packet relaying. This task is included in the normal flow of block construction. Each validator pulls outstanding IBC packets from connected chains and uses ExtendVote
to inject those packets (alongside appropriate IBC client update) into the block that is being constructed. The IBC packets then become ordinary transactions that are included and executed in the subsequent block.
The CoCage project is similar to IBC-Sync in the sense that the goal is the same, to relay IBC packets, i.e., cross-chain messages. It is entirely different from IBC-Sync because in CoCage the model involves a rollup and a Cosmos SDK chain (in contrast, in IBC-Sync the model involved two SDK chains). Beside a rollup and an SDK chain, there is also a third system involved, namely a Data Publication (DP) network such as Celestia.
The goal is for the SDK chain to verify IBC packets that originate from the rollup. To do so, validators are tasked with running a local light node for the DP network and to regularly sample blocks from this network. These blocks are important because they contain rollup transactions (as well as the application root hash). If the SDK chain can obtain reliable data about blocks in the DP, they can correlate that data against IBC packets originating from the rollup, and can therefore trust these packets. The basic steps here are as follows:
Validators use ExtendVote
to extend their pre-commit with new block height(s) sampled from the DP. Specifically, for each height, the validator inserts data commitments extracted from the DP via their local instance of a light node.
During PrepareProposal
, the proposer collects the vote extensions and includes them in the proposed block. This only happens for heights that have not been sampled before, and for which there is a minimum threshold (over 2/3 voting power-equivalent) of votes.
During ProcessProposal
, each validator only accepts the proposed block if they have previously sampled the same block heights as present in the vote extensions and can attest to their validity; otherwise each validator rejects the block proposal. This is also a form of external validation (as in the Polygon L2 use-case), and this validation is also not guaranteed to be deterministic due to RPC failures, for example, or inconsistency due to light client attacks.
We recommend interested readers to check detailed architecture and design in the repo directly to understand how the commitments are stored, and how IBC clients can used these commitments for IBC packet proof verification.
RFC 013: ABCI++: The first RFC that proposed ABCI++ has a very good table describing improvements that ABCI++ unlocks.