Skip to main content

Builders

MPBC compensates builders for flow added to their blocks and for contributions to other builders' blocks. This allows earning revenue without winning the slot outright, and increases the value of winning blocks.

Operators continue to offer services like cancels and block propagation. Because operators share delivered payloads with each other, block propagation is likely to be faster and more predictable compared to legacy relay services. Operators share demotions and will support shared collateral to unlock more capital efficiency for builders.

MPBC is permissionless and requires minimal changes to the existing block submission process. Common builder questions are answered in the FAQ.

Getting started​

Builders already submitting blocks to Ultra Sound, Titan or Aestus do not have to change their submission endpoints. Participation requires MPBC reserves and lean additions to bid submissions. See Interfaces for wire details.

Auction dynamics​

MPBC aims to maintain the dynamics of the PBS auction. Builders continue to compete on the highest bid to increase their chance of winning the auction outright, having a block selected as the base block for MPBC, or landing transactions in a multi-party block.

A multi-party block is only delivered if its base builder also holds the highest single-party bid at delivery time. This means that MPBC can improve the winning block, but it cannot change who wins the auction at an operator. Therefore, builders do not need to worry about being outbid by a multi-party block on a specific operator.

For example, builder A leads the auction with a bid of 1.00 ETH when its block is selected as the base block. Transactions are appended to this base block, and the resulting multi-party block pays 1.05 ETH. If at delivery time builder A bids 1.03 ETH and builder B bids 1.02 ETH, the multi-party block is delivered as it pays more than the top bid held by builder A. If builder B bids 1.04 ETH instead, builder B's block is delivered as builder A does not hold the top bid.

Reserves and opt-in​

Builders become eligible for MPBC by registering a Safe with every operator they wish to use and adding reserves.

A builder then opts in one submission at a time, through the x-merge-type header. A builder that sets append_only offers the block as a merge base. A builder that sets mergeable offers transactions out of the block, and offers the block as a base only when the body sets allow_appending. A submission that sets neither value stays out of MPBC.

Because the priority fees added through MPBC accrue to the base builder's coinbase, the value share of the proposer, contributing builders, and operator is drawn from the base builder's reserves. For this reason, builders participating in MPBC must keep their reserves Safe funded. See Value distribution for more details.

Contributing transactions​

To contribute transactions to MPBC, submissions carry the mergeable merge type and merging data. Over the TCP stream, this can be merging data v2:

struct BlockMergingDataV2 {
allow_appending: bool, // may this block be used as a merge base?
builder_address: Address, // credited for orders merged out of this block
orders: Vec<OrderV2>, // { start, len, flags }: what may be merged out of it
tx_codes: Vec<OrderTxCodes>, // per-transaction codes, only for bundles whose transactions differ
}

Bundles are defined as ranges of consecutive block transactions, and individual transactions are defined as bundles of length one. Bundles are kept in sequence and execute atomically unless ALL_REVERT is set or specific transactions within the bundle are marked as available to be dropped or reverted. Orders flagged LATEST_ONLY are only used while present in the builder's most recent submission, thus allowing cancels. Cancels only apply to future multi-party blocks and a block built before the cancel can still be delivered. Blocks and transactions made available for merging must comply with the filtering preferences of the proposer.

Over HTTP, merging data uses the v1 form BlockMergingData, described under Merging data v1. An operator converts v1 into v2 on arrival, so both versions are merged identically:

struct BlockMergingData {
allow_appending: bool, // may this block be used as a merge base?
builder_address: Address, // credited for orders merged out of this block
merge_orders: Vec<Order>, // what may be merged out of it
}

enum Order {
Tx(TransactionOrder), // { index, can_revert }
Bundle(BundleOrder), // { txs, reverting_txs, dropping_txs, flags }
}

Mergeable submissions may use the dehydrated format, and the operator decodes the merging data alongside them. Merge headers that fail to parse are treated as none, which leaves the block out of MPBC.

Builders continue to benefit from bidding competitively in the auction. Higher bids increase the chance of winning the slot outright, of a block being selected as a base block, and of contributing transactions to others' base blocks.

Accounting​

Operators expose a data API for tracking multi-party blocks. For every multi-party block, the endpoint reports the original and new block hash, the original and new value, and the revenue of the base builder, contributing builders, operator, and proposer. This makes win rates and revenue traceable and is documented under Verification. Value charts those figures aggregated per builder. Operators also report how they handled each transaction made available for merging.

Quickstart example​

The following bid submission metadata marks a block as an eligible base block for MPBC. This means that transactions by other builders can be added to it. Additionally, a transaction and a bundle are marked as eligible to be merged into a base block by another builder.

Over the TCP stream, this is done by setting merge type mergeable and the MERGING_V2 flag in the submission header, with preferences indicated in the merging data v2:

BlockMergingDataV2 {
allow_appending: true,
builder_address: 0x4242424242424242424242424242424242424242,
orders: [
OrderV2 { start: 12, len: 1, flags: 0 },
OrderV2 { start: 45, len: 3, flags: LATEST_ONLY },
],
tx_codes: [
OrderTxCodes { order: 1, codes: [0b00_01_00_00] },
],
}
  • The block takes part in MPBC because the header sets merge type mergeable.
  • By setting allow_appending true, the block is eligible to serve as a base block for others to merge on.
  • The first order marks the transaction at index 12 available for MPBC. With no flags and no codes, it must not revert.
  • The second order offers the transactions at indices 45 to 47 as a bundle, in this order. LATEST_ONLY means that it is cancelled if it is not included in the builder's next submission for this block.
  • The codes entry for the second order assigns code 0 to its first two transactions and code 1 to its third. The first two must succeed, the third may revert, and none may be dropped.

Over HTTP, this is done by submitting the bid submission with an x-merge-type: mergeable header to the operator API endpoint under POST /relay/v1/builder/blocks, with preferences indicated in the body. A builder that only wants to make its block available as a base can alternatively simply set x-merge-type: append_only in the header without submitting the body.

{
"submission": { "...": "the standard signed bid submission" },
"merging_data": {
"allow_appending": true,
"builder_address": "0x4242424242424242424242424242424242424242",
"merge_orders": [
{ "index": 12, "can_revert": false },
{
"txs": [45, 46, 47],
"reverting_txs": [2],
"dropping_txs": [],
"flags": "LATEST_ONLY"
}
]
}
}
  • The header x-merge-type: mergeable takes the place of the merge type in the TCP header.
  • The same orders are expressed with explicit indices: can_revert on the single transaction, reverting_txs and dropping_txs positions within the bundle, and flags as a string of flag names.