Brainstorming Paths to ACE on BAM

Executive Summary

This document presents an initial design proposal for enabling Application Controlled Execution (ACE) for Solana applications through BAM’s Plugin system. In this document, we outline a first ACE-enabling Plugin in the form of permissionless, opt-in speedbumps for applications. As Plugin design mechanisms continue to evolve, Jito Labs and others will continue to propose other Plugin implementations for the community through this forum.

We believe ACE represents an ideal starting point for BAM Plugins because:

  • Critical infrastructure: Applications are fundamental to Solana’s ecosystem; many have requested better tools to manage their microstructure.

  • Clear demand: Multiple trading applications have expressed the desire for granular control over transaction ordering, particularly speedbumps, to protect market makers from getting picked off on stale quotes by aggressive takers.

  • Pragmatic approach: Demonstrates BAM’s value proposition through a relatively simple, well-defined Plugin before expanding to more complex functionalities.

What we’re proposing:

  • A permissionless registration system where applications can opt-in to custom speedbump configurations

  • Verifiable sequencing guarantees through TEE-based attestations

  • Flexible parameters that applications can configure based on their specific needs

What we’re seeking:

This proposal is intentionally a first pass designed to spark discussion and gather feedback from the community. We want to understand:

  • Technical considerations we may have overlooked

  • Concerns about the permissionless registration model

  • Ideas for preventing abuse while maintaining openness

Important Points:

  • We would like to keep the conversation focused on this particular Plugin in the context of ACE. If you have comments or ideas for other Plugins, please post those on the Plugin Ideation thread https://forum.bam.dev/t/Plugin-ideation/20

  • This is a first pass and is not the final form of this Plugin. We expect some iteration to take place with feedback from applications and the community.

Application Controlled Execution

Application Controlled Execution (ACE) provides applications more granular control over their transaction ordering and sequencing. As outlined in Anza’s Internet Capital Markets roadmap, IBRL alone isn’t sufficient to enable Internet Capital Markets (ICM). Certain application types need custom forms of transaction ordering, sequencing and batching to deliver on their value proposition, provide the best user experience, and enable optimal market structures. This need is reflected in the growing ecosystem and success of purpose-built execution environments for trading applications.

BAM enables ACE by allowing applications to leverage Plugin primitives in the BAM node software that runs inside Trusted Execution Environments (TEEs). This software generates attestations recording transaction ordering decisions before sending them to validators. Without BAM, implementing ACE would require trusting validators to respect transaction ordering without any way to prove they actually did so.

BAM solves this trust problem by providing two key capabilities. First, applications can trigger Plugins inside BAM’s TEE, giving them more control over ordering logic. Second, cryptographic proofs of transaction ordering create a verifiable record that can be compared against the final transaction sequence. This creates an immutable ground truth for transaction ordering that validators cannot secretly manipulate, making ACE implementation both possible and trustworthy.

How does BAM work?

Transaction Scheduler

In order to have a conversation about ACE in the context of Solana scheduling, let’s go over how the v0 BAM scheduler is designed. While Jito Labs is the only entity running BAM on testnet and mainnet today, we have a proposed transaction scheduler for testing detailed below.

The current BAM scheduler uses a linear compute unit (CU) allocation strategy over each 400ms slot. It aims to fill blocks to 100% capacity (60M CUs) by linearly distributing compute units across time - for example, at 300ms (halfway through the slot), there should be 75% utilization (45M CUs). All transactions and bundles received from the Jito Labs Block Engine are unified in the BAM Node and scheduled using this scheduler. BAM builds the entire non-voting portion of the block with this algorithm.

The current implementation runs periodic auctions (<50ms) throughout the slot, with each auction targeting its time-slice worth of compute units. A feedback control system adjusts allocations in real-time to track the linear target curve as closely as possible. This approach ensures predictable, smooth block filling during high-demand periods. We believe a strategy like this balances an IBRL approach and one that ensures state can be updated continuously as opposed to filling blocks as fast as possible and sitting idle for 300ms or delaying block packing until the last available milliseconds.

With this understanding of the normal BAM scheduler, one can start to gain intuition around how ACE-related transactions can be sequenced inside the BAM Node.

BAM & ACE

