Skip to content

Conversation

@avalonche
Copy link
Collaborator

@avalonche avalonche commented Oct 3, 2025

📝 Summary

Add permit function calls so that tee signer don't need funding to do the flashtestation transactions. Adds additional flashtestation tests and improves error handling.

CLI Changes

--flashtestations.use-permit enables the permit contract call and does not attempt to fund the tee key. It would use the builder key and many flags such as --flashtestations.rpc-url, --flashtestations.funding-key will not be needed to support flashtestations


✅ I have completed the following steps:

  • Run make lint
  • Run make test
  • Added tests (if applicable)

@avalonche avalonche force-pushed the flashtestations-permit branch 3 times, most recently from ad61301 to 75e520c Compare October 4, 2025 09:19
@avalonche avalonche mentioned this pull request Oct 6, 2025
3 tasks
@avalonche avalonche force-pushed the add-flashtestation-integration-tests branch from 260cb95 to 2bd3b66 Compare October 16, 2025 18:21
Base automatically changed from add-flashtestation-integration-tests to main October 16, 2025 18:34
Copilot AI review requested due to automatic review settings October 18, 2025 06:32
@avalonche avalonche force-pushed the flashtestations-permit branch from 75e520c to ef81cca Compare October 18, 2025 06:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds permit-based registration and block proof verification for flashtestations so the TEE signer no longer needs funding; introduces new tests and refactors builder transaction simulation to support permit flows.

  • Introduces EIP-712 style permit functions on registry and builder policy contracts plus related signature/nonce logic.
  • Refactors builder transaction trait and implementations to generic over extra context and execution info, adding unified simulation helpers and error types.
  • Adds CLI flag --flashtestations.use-permit and corresponding test coverage for permit registration and block proof flows.

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
crates/op-rbuilder/src/tests/mod.rs Updates test contract addresses used in setup.
crates/op-rbuilder/src/tests/flashtestations.rs Expands test suite with permit, invalid quote, unauthorized workload, and block proof scenarios; adjusts expected tx counts.
crates/op-rbuilder/src/flashtestations/service.rs Extends bootstrap to pass builder key and support permit flag gating RPC registration.
crates/op-rbuilder/src/flashtestations/mod.rs Adds permit-related function and error definitions to interfaces; simplifies revert enum.
crates/op-rbuilder/src/flashtestations/builder_tx.rs Implements permit registration and block proof signing logic; refactors simulation paths and error handling.
crates/op-rbuilder/src/flashtestations/args.rs Adds CLI arg flashtestations_use_permit.
crates/op-rbuilder/src/builders/standard/service.rs Passes builder key into flashtestations bootstrap with new signature.
crates/op-rbuilder/src/builders/standard/builder_tx.rs Adjusts trait usage for new generics and error-tolerant flashtestations integration.
crates/op-rbuilder/src/builders/mod.rs Re-exports new error/result types, removes obsolete helper.
crates/op-rbuilder/src/builders/flashblocks/service.rs Updates generic bounds to include execution info type for flashblocks.
crates/op-rbuilder/src/builders/flashblocks/payload.rs Adds FlashblocksExecutionInfo; updates trait bounds accordingly.
crates/op-rbuilder/src/builders/flashblocks/builder_tx.rs Adapts builder tx structures to new generic trait; commits state before flashtestations txs.
crates/op-rbuilder/src/builders/builder_tx.rs Major refactor: adds unified simulation utilities, new error variants, generic BuilderTxBase, and removes log_exists helper.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copilot AI review requested due to automatic review settings October 18, 2025 10:27
@avalonche avalonche force-pushed the flashtestations-permit branch from 95a824c to 82c5fea Compare October 18, 2025 10:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@avalonche avalonche force-pushed the flashtestations-permit branch from 82c5fea to e79a2c9 Compare October 18, 2025 10:32
Copilot AI review requested due to automatic review settings October 21, 2025 15:52
@avalonche avalonche force-pushed the flashtestations-permit branch from e79a2c9 to 9f2874a Compare October 21, 2025 15:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


#[derive(Debug, thiserror::Error)]
pub enum InvalidContractDataError {
#[error("did not find expected logs expected {0:?} but got {1:?}")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't :? for vec look unreadable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a vec of hashes though, not a complex struct

) -> Result<Vec<BuilderTransactionCtx>, BuilderTransactionError>;

