From 3575a617cbdf0b20725a4e5fff90bc904e5fc633 Mon Sep 17 00:00:00 2001 From: avalonche Date: Thu, 2 Oct 2025 08:39:52 +1000 Subject: [PATCH 1/2] Add flashtestations integration tests --- crates/op-rbuilder/Cargo.toml | 3 + crates/op-rbuilder/src/tests/flashblocks.rs | 12 +- .../op-rbuilder/src/tests/flashtestations.rs | 450 ++++++++++++++++++ .../framework/artifacts/genesis.json.tmpl | 6 + .../framework/artifacts/quote-output.bin | Bin 597 -> 597 bytes .../tests/framework/artifacts/test-quote.bin | Bin 5006 -> 5006 bytes .../src/tests/framework/instance.rs | 155 +++++- crates/op-rbuilder/src/tests/framework/mod.rs | 23 +- .../op-rbuilder/src/tests/framework/utils.rs | 63 ++- crates/op-rbuilder/src/tests/mod.rs | 17 + 10 files changed, 704 insertions(+), 25 deletions(-) create mode 100644 crates/op-rbuilder/src/tests/flashtestations.rs diff --git a/crates/op-rbuilder/Cargo.toml b/crates/op-rbuilder/Cargo.toml index c674691c4..8ae251460 100644 --- a/crates/op-rbuilder/Cargo.toml +++ b/crates/op-rbuilder/Cargo.toml @@ -192,6 +192,9 @@ testing = [ "ctor", "macros", "rlimit", + "hyper", + "hyper-util", + "http-body-util", ] interop = [] diff --git a/crates/op-rbuilder/src/tests/flashblocks.rs b/crates/op-rbuilder/src/tests/flashblocks.rs index f3e46dae5..781048283 100644 --- a/crates/op-rbuilder/src/tests/flashblocks.rs +++ b/crates/op-rbuilder/src/tests/flashblocks.rs @@ -1,8 +1,7 @@ use alloy_consensus::Transaction; use alloy_eips::Decodable2718; -use alloy_primitives::{Address, TxHash, U256, address, b128, b256}; +use alloy_primitives::{Address, TxHash, U256}; use alloy_provider::Provider; -use alloy_sol_types::SolCall; use macros::rb_test; use op_alloy_consensus::OpTxEnvelope; use std::time::Duration; @@ -10,16 +9,11 @@ use std::time::Duration; use crate::{ args::{FlashblocksArgs, OpRbuilderArgs}, tests::{ - BUILDER_PRIVATE_KEY, BlockTransactionsExt, BundleOpts, ChainDriver, ChainDriverExt, - FUNDED_PRIVATE_KEY, LocalInstance, ONE_ETH, TransactionBuilderExt, - flashblocks_number_contract::FlashblocksNumber, + BlockTransactionsExt, BundleOpts, ChainDriver, FLASHBLOCKS_NUMBER_ADDRESS, LocalInstance, + TransactionBuilderExt, flashblocks_number_contract::FlashblocksNumber, }, - tx_signer::Signer, }; -// If the order of deployment from the signer changes the address will change -const FLASHBLOCKS_NUMBER_ADDRESS: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); - #[rb_test(flashblocks, args = OpRbuilderArgs { chain_block_time: 2000, flashblocks: FlashblocksArgs { diff --git a/crates/op-rbuilder/src/tests/flashtestations.rs b/crates/op-rbuilder/src/tests/flashtestations.rs new file mode 100644 index 000000000..c4e0eaed9 --- /dev/null +++ b/crates/op-rbuilder/src/tests/flashtestations.rs @@ -0,0 +1,450 @@ +use alloy_consensus::Transaction; +use alloy_network::TransactionResponse; +use alloy_primitives::{Address, U256}; +use alloy_provider::{Provider, RootProvider}; +use macros::{if_flashblocks, if_standard, rb_test}; +use op_alloy_network::Optimism; + +use crate::{ + args::{FlashblocksArgs, OpRbuilderArgs}, + flashtestations::args::FlashtestationsArgs, + tests::{ + BLOCK_BUILDER_POLICY_ADDRESS, BundleOpts, ChainDriver, ChainDriverExt, + FLASHBLOCKS_NUMBER_ADDRESS, FLASHTESTATION_REGISTRY_ADDRESS, LocalInstance, + MOCK_DCAP_ADDRESS, TEE_DEBUG_ADDRESS, TransactionBuilderExt, + flashblocks_number_contract::FlashblocksNumber, + flashtestation_registry::FlashtestationRegistry, flashtestations_signer, + }, +}; + +#[rb_test(args = OpRbuilderArgs { + chain_block_time: 1000, + enable_revert_protection: true, + flashtestations: FlashtestationsArgs { + flashtestations_enabled: true, + registry_address: Some(FLASHTESTATION_REGISTRY_ADDRESS), + builder_policy_address: Some(BLOCK_BUILDER_POLICY_ADDRESS), + funding_key: Some(flashtestations_signer()), + debug: true, + ..Default::default() + }, + ..Default::default() +})] +async fn test_flashtestations_registrations(rbuilder: LocalInstance) -> eyre::Result<()> { + let driver = rbuilder.driver().await?; + let provider = rbuilder.provider().await?; + setup_flashtestation_contracts(&driver, &provider, true).await?; + let block: alloy_rpc_types_eth::Block = + driver.build_new_block_with_current_timestamp(None).await?; + // check the builder tx, funding tx and registration tx is in the block + let num_txs = block.transactions.len(); + assert!(num_txs >= 3, "Expected at least 3 transactions in block"); + println!( + "block transactions {:#?}", + &block.transactions.clone().into_transactions_vec() + ); + let last_3_txs = &block.transactions.into_transactions_vec()[num_txs - 3..]; + // Check builder tx + assert_eq!( + last_3_txs[0].to(), + Some(Address::ZERO), + "builder tx should send to zero address" + ); + // Check funding tx + assert_eq!( + last_3_txs[1].to(), + Some(TEE_DEBUG_ADDRESS), + "funding tx should send to tee address" + ); + assert!( + last_3_txs[1] + .value() + .eq(&rbuilder.args().flashtestations.funding_amount), + "funding tx should have correct amount" + ); + // Check registration tx + assert_eq!( + last_3_txs[2].to(), + Some(FLASHTESTATION_REGISTRY_ADDRESS), + "registration tx should call registry" + ); + let contract = FlashtestationRegistry::new(FLASHTESTATION_REGISTRY_ADDRESS, provider.clone()); + let result = contract.getRegistration(TEE_DEBUG_ADDRESS).call().await?; + assert!(result._1.isValid, "The tee key is not registered"); + + // check builder does not try to register again + let block = driver.build_new_block_with_current_timestamp(None).await?; + let num_txs = block.transactions.len(); + if_flashblocks!( + assert!(num_txs == 3, "Expected at 3 transactions in block"); // deposit + 2 builder tx + ); + if_standard!( + assert!(num_txs == 2, "Expected at 2 transactions in block"); // deposit + builder tx + ); + + Ok(()) +} + +#[rb_test(args = OpRbuilderArgs { + chain_block_time: 1000, + enable_revert_protection: true, + flashtestations: FlashtestationsArgs { + flashtestations_enabled: true, + registry_address: Some(FLASHTESTATION_REGISTRY_ADDRESS), + builder_policy_address: Some(BLOCK_BUILDER_POLICY_ADDRESS), + funding_key: Some(flashtestations_signer()), + debug: true, + enable_block_proofs: true, + ..Default::default() + }, + ..Default::default() +})] +async fn test_flashtestations_block_proofs(rbuilder: LocalInstance) -> eyre::Result<()> { + let driver = rbuilder.driver().await?; + let provider = rbuilder.provider().await?; + setup_flashtestation_contracts(&driver, &provider, true).await?; + driver.build_new_block_with_current_timestamp(None).await?; + + // check registered + let contract = FlashtestationRegistry::new(FLASHTESTATION_REGISTRY_ADDRESS, provider.clone()); + let result = contract.getRegistration(TEE_DEBUG_ADDRESS).call().await?; + assert!(result._1.isValid, "The tee key is not registered"); + + // check that only the builder tx and block proof is in the block + let (tx_hash, block) = driver.build_new_block_with_valid_transaction().await?; + let txs = block.transactions.into_transactions_vec(); + + if_flashblocks!( + assert_eq!(txs.len(), 5, "Expected at 4 transactions in block"); // deposit + valid tx + 2 builder tx + end of block proof + // Check builder tx + assert_eq!( + txs[1].to(), + Some(Address::ZERO), + "builder tx should send to zero address" + ); + ); + if_standard!( + assert_eq!(txs.len(), 4, "Expected at 4 transactions in block"); // deposit + valid tx + builder tx + end of block proof + ); + let last_3_txs = &txs[txs.len() - 3..]; + // Check valid transaction + assert_eq!( + last_3_txs[0].inner.tx_hash(), + tx_hash, + "tx hash for valid transaction should match" + ); + // Check builder tx + assert_eq!( + last_3_txs[1].to(), + Some(Address::ZERO), + "builder tx should send to zero address" + ); + // Check builder proof + assert_eq!( + last_3_txs[2].to(), + Some(BLOCK_BUILDER_POLICY_ADDRESS), + "builder tx should send to zero address" + ); + Ok(()) +} + +#[rb_test(flashblocks, args = OpRbuilderArgs { + chain_block_time: 1000, + enable_revert_protection: true, + flashblocks: FlashblocksArgs { + flashblocks_number_contract_address: Some(FLASHBLOCKS_NUMBER_ADDRESS), + ..Default::default() + }, + flashtestations: FlashtestationsArgs { + flashtestations_enabled: true, + registry_address: Some(FLASHTESTATION_REGISTRY_ADDRESS), + builder_policy_address: Some(BLOCK_BUILDER_POLICY_ADDRESS), + funding_key: Some(flashtestations_signer()), + debug: true, + enable_block_proofs: true, + ..Default::default() + }, + ..Default::default() +})] +async fn test_flashtestations_with_number_contract(rbuilder: LocalInstance) -> eyre::Result<()> { + let driver = rbuilder.driver().await?; + let provider = rbuilder.provider().await?; + setup_flashblock_number_contract(&driver, &provider, true).await?; + setup_flashtestation_contracts(&driver, &provider, true).await?; + let tx = driver + .create_transaction() + .random_valid_transfer() + .with_bundle(BundleOpts::default().with_flashblock_number_min(4)) + .send() + .await?; + let block = driver.build_new_block_with_current_timestamp(None).await?; + // 1 deposit tx, 1 fallback builder tx, 4 flashblocks number tx, valid tx, funding tx, registration tx, block proof + let txs = block.transactions.into_transactions_vec(); + assert_eq!(txs.len(), 10, "Expected at 10 transactions in block"); + // Check builder tx + assert_eq!( + txs[1].to(), + Some(Address::ZERO), + "fallback builder tx should send to zero address" + ); + // flashblocks number contract + for i in 2..6 { + assert_eq!( + txs[i].to(), + Some(FLASHBLOCKS_NUMBER_ADDRESS), + "builder tx should send to flashblocks number contract" + ); + } + // check regular tx + assert_eq!( + txs[6].tx_hash(), + *tx.tx_hash(), + "bundle tx was not in block" + ); + // check funding, registration and block proof tx + assert_eq!( + txs[7].to(), + Some(TEE_DEBUG_ADDRESS), + "funding tx should send to tee address" + ); + assert_eq!( + txs[8].to(), + Some(FLASHTESTATION_REGISTRY_ADDRESS), + "registration tx should call registry" + ); + assert_eq!( + txs[9].to(), + Some(BLOCK_BUILDER_POLICY_ADDRESS), + "block proof tx should call block policy address" + ); + + // add a user transaciton to ensure the flashblock number builder tx is top of block + let tx = driver + .create_transaction() + .random_valid_transfer() + .with_bundle(BundleOpts::default().with_flashblock_number_min(4)) + .send() + .await?; + let block = driver.build_new_block_with_current_timestamp(None).await?; + // check the flashblocks number tx and block proof is in the block + let txs = block.transactions.into_transactions_vec(); + assert_eq!(txs.len(), 8, "Expected at 5 transactions in block"); + // Check builder tx + assert_eq!( + txs[1].to(), + Some(Address::ZERO), + "fallback builder tx should send to zero address" + ); + // flashblocks number contract + for i in 2..6 { + assert_eq!( + txs[i].to(), + Some(FLASHBLOCKS_NUMBER_ADDRESS), + "builder tx should send to flashblocks number contract" + ); + } + // user tx + assert_eq!( + txs[6].tx_hash(), + *tx.tx_hash(), + "bundle tx was not in block" + ); + // block proof + assert_eq!( + txs[7].to(), + Some(BLOCK_BUILDER_POLICY_ADDRESS), + "block proof tx should call block policy address" + ); + + let contract = FlashtestationRegistry::new(FLASHTESTATION_REGISTRY_ADDRESS, provider.clone()); + let result = contract.getRegistration(TEE_DEBUG_ADDRESS).call().await?; + assert!(result._1.isValid, "The tee key is not registered"); + // Verify flashblock number incremented correctly + let contract = FlashblocksNumber::new(FLASHBLOCKS_NUMBER_ADDRESS, provider.clone()); + let current_number = contract.getFlashblockNumber().call().await?; + assert!( + current_number.gt(&U256::from(8)), // contract deployments incremented the number but we built at least 2 full blocks + "Flashblock number not incremented" + ); + Ok(()) +} + +async fn setup_flashtestation_contracts( + driver: &ChainDriver, + provider: &RootProvider, + authorize_workload: bool, +) -> eyre::Result<()> { + // deploy the mock contract and register a mock quote + let mock_dcap_deploy_tx = driver + .create_transaction() + .deploy_mock_dcap_contract() + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // Add test quote + let mock_quote_tx = driver + .create_transaction() + .add_mock_quote() + .with_to(MOCK_DCAP_ADDRESS) + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // deploy the flashtestations registry contract + let flashtestations_registry_tx = driver + .create_transaction() + .deploy_flashtestation_registry_contract() + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // init the flashtestation registry contract + let init_registry = driver + .create_transaction() + .init_flashtestation_registry_contract(MOCK_DCAP_ADDRESS) + .with_to(FLASHTESTATION_REGISTRY_ADDRESS) + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // deploy the block builder policy contract + let block_builder_policy_tx = driver + .create_transaction() + .deploy_builder_policy_contract() + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // init the builder block policy contract + let init_builder_policy = driver + .create_transaction() + .init_builder_policy_contract(FLASHTESTATION_REGISTRY_ADDRESS) + .with_to(BLOCK_BUILDER_POLICY_ADDRESS) + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // include the deployment and initialization in a block + driver.build_new_block_with_current_timestamp(None).await?; + + if authorize_workload { + // add the workload id to the block builder policy + let add_workload = driver + .create_transaction() + .add_workload_to_policy() + .with_to(BLOCK_BUILDER_POLICY_ADDRESS) + .with_bundle(BundleOpts::default()) + .send() + .await?; + driver.build_new_block_with_current_timestamp(None).await?; + provider + .get_transaction_receipt(*add_workload.tx_hash()) + .await? + .expect("add workload to builder policy tx not mined"); + } + + // Verify mock dcap contract deployment + let receipt = provider + .get_transaction_receipt(*mock_dcap_deploy_tx.tx_hash()) + .await? + .expect("mock dcap contract deployment not mined"); + let mock_dcap_address = receipt + .inner + .contract_address + .expect("contract receipt does not contain flashblock number contract address"); + assert_eq!( + mock_dcap_address, MOCK_DCAP_ADDRESS, + "mock dcap contract address mismatch" + ); + // verify mock quote added + provider + .get_transaction_receipt(*mock_quote_tx.tx_hash()) + .await? + .expect("add mock quote not mined"); + // verify flashtestations registry contract deployment + let receipt = provider + .get_transaction_receipt(*flashtestations_registry_tx.tx_hash()) + .await?; + let flashtestations_registry_address = receipt + .expect("flashtestations registry contract deployment not mined") + .inner + .contract_address + .expect("contract receipt does not contain flashtestations registry contract address"); + assert_eq!( + flashtestations_registry_address, FLASHTESTATION_REGISTRY_ADDRESS, + "flashtestations registry contract address mismatch" + ); + // verify flashtestations registry contract initialization + provider + .get_transaction_receipt(*init_registry.tx_hash()) + .await? + .expect("init registry tx not mined"); + + // verify block builder policy contract deployment + let receipt = provider + .get_transaction_receipt(*block_builder_policy_tx.tx_hash()) + .await?; + let block_builder_policy_address = receipt + .expect("block builder policy contract deployment not mined") + .inner + .contract_address + .expect("contract receipt does not contain block builder policy contract address"); + assert_eq!( + block_builder_policy_address, BLOCK_BUILDER_POLICY_ADDRESS, + "block builder policy contract address mismatch" + ); + // verify block builder policy contract initialization + provider + .get_transaction_receipt(*init_builder_policy.tx_hash()) + .await? + .expect("init builder policy tx not mined"); + + Ok(()) +} + +async fn setup_flashblock_number_contract( + driver: &ChainDriver, + provider: &RootProvider, + authorize_builder: bool, +) -> eyre::Result<()> { + // Deploy flashblocks number contract + let deploy_tx = driver + .create_transaction() + .deploy_flashblock_number_contract() + .with_bundle(BundleOpts::default()) + .send() + .await?; + + // Initialize contract + let init_tx = driver + .create_transaction() + .init_flashblock_number_contract(authorize_builder) + .with_to(FLASHBLOCKS_NUMBER_ADDRESS) + .with_bundle(BundleOpts::default()) + .send() + .await?; + driver.build_new_block_with_current_timestamp(None).await?; + + // Verify contract deployment + let receipt = provider + .get_transaction_receipt(*deploy_tx.tx_hash()) + .await? + .expect("flashblock number contract deployment not mined"); + let contract_address = receipt + .inner + .contract_address + .expect("contract receipt does not contain flashblock number contract address"); + assert_eq!( + contract_address, FLASHBLOCKS_NUMBER_ADDRESS, + "Flashblocks number contract address mismatch" + ); + + // Verify initialization + provider + .get_transaction_receipt(*init_tx.tx_hash()) + .await? + .expect("init tx not mined"); + + Ok(()) +} diff --git a/crates/op-rbuilder/src/tests/framework/artifacts/genesis.json.tmpl b/crates/op-rbuilder/src/tests/framework/artifacts/genesis.json.tmpl index dddb61d7a..39a6f53e2 100644 --- a/crates/op-rbuilder/src/tests/framework/artifacts/genesis.json.tmpl +++ b/crates/op-rbuilder/src/tests/framework/artifacts/genesis.json.tmpl @@ -869,6 +869,12 @@ "fabb0ac9d68b0b445fb7357272ff202c5651694a": { "balance": "0x21e19e0c9bab2400000" }, + "23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": { + "balance": "0x21e19e0c9bab2400000" + }, + "a0ee7a142d267c1f36714e4a8f75612f20a79720": { + "balance": "0x21e19e0c9bab2400000" + }, "fb1bffc9d739b8d520daf37df666da4c687191ea": { "code": "0x6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506126fc565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b810190808035906020019092919080359060200190929190505050612732565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b81019080803590602001909291905050506127b9565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127d1565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612b63565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612c9d565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612edc565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f01565b005b348015610d3457600080fd5b50610d3d612f90565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613139565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061313f565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613161565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff16906020019092919050505061331f565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613447565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613639565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137d8565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613805565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c1a565b005b34801561148957600080fd5b5061149261428c565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614296565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061443e565b005b3480156116a457600080fd5b506116ad61449f565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061451d565b005b34801561174a57600080fd5b50611753614950565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614989565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612b63565b5b5050565b611bd2604182614a2c90919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614a66565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614a2c90919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614a9590919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614a9590919063ffffffff16565b614a9590919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183600181111561266b57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156126a857808201518184015260208101905061268d565b50505050905090810190601f1680156126d55780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a16126f285858585614ab4565b9050949350505050565b6000606061270c868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561275057600080fd5b506040519080825280601f01601f1916602001820160405280156127835781602001600182028036833780820191505090505b50905060005b838110156127ae57808501548060208302602085010152508080600101915050612789565b508091505092915050565b60076020528060005260406000206000915090505481565b6127d9614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156128435750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6128b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612b6b614989565b600354811115612be3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612c5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612d5057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b83811015612e0a578082015181840152602081019050612def565b50505050905090810190601f168015612e375780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015612e70578082015181840152602081019050612e55565b50505050905090810190601f168015612e9d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a1612eca8d8d8d8d8d8d8d8d8d8d8d614c9a565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111612f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f8a84848484611bbe565b50505050565b6060600060035467ffffffffffffffff81118015612fad57600080fd5b50604051908082528060200260200182016040528015612fdc5781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613130578083838151811061308757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613046565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6131ac8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050896151d7565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146131ea576131e9846156d7565b5b6132388787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615706565b60008211156132525761325082600060018685615941565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a9050613376878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615b47565b61337f57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561340c5780820151818401526020810190506133f1565b50505050905090810190601f1680156134395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561346257600080fd5b506040519080825280602002602001820160405280156134915781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135645750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561356f57508482105b1561362a578084838151811061358157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506134fa565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561373b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006137ed8c8c8c8c8c8c8c8c8c8c8c614296565b8051906020012090509b9a5050505050505050505050565b61380d614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138775750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6138e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613b9e614989565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613c22614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c8c5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613cc457503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613d36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613ea15750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613f13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561432757fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6143b361449f565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b614446614989565b61444f816156d7565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6144cd6125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614525614989565b8060016003540310156145a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561460a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61467c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461477c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461494b5761494a81612b63565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614a2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614a3f5760009050614a60565b6000828402905082848281614a5057fe5b0414614a5b57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614aaa57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614b7f5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614bf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614bfe858585855a615b47565b90508015614c4e573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614c92565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614cb48e8e8e8e8e8e8e8e8e8e600554614296565b905060056000815480929190600101919050555080805190602001209150614cdd828286612f01565b506000614ce8615b93565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614ece578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115614d8b57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015614e5d578082015181840152602081019050614e42565b50505050905090810190601f168015614e8a5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015614eb557600080fd5b505af1158015614ec9573d6000803e3d6000fd5b505050505b6101f4614ef56109c48b01603f60408d0281614ee657fe5b04615bc490919063ffffffff16565b015a1015614f6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a9050614fd48f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d14614fc9578e614fcf565b6109c45a035b615b47565b9350614fe95a82615bde90919063ffffffff16565b90508380614ff8575060008a14155b80615004575060008814155b615076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808911156150905761508d828b8b8b8b615941565b90505b84156150da577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a161511a565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151c6578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156151ad57600080fd5b505af11580156151c1573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b60006004541461524f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81518111156152c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600181101561533d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b835181101561564357600084828151811061535d57fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153d15750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561540957503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561544157508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6154b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146155b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615346565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615808576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461593d576158ca8260008360015a615b47565b61593c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461597e5782615980565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615a98576159ea3a86106159c7573a6159c9565b855b6159dc888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615b3d565b615abd85615aaf888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b9150615aca848284615bfe565b615b3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615b5557fe5b836001811115615b6157fe5b1415615b7a576000808551602087018986f49050615b8a565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615bd45781615bd6565b825b905092915050565b600082821115615bed57600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615ca55760208114615cad5760009350615cb8565b819350615cb8565b600051158215171593505b505050939250505056fea2646970667358221220047fac33099ca576d1c4f1ac6a8abdb0396e42ad6a397d2cb2f4dc1624cc0c5b64736f6c63430007060033", "balance": "0x0", diff --git a/crates/op-rbuilder/src/tests/framework/artifacts/quote-output.bin b/crates/op-rbuilder/src/tests/framework/artifacts/quote-output.bin index 84b2c09b7eddca45fc903018179882d6a9ba4ac8..70a42bbf551977f685c409f3e180f7414160aa2e 100644 GIT binary patch delta 72 zcmcc0a+PI+D3e3hN6$~`51;A&ahBJ8cJJMBC3m+kM=!ZCwtZK&nN(N1>CSQH15X*Y V1)pkCx32zmgC(|gNdW^A000Yv9+Ut8 delta 31 ncmcc0a+PI+D3eIR%*ukJ5<+*Z7Ez?F;E8pvXKiS diff --git a/crates/op-rbuilder/src/tests/framework/artifacts/test-quote.bin b/crates/op-rbuilder/src/tests/framework/artifacts/test-quote.bin index 057f9ed2d79147c67882abdb43fc9a927869e19d..aea0077d4f1f781b044dc52df472195762f46c16 100644 GIT binary patch delta 146 zcmeBE?^EAk!Bp?KR{NNhLgdeF%E7kn|7Ld7R(iM}z2wH&_FdU#QeEw)JI9$1JZ0Dx ze5y&^y871*me|%M1q?{wi~s|}P5zUbf0|!SQdr~PBvU?p!>kv6=8m&V3hkzwC-JCE u-ty!o1K*Uu13J$`+&0bJe_3|kMM-u|^<-O}iwdl7_srfDuz3&DB>@14MLk;p delta 105 zcmV-v0G9ubCypnuI06)KnR#%<7!uq%0StWswGIsz+, pool_observer: TransactionPoolObserver, + attestation_server: Option, } impl LocalInstance { @@ -92,6 +100,15 @@ impl LocalInstance { args.builder_signer = Some(signer); args.rollup_args.enable_tx_conditional = true; + let attestation_server = if args.flashtestations.flashtestations_enabled { + let server = spawn_attestation_provider().await?; + args.flashtestations.quote_provider = Some(server.url()); + tracing::info!("Started attestation server at {}", server.url()); + Some(server) + } else { + None + }; + let builder_config = BuilderConfig::::try_from(args.clone()) .expect("Failed to convert rollup args to builder config"); let da_config = builder_config.da_config.clone(); @@ -168,6 +185,7 @@ impl LocalInstance { _node_handle: node_handle, task_manager: Some(task_manager), pool_observer: TransactionPoolObserver::new(pool_monitor, reverted_cache_clone), + attestation_server, }) } @@ -244,6 +262,10 @@ impl LocalInstance { &self.pool_observer } + pub const fn attestation_server(&self) -> &Option { + &self.attestation_server + } + pub async fn driver(&self) -> eyre::Result> { ChainDriver::::local(self).await } @@ -349,6 +371,13 @@ fn pool_component(args: &OpRbuilderArgs) -> OpPoolBuilder { ) } +async fn spawn_attestation_provider() -> eyre::Result { + let quote = include_bytes!("./artifacts/test-quote.bin"); + let mut service = AttestationServer::new(TEE_DEBUG_ADDRESS, Bytes::new(), quote.into()); + service.start().await?; + Ok(service) +} + /// A utility for listening to flashblocks WebSocket messages during tests. /// /// This provides a reusable way to capture and inspect flashblocks that are produced @@ -443,3 +472,119 @@ impl FlashblocksListener { self.handle.await? } } + +/// A utility service to spawn a server that returns a mock quote for an attestation request +pub struct AttestationServer { + tee_address: Address, + extra_registration_data: Bytes, + mock_attestation: Bytes, + server_handle: Option>, + shutdown_tx: Option>, + port: u16, + error_on_request: bool, +} + +impl AttestationServer { + pub fn new( + tee_address: Address, + extra_registration_data: Bytes, + mock_attestation: Bytes, + ) -> Self { + AttestationServer { + tee_address, + extra_registration_data, + mock_attestation, + server_handle: None, + shutdown_tx: None, + port: 0, + error_on_request: false, + } + } + + pub fn set_error(&mut self, error: bool) { + self.error_on_request = error; + } + + pub async fn start(&mut self) -> eyre::Result { + self.port = get_available_port(); + let addr = SocketAddr::from(([127, 0, 0, 1], self.port)); + let listener = TcpListener::bind(addr).await?; + + let mock_attestation = self.mock_attestation.clone(); + // Concatenate tee_address bytes and extra_registration_data bytes, then hex encode + let combined = [ + self.tee_address.as_slice(), // 20 bytes address + keccak256(self.extra_registration_data.clone()).as_slice(), // 32 byte hash + &[0u8; 12], // padding to 64 bytes + ] + .concat(); + let set_error = self.error_on_request; + + let (shutdown_tx, mut shutdown_rx) = oneshot::channel::<()>(); + self.shutdown_tx = Some(shutdown_tx); + + // Create the service + self.server_handle = Some(tokio::spawn(async move { + loop { + let mock_attestation = mock_attestation.clone(); + let expected_path = format!("/{}", hex::encode(&combined)); + tokio::select! { + // Handle shutdown signal + _ = &mut shutdown_rx => { + break; + } + result = listener.accept() => { + let (stream, _) = result.expect("failed to accept attestation request"); + + tokio::task::spawn(async move { + let service = service_fn(move |req: Request| { + let response = + if set_error { + Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Full::new(HyperBytes::new())) + .unwrap() + } + else if req.uri().path() == expected_path { + Response::builder() + .header("content-type", "application/octet-stream") + .body(Full::new(mock_attestation.clone().into())) + .unwrap() + } else { + Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Full::new(HyperBytes::new())) + .unwrap() + }; + async { Ok::<_, hyper::Error>(response) } + }); + + let io = TokioIo::new(stream); + if let Err(err) = http1::Builder::new().serve_connection(io, service).await { + tracing::error!(message = "Error serving attestations", error = %err); + } + }); + } + } + } + })); + + // Give the spawned task a chance to start + tokio::task::yield_now().await; + + Ok(self.port) + } + + pub fn url(&self) -> String { + format!("http://127.0.0.1:{}", self.port) + } +} + +impl Drop for AttestationServer { + fn drop(&mut self) { + if let Some(tx) = self.shutdown_tx.take() { + let _ = tx.send(()); + } + tracing::info!("AttestationServer dropped, terminating server"); + } +} diff --git a/crates/op-rbuilder/src/tests/framework/mod.rs b/crates/op-rbuilder/src/tests/framework/mod.rs index 4e3171fb9..26e24f0de 100644 --- a/crates/op-rbuilder/src/tests/framework/mod.rs +++ b/crates/op-rbuilder/src/tests/framework/mod.rs @@ -6,6 +6,7 @@ mod instance; mod txs; mod utils; +use alloy_primitives::{B256, b256}; pub use apis::*; pub use contracts::*; pub use driver::*; @@ -14,11 +15,18 @@ pub use instance::*; pub use txs::*; pub use utils::*; +// anvil default key[1] pub const BUILDER_PRIVATE_KEY: &str = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; - +// anvil default key[0] pub const FUNDED_PRIVATE_KEY: &str = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; +// anvil default key[8] +pub const FLASHBLOCKS_DEPLOY_KEY: &str = + "0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97"; +// anvil default key[9] +pub const FLASHTESTATION_DEPLOY_KEY: &str = + "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"; pub const DEFAULT_GAS_LIMIT: u64 = 10_000_000; @@ -27,6 +35,19 @@ pub const DEFAULT_JWT_TOKEN: &str = pub const ONE_ETH: u128 = 1_000_000_000_000_000_000; +// flashtestations constants +pub const TEE_DEBUG_ADDRESS: alloy_primitives::Address = + alloy_primitives::address!("6Af149F267e1e62dFc431F2de6deeEC7224746f4"); + +pub const WORKLOAD_ID: B256 = + b256!("f724e7d117f5655cf33beefdfc7d31e930278fcb65cf6d1de632595e97ca82b2"); + +pub const SOURCE_LOCATORS: &[&str] = &[ + "https://github.com/flashbots/flashbots-images/commit/53d431f58a0d1a76f6711518ef8d876ce8181fc2", +]; + +pub const COMMIT_HASH: &str = "53d431f58a0d1a76f6711518ef8d876ce8181fc2"; + /// This gets invoked before any tests, when the cargo test framework loads the test library. /// It injects itself into #[ctor::ctor] diff --git a/crates/op-rbuilder/src/tests/framework/utils.rs b/crates/op-rbuilder/src/tests/framework/utils.rs index 764b3fa31..35a5f2a51 100644 --- a/crates/op-rbuilder/src/tests/framework/utils.rs +++ b/crates/op-rbuilder/src/tests/framework/utils.rs @@ -1,6 +1,7 @@ use crate::{ tests::{ - BUILDER_PRIVATE_KEY, Protocol, block_builder_policy::BlockBuilderPolicy, + BUILDER_PRIVATE_KEY, COMMIT_HASH, FLASHBLOCKS_DEPLOY_KEY, FLASHTESTATION_DEPLOY_KEY, + Protocol, SOURCE_LOCATORS, WORKLOAD_ID, block_builder_policy::BlockBuilderPolicy, flashblocks_number_contract::FlashblocksNumber, flashtestation_registry::FlashtestationRegistry, framework::driver::ChainDriver, mock_dcap_attestation::MockAutomataDcapAttestationFee, @@ -37,6 +38,7 @@ pub trait TransactionBuilderExt { fn init_flashtestation_registry_contract(self, dcap_address: Address) -> Self; fn deploy_builder_policy_contract(self) -> Self; fn init_builder_policy_contract(self, registry_address: Address) -> Self; + fn add_workload_to_policy(self) -> Self; fn deploy_mock_dcap_contract(self) -> Self; fn add_mock_quote(self) -> Self; } @@ -62,11 +64,12 @@ impl TransactionBuilderExt for TransactionBuilder { self.with_create() .with_input(FlashblocksNumber::BYTECODE.clone()) .with_gas_limit(2_000_000) // deployment costs ~1.6 million gas + .with_signer(flashblocks_number_signer()) } fn init_flashblock_number_contract(self, register_builder: bool) -> Self { let builder_signer = builder_signer(); - let owner = funded_signer(); + let owner = flashblocks_number_signer(); let init_data = FlashblocksNumber::initializeCall { _owner: owner.address, @@ -79,16 +82,18 @@ impl TransactionBuilderExt for TransactionBuilder { .abi_encode(); self.with_input(init_data.into()) + .with_signer(flashblocks_number_signer()) } fn deploy_flashtestation_registry_contract(self) -> Self { self.with_create() .with_input(FlashtestationRegistry::BYTECODE.clone()) - .with_gas_limit(1_000_000) + .with_gas_limit(5_000_000) + .with_signer(flashtestations_signer()) } fn init_flashtestation_registry_contract(self, dcap_address: Address) -> Self { - let owner = funded_signer(); + let owner = flashtestations_signer(); let init_data = FlashtestationRegistry::initializeCall { owner: owner.address, @@ -96,17 +101,18 @@ impl TransactionBuilderExt for TransactionBuilder { } .abi_encode(); - self.with_input(init_data.into()) + self.with_input(init_data.into()).with_signer(owner) } fn deploy_builder_policy_contract(self) -> Self { self.with_create() .with_input(BlockBuilderPolicy::BYTECODE.clone()) - .with_gas_limit(1_000_000) + .with_gas_limit(3_000_000) + .with_signer(flashtestations_signer()) } fn init_builder_policy_contract(self, registry_address: Address) -> Self { - let owner = funded_signer(); + let owner = flashtestations_signer(); let init_data = BlockBuilderPolicy::initializeCall { _initialOwner: owner.address, @@ -115,12 +121,29 @@ impl TransactionBuilderExt for TransactionBuilder { .abi_encode(); self.with_input(init_data.into()) + .with_signer(flashtestations_signer()) + } + + fn add_workload_to_policy(self) -> Self { + let workload = BlockBuilderPolicy::addWorkloadToPolicyCall { + workloadId: WORKLOAD_ID, + commitHash: COMMIT_HASH.to_string(), + sourceLocators: SOURCE_LOCATORS + .iter() + .map(|source| source.to_string()) + .collect(), + } + .abi_encode(); + + self.with_input(workload.into()) + .with_signer(flashtestations_signer()) } fn deploy_mock_dcap_contract(self) -> Self { self.with_create() .with_input(MockAutomataDcapAttestationFee::BYTECODE.clone()) .with_gas_limit(1_000_000) + .with_signer(flashtestations_signer()) } fn add_mock_quote(self) -> Self { @@ -133,7 +156,9 @@ impl TransactionBuilderExt for TransactionBuilder { _output: include_bytes!("./artifacts/quote-output.bin").into(), } .abi_encode(); - self.with_input(quote.into()).with_gas_limit(500_000) + self.with_input(quote.into()) + .with_gas_limit(500_000) + .with_signer(flashtestations_signer()) } } @@ -163,7 +188,7 @@ pub trait ChainDriverExt { &self, ) -> impl Future)>>; - fn build_new_block_with_reverrting_transaction( + fn build_new_block_with_reverting_transaction( &self, ) -> impl Future)>>; } @@ -226,7 +251,7 @@ impl ChainDriverExt for ChainDriver

{ Ok((*tx.tx_hash(), self.build_new_block().await?)) } - async fn build_new_block_with_reverrting_transaction( + async fn build_new_block_with_reverting_transaction( &self, ) -> eyre::Result<(TxHash, Block)> { let tx = self @@ -337,3 +362,21 @@ pub fn funded_signer() -> Signer { ) .expect("Failed to create signer from hardcoded funded private key") } + +pub fn flashblocks_number_signer() -> Signer { + Signer::try_from_secret( + FLASHBLOCKS_DEPLOY_KEY + .parse() + .expect("invalid hardcoded flashblocks number deployer private key"), + ) + .expect("Failed to create signer from hardcoded flashblocks number deployer private key") +} + +pub fn flashtestations_signer() -> Signer { + Signer::try_from_secret( + FLASHTESTATION_DEPLOY_KEY + .parse() + .expect("invalid hardcoded flashtestations deployer private key"), + ) + .expect("Failed to create signer from hardcoded flashtestations deployer private key") +} diff --git a/crates/op-rbuilder/src/tests/mod.rs b/crates/op-rbuilder/src/tests/mod.rs index f32eccb61..cb5646f84 100644 --- a/crates/op-rbuilder/src/tests/mod.rs +++ b/crates/op-rbuilder/src/tests/mod.rs @@ -5,6 +5,9 @@ pub use framework::*; #[cfg(test)] mod flashblocks; +#[cfg(test)] +mod flashtestations; + #[cfg(test)] mod data_availability; @@ -22,3 +25,17 @@ mod smoke; #[cfg(test)] mod txpool; + +// If the order of deployment from the signer changes the address will change +#[cfg(test)] +const FLASHBLOCKS_NUMBER_ADDRESS: alloy_primitives::Address = + alloy_primitives::address!("95bd8d42f30351685e96c62eddc0d0613bf9a87a"); +#[cfg(test)] +const MOCK_DCAP_ADDRESS: alloy_primitives::Address = + alloy_primitives::address!("700b6a60ce7eaaea56f065753d8dcb9653dbad35"); +#[cfg(test)] +const FLASHTESTATION_REGISTRY_ADDRESS: alloy_primitives::Address = + alloy_primitives::address!("b19b36b1456e65e3a6d514d3f715f204bd59f431"); +#[cfg(test)] +const BLOCK_BUILDER_POLICY_ADDRESS: alloy_primitives::Address = + alloy_primitives::address!("e1aa25618fa0c7a1cfdab5d6b456af611873b629"); From 260cb95cd8aec98156018ae51083f4ae18d52a6b Mon Sep 17 00:00:00 2001 From: avalonche Date: Fri, 3 Oct 2025 05:14:34 +1000 Subject: [PATCH 2/2] logging improvements --- README.md | 4 ++-- crates/op-rbuilder/src/flashtestations/attestation.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 599f360c4..2b3092433 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ This will increment the flashblock number before the start of every flashblock a To run op-rbuilder with flashtestations: ```bash -cargo run -p op-rbuilder --bin op-rbuilder --features=flashtestations -- node \ +cargo run -p op-rbuilder --bin op-rbuilder -- node \ --chain /path/to/chain-config.json \ --http \ --authrpc.port 9551 \ @@ -73,7 +73,7 @@ cargo run -p op-rbuilder --bin op-rbuilder --features=flashtestations -- node \ --flashtestations.funding-amount 0.01 \ # amount in ETH to fund the TEE generated key --flashtestations.funding-key secret-key \ # funding key for the TEE key --flashtestations.registry-address 0xFlashtestationsRegistryAddress \ - flashtestations.builder-policy-address 0xBuilderPolicyAddress + --flashtestations.builder-policy-address 0xBuilderPolicyAddress ``` Note that `--rollup.builder-secret-key` must be set and funded in order for the flashtestations key to be funded and submit the attestation on-chain. diff --git a/crates/op-rbuilder/src/flashtestations/attestation.rs b/crates/op-rbuilder/src/flashtestations/attestation.rs index 39c99539d..b38dcf5ab 100644 --- a/crates/op-rbuilder/src/flashtestations/attestation.rs +++ b/crates/op-rbuilder/src/flashtestations/attestation.rs @@ -33,7 +33,7 @@ impl RemoteAttestationProvider { let report_data_hex = hex::encode(report_data); let url = format!("{}/{}", self.service_url, report_data_hex); - info!(target: "flashtestations", url = url, "fetching quote in debug mode"); + info!(target: "flashtestations", url = url, "fetching quote from remote attestation provider"); let response = self .client