We are proposing an initial version of ACE which leverages a generalized speed bump Plugin with permissionless application registration. The speed bump logic only applies for applications which register for the logic to run; all other transactions flow immediately to the scheduler and are not impacted.

Speed Bump Plugin

Context

Several of the trading applications we’ve talked to have a desire to define a speed bump for specific instructions using wall-clock time. For instance, an exchange may want to give a 20ms speed bump to takers and no speed bump for market makers, liquidations, and other key instructions to keep the protocol healthy. By doing this, applications may be able to:

  • Reduce toxic flow and adverse selection: Market makers get a head start on updating quotes before aggressive takers can execute against them, protecting liquidity providers from being picked off

  • Improve spread quality and market depth: When market makers face less adverse selection risk, they can quote tighter spreads and provide more liquidity, leading to better execution prices for all participants

Design

Router

Within BAM, we define a Router, which routes transactions to different subsystems within BAM. Within the Router, application owners can register their program ID and instruction markers which segment their transactions.

When the Router receives a transaction, it evaluates it against the registered applications for the speed bump Plugin. When a transaction is marked for the speed bump Plugin based on the program IDs in the transaction, it flows to the speed bump transaction pool where it sits for a pre-determined amount of time.

After the specified amount of time, the transaction gets forwarded to the scheduler where it’s sequenced according to the priority-fee-based scheduling algorithm.

It’s important to note that transactions which do trigger any conditions within the router immediately flow through to the scheduler. This ensures that all transactions which do not meet any of the speedbump conditions are immediately forwarded to the next stage.

Pros:

  • Simple design

Cons:

  • If the priority of the “fast pathed” transaction is too low such that it doesn’t immediately make it into the block and the “speed bumped” transaction has a higher priority fee, the speed bumped transaction may land before the non-speed bumped one.

  • When a composable transaction (aggregator swap) triggers multiple speed bumps, the max is taken.

Parameters

We suggest the following global parameters for the segmented transaction pool to enable customizability and avoid extreme abuse:

  • Minimum speed bump: 10ms

    • Needs to be less than or equal to the auction period of the currently implemented scheduler
  • Maximum speed bump: 50ms

  • Precision: 1ms

We envision that programs will want to apply speed bumps to specific transactions that do not meet some criteria. We envision an API with something like the below:

struct ApplicationSpeedBumpConfig {

    // Program ID registering for the speed bump

    program_id: Pubkey,



    // These are a list of negative markers containing instruction 

    // data offset and byte marker. 

    //

    // Any transaction which calls into program_id from a top-level

    // instruction with data at the given offset matching the marker will

    // bypass the speedbump. If the transaction passes program_id to any

    // other instruction and that program_id is not called at the top-level,

    // the speed bump is applied.

    negative_markers: InstructionMarker,



    // The speed bump in milliseconds

    speed_bump_ms: u8,

}



struct InstructionMarker {

    // Offset into instruction data

    data_offset: u8,

    // Marker to look for at the byte

    marker: u8

}

Application Registration

We would like a large number of applications to permissionlessly register, without intervention from any intermediaries or exposing BAM to denial-of-service attacks. It’s required that only application owners can register ACE Plugins for their applications. Application owners register through a variety of means:

  • Programs with upgrade authorities can sign messages proving ownership over their program and the configuration they’d like

  • Frozen programs or those unwilling to prove ownership through their upgrade authority can authenticate through social means via Github or other to-be-determined methods

We also recommend the following information is gathered from the program owner:

  • Name of the program

  • Link to website

  • Short description of what instructions are targeted

The type of authentication used (program owner signature or social check) will be saved for each application.

Transparency

Understanding the market structure for applications and the Solana network is a key component for its success. In addition to the BAM software being open sourced in the near future, we suggest the following:

  • We propose that applications are registered through an on-chain program using the information in the “Application Registration” section

  • Users can read this information from the blockchain

  • BAM Nodes can serve their view of program configurations on an attested HTTPS endpoint

Resources Used

It’s important to understand additional resource usage for enabling this system. This will ensure an accurate pricing model and allow the system to mitigate DOS attacks:

  • The Router needs to have a cache of the programs and how to identify transactions for segmentation

    • Estimated 32 bytes per program ID + some number of bytes to store instruction markers for segmentation and associated speed bumps
  • The Router will need to loop through all instructions and all account keys in all transactions, examining program IDs and instruction payloads for each transaction

    • This is trivially parallelizable
  • For segmented transactions, there will need to be a chunk of memory set aside for the delayed transactions.

  • On-chain program state for registration

    • Too many applications requires longer getProgramAccounts calls and more network ingress