fn add_builder_txs<Extra: Debug + Default>(
fn simulate_builder_txs_with_state_copy(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc comment please, why state copy is needed?


pub fn get_balance(
db: &mut State<impl Database>,
db: impl DatabaseRef,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noice


#[derive(Debug, Clone)]
pub(super) struct BuilderTxBase {
pub(super) struct BuilderTxBase<ExtraCtx = ()> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you use extraCtx in here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed in ctx to satisfy generics for both standard and flashblocks builder. Though we can consider deprecating the standard builder now that flashblocks is stable?

let ResultAndState { state, .. } = evm
.transact(&builder_tx.signed_tx)
.transact(&signed_tx)
.map_err(|err| BuilderTransactionError::EvmExecutionError(Box::new(err)))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to fail all transaction is some tx failed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BuilderTransactionError::EvmExecutionError is a fatal error, though we can distinguish between invalid transactions (e.g. nonce errors) from evm execution errors and only skip invalid transactions


if ctx.is_first_flashblock() {
let flashblocks_builder_tx = self.base_builder_tx.simulate_builder_tx(ctx, db)?;
let flashblocks_builder_tx = self.base_builder_tx.simulate_builder_tx(ctx, &mut *db)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you just pass db?

self.flashblock_number_address,
InvalidContractDataError::InvalidLogs(
vec![IFlashblockNumber::FlashblockIncremented::SIGNATURE_HASH],
vec![],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to put actual logs in there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no planning to deprecate this soon after permit changes are tested and merged

env = "FLASHTESTATIONS_USE_PERMIT",
default_value = "false"
)]
pub flashtestations_use_permit: bool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, is there a case when we don't want to use permit?
Maybe it should be the only option for flashtestations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The non permit flags are being used in experimental so it'll be a breaking change. This PR should be merged first before updating the builder args in experimental, then removing the flags and related code

}

fn simulate_verify_block_proof_tx<ExtraCtx: Debug + Default>(
// TODO: deprecate in favour of permit calls
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it makes sense to deprecate it right now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its still being used in experimental

) -> Result<Option<BuilderTransactionCtx>, BuilderTransactionError> {
let balance = get_balance(evm.db_mut(), self.tee_service_signer.address)?;
let balance = get_balance(evm.db(), self.tee_service_signer.address)?;
if balance.is_zero() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, what if balance 1 wei?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we just manually fund it, we don't want to fund the key more than necessary

}

fn register_tee_service_tx<ExtraCtx: Debug + Default>(
// TODO: deprecate in favour of permit calls
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copilot AI review requested due to automatic review settings October 22, 2025 18:59
@avalonche avalonche enabled auto-merge (squash) October 22, 2025 19:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +141 to 145
fn fund_tee_service_tx(
&self,
block_content_hash: B256,
ctx: &OpPayloadBuilderCtx<ExtraCtx>,
evm: &mut OpEvm<
&mut State<StateProviderDatabase<impl StateProvider>>,
NoOpInspector,
PrecompilesMap,
>,
) -> Result<TxSimulateResult, BuilderTransactionError> {
let nonce = get_nonce(evm.db_mut(), self.tee_service_signer.address)?;

let verify_block_proof_tx = self.signed_block_builder_proof_tx(
block_content_hash,
ctx,
ctx.block_gas_limit(),
nonce,
)?;
let ResultAndState { result, state } = match evm.transact(&verify_block_proof_tx) {
Ok(res) => res,
Err(err) => {
if err.is_invalid_tx_err() {
return Err(BuilderTransactionError::InvalidTransactionError(Box::new(
err,
)));
} else {
return Err(BuilderTransactionError::EvmExecutionError(Box::new(err)));
}
}
};
match result {
ExecutionResult::Success { gas_used, logs, .. } => Ok(TxSimulateResult {
gas_used,
success: true,
state_changes: state,
revert_reason: None,
logs,
}),
ExecutionResult::Revert { output, gas_used } => {
let revert_reason =
IBlockBuilderPolicy::IBlockBuilderPolicyErrors::abi_decode(&output)
.map(FlashtestationRevertReason::BlockBuilderPolicy)
.unwrap_or_else(|e| {
FlashtestationRevertReason::Unknown(hex::encode(output), e)
});
Ok(TxSimulateResult {
gas_used,
success: false,
state_changes: state,
revert_reason: Some(revert_reason),
logs: vec![],
})
}
ExecutionResult::Halt { reason, .. } => Ok(TxSimulateResult {
gas_used: 0,
success: false,
state_changes: state,
revert_reason: Some(FlashtestationRevertReason::Halt(reason)),
logs: vec![],
}),
}
}

fn check_verify_block_proof_log(&self, logs: &[Log]) -> bool {
for log in logs {
if log.topics().first() == Some(&BlockBuilderProofVerified::SIGNATURE_HASH) {
return true;
}
}
false
}

fn fund_tee_service_tx<ExtraCtx: Debug + Default>(
&self,
ctx: &OpPayloadBuilderCtx<ExtraCtx>,
evm: &mut OpEvm<
&mut State<StateProviderDatabase<impl StateProvider>>,
NoOpInspector,
PrecompilesMap,
>,
evm: &mut OpEvm<&mut State<impl Database + DatabaseRef>, NoOpInspector, PrecompilesMap>,
) -> Result<Option<BuilderTransactionCtx>, BuilderTransactionError> {
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment on line 140 indicates this function should be deprecated, but it's still being actively used in the codebase. Consider adding a deprecation timeline or tracking issue to the TODO comment to make it actionable.

Copilot uses AI. Check for mistakes.
Comment on lines +187 to +191
fn register_tee_service_tx(
&self,
ctx: &OpPayloadBuilderCtx<ExtraCtx>,
evm: &mut OpEvm<
&mut State<StateProviderDatabase<impl StateProvider>>,
NoOpInspector,
PrecompilesMap,
>,
) -> Result<(Option<BuilderTransactionCtx>, bool), BuilderTransactionError> {
let TxSimulateResult {
evm: &mut OpEvm<&mut State<impl Database + DatabaseRef>, NoOpInspector, PrecompilesMap>,
) -> Result<BuilderTransactionCtx, BuilderTransactionError> {
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment on line 186 indicates this function should be deprecated, but it's still actively used in non-permit code paths. Consider adding a deprecation timeline or migration plan to the TODO comment.

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +233
fn verify_block_proof_tx(
&self,
transactions: Vec<OpTransactionSigned>,
ctx: &OpPayloadBuilderCtx<ExtraCtx>,
evm: &mut OpEvm<
&mut State<StateProviderDatabase<impl StateProvider>>,
NoOpInspector,
PrecompilesMap,
>,
) -> Result<Option<BuilderTransactionCtx>, BuilderTransactionError> {
evm: &mut OpEvm<impl Database + DatabaseRef, NoOpInspector, PrecompilesMap>,
) -> Result<BuilderTransactionCtx, BuilderTransactionError> {
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment on line 227 says 'remove in favour of permit calls' but this function is still used in the non-permit code path. Consider clarifying whether this is a planned future removal or if both code paths will be maintained long-term.

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +85
// TODO: support permit with an external rpc, skip this step if using permit signatures
// since the permit txs are signed by the builder key and will result in nonce issues
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO describes a nonce issue limitation but doesn't provide a tracking issue or implementation plan. Consider adding a link to a GitHub issue or more specific implementation details about how external RPC support could be added.

Suggested change
// TODO: support permit with an external rpc, skip this step if using permit signatures
// since the permit txs are signed by the builder key and will result in nonce issues
// TODO: Support permit with an external RPC. See tracking issue: https://github.com/your-org/your-repo/issues/123
// Implementation plan: If using permit signatures, skip onchain registration since permit txs are signed by the builder key and will result in nonce issues.
// Instead, add logic to detect permit mode and bypass TxManager registration, relying on external RPC for permit validation and nonce management.

Copilot uses AI. Check for mistakes.
}
}

// TODO: remove and clean up in favour of simulate_call()
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO suggests removing this function in favor of simulate_call(), but the function is still actively used. Consider adding a timeline or tracking issue to make this TODO actionable, or update the implementation to use simulate_call() if feasible.

Suggested change
// TODO: remove and clean up in favour of simulate_call()
// TODO: remove and clean up in favour of simulate_call().
// Tracking issue: https://github.com/your-org/your-repo/issues/1234

Copilot uses AI. Check for mistakes.
@avalonche avalonche merged commit 663b981 into main Oct 22, 2025
4 checks passed
@avalonche avalonche deleted the flashtestations-permit branch October 22, 2025 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants