-
Notifications
You must be signed in to change notification settings - Fork 185
feat: update both optimistic submission methods to use adjustment data v3 #860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,5 @@ | ||
| use alloy_primitives::{Address, Bloom, Bytes, B256}; | ||
|
|
||
| /// The type representing UltraSound bid adjustments. | ||
| #[derive( | ||
| PartialEq, | ||
| Eq, | ||
| Clone, | ||
| Debug, | ||
| serde::Serialize, | ||
| serde::Deserialize, | ||
| ssz_derive::Encode, | ||
| ssz_derive::Decode, | ||
| )] | ||
| pub struct BidAdjustmentDataV1 { | ||
| /// State root of the payload. | ||
| pub state_root: B256, | ||
| /// Transactions root of the payload. | ||
| pub transactions_root: B256, | ||
| /// Receipts root of the payload. | ||
| pub receipts_root: B256, | ||
| /// The usual builder address that pays the proposer in the last transaction of the block. | ||
| /// When we adjust a bid, this transaction is overwritten by a transaction from the collateral | ||
| /// account `fee_payer_address`. If we don't adjust the bid, `builder_address` pays the | ||
| /// proposer as per usual. | ||
| pub builder_address: Address, | ||
| /// The state proof for the builder account. | ||
| pub builder_proof: Vec<Bytes>, | ||
| /// The proposer's fee recipient. | ||
| pub fee_recipient_address: Address, | ||
| /// The state proof for the fee recipient account. | ||
| pub fee_recipient_proof: Vec<Bytes>, | ||
| /// The fee payer address that is custodied by the relay. | ||
| pub fee_payer_address: Address, | ||
| /// The state proof for the fee payer account. | ||
| pub fee_payer_proof: Vec<Bytes>, | ||
| /// The merkle proof for the last transaction in the block, which will be overwritten with a | ||
| /// payment from `fee_payer` to `fee_recipient` if we adjust the bid. | ||
| pub placeholder_transaction_proof: Vec<Bytes>, | ||
| /// The merkle proof for the receipt of the placeholder transaction. It's required for | ||
| /// adjusting payments to contract addresses. | ||
| pub placeholder_receipt_proof: Vec<Bytes>, | ||
| } | ||
|
|
||
| /// The type for bid adjustments in optimistic v3. | ||
| /// Ref: <https://github.com/ultrasoundmoney/docs/blob/main/optimistic-v3.md#optimistic-v3> | ||
| #[derive( | ||
|
|
@@ -53,7 +12,7 @@ pub struct BidAdjustmentDataV1 { | |
| ssz_derive::Encode, | ||
| ssz_derive::Decode, | ||
| )] | ||
| pub struct BidAdjustmentDataV2 { | ||
| pub struct BidAdjustmentDataV3 { | ||
| /// Transactions root of the payload. | ||
| pub el_transactions_root: B256, | ||
| /// Withdrawals root of the payload. | ||
|
|
@@ -76,75 +35,16 @@ pub struct BidAdjustmentDataV2 { | |
| /// The merkle proof for the last transaction in the block, which will be overwritten with a | ||
| /// payment from `fee_payer` to `fee_recipient` if we adjust the bid. | ||
| pub el_placeholder_transaction_proof: Vec<Bytes>, | ||
| /// New in V2: SSZ merkle proof for last transaction | ||
| pub cl_placeholder_transaction_proof: Vec<B256>, | ||
| /// The merkle proof for the receipt of the placeholder transaction. It's required for | ||
| /// adjusting payments to contract addresses. | ||
| pub placeholder_receipt_proof: Vec<Bytes>, | ||
| /// New in V2: Logs bloom accrued until but not including the last (payment) transaction. | ||
| pub pre_payment_logs_bloom: Bloom, | ||
| } | ||
|
|
||
| /// Common bid adjustment information that can be used for creating bid adjustment data. | ||
| #[derive(Clone, Debug)] | ||
| pub struct BidAdjustmentData { | ||
| /// State root of the payload. | ||
| pub state_root: B256, | ||
| /// Transactions root of the payload. | ||
| pub el_transactions_root: B256, | ||
| /// Withdrawals root of the payload. | ||
| pub el_withdrawals_root: B256, | ||
| /// Receipts root of the payload. | ||
| pub receipts_root: B256, | ||
| /// The merkle proof for the last transaction in the block, which will be overwritten with a | ||
| /// payment from `fee_payer` to `fee_recipient` if we adjust the bid. | ||
| pub el_placeholder_transaction_proof: Vec<Bytes>, | ||
| /// New in V2: SSZ merkle proof for last transaction | ||
| /// SSZ merkle proof for last transaction | ||
| pub cl_placeholder_transaction_proof: Vec<B256>, | ||
| /// The merkle proof for the receipt of the placeholder transaction. It's required for | ||
| /// adjusting payments to contract addresses. | ||
| pub placeholder_receipt_proof: Vec<Bytes>, | ||
| /// New in V2: Logs bloom accrued until but not including the last (payment) transaction. | ||
| pub el_placeholder_receipt_proof: Vec<Bytes>, | ||
| /// Logs bloom accrued until but not including the last (payment) transaction. | ||
| pub pre_payment_logs_bloom: Bloom, | ||
| /// State proofs. | ||
| pub state_proofs: BidAdjustmentStateProofs, | ||
| } | ||
|
|
||
| impl BidAdjustmentData { | ||
| /// Convert bid adjustment data into [`BidAdjustmentDataV1`]. | ||
| pub fn into_v1(self) -> BidAdjustmentDataV1 { | ||
| BidAdjustmentDataV1 { | ||
| state_root: self.state_root, | ||
| transactions_root: self.el_transactions_root, | ||
| receipts_root: self.receipts_root, | ||
| builder_address: self.state_proofs.builder_address, | ||
| builder_proof: self.state_proofs.builder_proof, | ||
| fee_recipient_address: self.state_proofs.fee_recipient_address, | ||
| fee_recipient_proof: self.state_proofs.fee_recipient_proof, | ||
| fee_payer_address: self.state_proofs.fee_payer_address, | ||
| fee_payer_proof: self.state_proofs.fee_payer_proof, | ||
| placeholder_transaction_proof: self.el_placeholder_transaction_proof, | ||
| placeholder_receipt_proof: self.placeholder_receipt_proof, | ||
| } | ||
| } | ||
|
|
||
| /// Convert bid adjustment data into [`BidAdjustmentDataV2`]. | ||
| pub fn into_v2(self) -> BidAdjustmentDataV2 { | ||
| BidAdjustmentDataV2 { | ||
| el_transactions_root: self.el_transactions_root, | ||
| el_withdrawals_root: self.el_withdrawals_root, | ||
| builder_address: self.state_proofs.builder_address, | ||
| builder_proof: self.state_proofs.builder_proof, | ||
| fee_recipient_address: self.state_proofs.fee_recipient_address, | ||
| fee_recipient_proof: self.state_proofs.fee_recipient_proof, | ||
| fee_payer_address: self.state_proofs.fee_payer_address, | ||
| fee_payer_proof: self.state_proofs.fee_payer_proof, | ||
| el_placeholder_transaction_proof: self.el_placeholder_transaction_proof, | ||
| cl_placeholder_transaction_proof: self.cl_placeholder_transaction_proof, | ||
| placeholder_receipt_proof: self.placeholder_receipt_proof, | ||
| pre_payment_logs_bloom: self.pre_payment_logs_bloom, | ||
| } | ||
| } | ||
| /// Gas used by the placeholder (payout) transaction. Required for V3 to relax the | ||
| /// gas_limit == gas_used requirement. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New V3 field - verify relay compatibility The Please verify:
|
||
| pub placeholder_gas_used: u64, | ||
| } | ||
|
|
||
| /// Bid adjustment state proofs. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -39,7 +39,7 @@ use evm::EthCachedEvmFactory; | |||||
| use jsonrpsee::core::Serialize; | ||||||
| use parking_lot::Mutex; | ||||||
| use rbuilder_primitives::{ | ||||||
| mev_boost::BidAdjustmentData, BlockSpace, Order, SimValue, SimulatedOrder, | ||||||
| mev_boost::BidAdjustmentDataV3, BlockSpace, Order, SimValue, SimulatedOrder, | ||||||
| TransactionSignedEcRecoveredWithBlobs, | ||||||
| }; | ||||||
| use reth::{ | ||||||
|
|
@@ -613,7 +613,7 @@ pub struct FinalizeResult { | |||||
| /// The Pectra execution requests for this bid. | ||||||
| pub execution_requests: Vec<Bytes>, | ||||||
| /// Bid adjustment data. | ||||||
| pub bid_adjustments: HashMap<Address, BidAdjustmentData>, | ||||||
| pub bid_adjustments: HashMap<Address, BidAdjustmentDataV3>, | ||||||
| /// Duration of root hash calculation. | ||||||
| pub root_hash_time: Duration, | ||||||
| } | ||||||
|
|
@@ -1141,21 +1141,30 @@ impl<Tracer: SimulationTracer, PartialBlockExecutionTracerType: PartialBlockExec | |||||
| &local_ctx.tx_ssz_leaf_root_cache, | ||||||
| ) | ||||||
| }); | ||||||
| let placeholder_gas_used = self | ||||||
| .executed_tx_infos | ||||||
| .last() | ||||||
| .map(|tx_info| tx_info.space_used.gas) | ||||||
| .expect("payout transaction must exist"); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential panic in edge cases This Consider deferring this calculation to only when
Suggested change
Alternatively, you could compute this lazily: let placeholder_gas_used = LazyCell::new(|| {
self.executed_tx_infos
.last()
.map(|tx_info| tx_info.space_used.gas)
.expect("payout transaction must exist")
});This preserves the original behavior where the expect would only be evaluated when bid adjustments are actually created. |
||||||
| let bid_adjustments = bid_adjustment_state_proofs | ||||||
| .into_iter() | ||||||
| .map(|(fee_payer, state_proofs)| { | ||||||
| ( | ||||||
| fee_payer, | ||||||
| BidAdjustmentData { | ||||||
| state_root: block.header.state_root, | ||||||
| BidAdjustmentDataV3 { | ||||||
| el_transactions_root: block.header.transactions_root, | ||||||
| el_withdrawals_root: block.header.withdrawals_root.unwrap_or_default(), | ||||||
| receipts_root: block.header.receipts_root, | ||||||
| builder_address: state_proofs.builder_address, | ||||||
| builder_proof: state_proofs.builder_proof, | ||||||
| fee_recipient_address: state_proofs.fee_recipient_address, | ||||||
| fee_recipient_proof: state_proofs.fee_recipient_proof, | ||||||
| fee_payer_address: state_proofs.fee_payer_address, | ||||||
| fee_payer_proof: state_proofs.fee_payer_proof, | ||||||
| el_placeholder_transaction_proof: el_placeholder_transaction_proof.clone(), | ||||||
| cl_placeholder_transaction_proof: cl_placeholder_transaction_proof.clone(), | ||||||
| placeholder_receipt_proof: placeholder_receipt_proof.clone(), | ||||||
| el_placeholder_receipt_proof: placeholder_receipt_proof.clone(), | ||||||
| pre_payment_logs_bloom, | ||||||
| state_proofs, | ||||||
| placeholder_gas_used, | ||||||
| }, | ||||||
| ) | ||||||
| }) | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Field naming change
The field was renamed from
placeholder_receipt_prooftoel_placeholder_receipt_proof. While this naming is more consistent with the EL/CL prefix convention used elsewhere in V3, ensure this matches the exact field name expected by the relay API. The UltraSound docs should be the source of truth for field names.The
el_prefix makes sense as this is an execution layer proof (vs consensus layer), similar toel_transactions_rootandcl_placeholder_transaction_proof.