Potential DOS Attacks

  • Mass registration abuse: Flooding the system with spurious program registrations, inflating memory sizes inside the BAM node, inducing extra processing time on transactions, and increasing on-chain state.

  • Transaction spam: Sending high volumes of transactions to fill the speed bump memory pools, consuming parallelizable compute and memory without landing on-chain.

  • Multi-Plugin triggering: Transactions designed to invoke multiple speed bumps, amplifying compute per tx and potentially conflicting delays.

  • Indirect abuse: Adversaries racking up unintended fees for legitimate apps or exploiting zero-fee edge cases.

Fees

A well-designed fee model should incentivize legitimate adoption while covering infrastructure costs and preventing abuse.

Why Fees Are Necessary

  • Infrastructure Costs: Running ACE Plugins requires real resources: TEE hardware, dedicated memory pools, and compute cycles to inspect every transaction. These aren’t free to operate and the goal is that accrued fees can be re-invested into the development of the BAM technology and better hardware for BAM Node operators.

  • Security: Without fees, attackers could register thousands of fake applications or spam transactions to fill up memory, degrading service for everyone. Fees should make attacks economically unfeasible.

  • Value Alignment: Applications using this plugin to reduce adverse selection and improve market quality create significant value. A fee ensures sustainable infrastructure that can deliver reliable performance guarantees and all ecosystem participants benefit from the upside.

Proposed Fee Structure:

  • Registration Fee: A subscription-based fee to cover application configuration storage and prevent spam registrations.

  • Per-Transaction Fee: Either a flat fee per transaction or dynamic based on compute units used and/or priority fee

  • Fee Split: We propose majority of these fees go to the validators and stakers running the BAM software

Conflicts

For transactions which conflict with multiple speedbump plugins, we suggest taking the maximum of all the speedbumps. For muli-transaction bundles, the speedbump is evaluated on all transactions within the bundle. The maximum is used because if anything less than the max is used, there is incentivize to compose maliciously created plugins to bypass the speedbumps of other programs.

Enforcement

  • How to enforce validators are following the proposed design

    • Ban validators not respecting the order sent to them.

      • Easily attributable
    • Require collateral and slash

Negative Second Order Effects

  • Rapidly changing market structure

    • We suggest a rate limited approach to changing an applications market structure (once per day)

Ecosystem Advisor Committee

  • Details of this committee are still TBD, but likely play a role:

    • Ensuring fairness of plugins

    • Determining fees

Wrapping Up

These are our initial thoughts on enabling a primitive version of ACE to unlock a wave of new applications to build on Solana. Please let us know your thoughts in the thread below, and if you’re an application developer interested in leveraging this Plugin, please comment below and reach out.

6 Likes

Interesting. Would love to see more details around resolving speed bumps being enforced for CPI based inner ixs with potentially conflicting sequence of execution.

1 Like

Really happy I found this and got a better feel for the internals of the BAM node.

Is it reasonable to expect that the checks the validator runs (account write locks, multi‑threading, CU/block limits, slot boundaries, etc.) can legitimately change the ordering of transactions it receives from the BAM node, even when the validator is behaving honestly? And if so, how feasible is it in practice to distinguish that kind of reordering from a validator maliciously reordering or front‑running BAM flow?

The BAM client sends transactions to the validator in a stream and the validator executes them in a conflict FIFO manner using a modified PrioGraph scheduler. At the same time, the BAM node saves the sequence and transactions sent to the validator.

After the block is built, analysis can be run if the ordering was different or the same in addition to seeing if any unrecognized transactions were added or things were censored.

2 Likes

Right now we’re thinking about something like a positive marker for bypassing the speedbump.

For instance, speedbump my Flashtrade program ABC by 20ms except for and transaction which directly calls ABC in a top level instruction which has an instruction data marker equal to [x,y,z] at offset O. If any transaction passes program ABC as account data, it must be a CPI and that gets speedbumped.

It gets a little tricky if apps are wrapping the non-speedbumped txs with other logic, but I think we can figure out a way around that.

1 Like