@@ -4,7 +4,7 @@ use alloy_rpc_types::erc4337::PackedUserOperation;
44use rdkafka:: config:: ClientConfig ;
55use rdkafka:: consumer:: { Consumer , StreamConsumer } ;
66use rdkafka:: message:: Message ;
7- use rdkafka:: producer:: { FutureProducer , FutureRecord } ;
7+ use rdkafka:: producer:: FutureRecord ;
88use serde_json;
99use std:: sync:: Arc ;
1010use std:: time:: Duration ;
@@ -44,7 +44,7 @@ fn create_test_user_op(sender: Address, nonce: u64) -> UserOperationRequest {
4444
4545#[ tokio:: test]
4646#[ ignore]
47- async fn test_e2e_userop_to_block ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
47+ async fn test_e2e_userop_to_block ( ) -> anyhow :: Result < ( ) > {
4848 println ! ( "\n ========================================" ) ;
4949 println ! ( "END-TO-END TEST: UserOp → Kafka → Block" ) ;
5050 println ! ( "========================================\n " ) ;
@@ -118,7 +118,7 @@ async fn test_e2e_userop_to_block() -> Result<(), Box<dyn std::error::Error>> {
118118 let consumed_ops = received_user_ops. lock ( ) . await ;
119119 assert_eq ! ( consumed_ops. len( ) , 3 , "Expected 3 UserOps" ) ;
120120
121- println ! ( "\n Step 5: Creating UserOp bundle (simulating builder) ..." ) ;
121+ println ! ( "\n Step 5: Creating UserOp bundle..." ) ;
122122 use tips_builder:: UserOpBundle ;
123123
124124 let mut bundle = UserOpBundle :: new ( TEST_ENTRY_POINT , TEST_BUNDLER ) ;
@@ -128,6 +128,9 @@ async fn test_e2e_userop_to_block() -> Result<(), Box<dyn std::error::Error>> {
128128 }
129129
130130 assert_eq ! ( bundle. user_ops. len( ) , 3 , "Bundle should have 3 UserOps" ) ;
131+ assert_eq ! ( bundle. entry_point, TEST_ENTRY_POINT ) ;
132+ assert_eq ! ( bundle. beneficiary, TEST_BUNDLER ) ;
133+ println ! ( " ✓ Bundle created with {} UserOps" , bundle. user_ops. len( ) ) ;
131134
132135 println ! ( "\n Step 6: Generating handleOps() calldata..." ) ;
133136 let calldata = bundle. build_handleops_calldata ( ) ;
@@ -137,23 +140,72 @@ async fn test_e2e_userop_to_block() -> Result<(), Box<dyn std::error::Error>> {
137140
138141 let function_selector = & calldata[ 0 ..4 ] ;
139142 println ! (
140- " ✓ Function selector: 0x{}" ,
143+ " ✓ Function selector: 0x{} (handleOps) " ,
141144 hex:: encode( function_selector)
142145 ) ;
146+ assert ! (
147+ calldata. len( ) > 4 ,
148+ "Calldata should contain function arguments"
149+ ) ;
143150
144- println ! ( "\n Step 7: Verifying bundler transaction structure..." ) ;
145- println ! ( " ✓ EntryPoint: {}" , TEST_ENTRY_POINT ) ;
146- println ! ( " ✓ Beneficiary: {}" , TEST_BUNDLER ) ;
147- println ! ( " ✓ UserOp count: {}" , bundle. user_ops. len( ) ) ;
151+ println ! ( "\n Step 7: Creating bundler transaction..." ) ;
152+ let chain_id = 10 ;
153+ let base_fee = 1000000000u128 ;
154+ let nonce = 0 ;
155+ let bundler_tx = bundle. create_bundle_transaction ( TEST_BUNDLER , nonce, chain_id, base_fee) ;
156+ assert ! ( bundler_tx. is_some( ) , "Failed to create bundler transaction" ) ;
157+ println ! ( " ✓ Bundler transaction created" ) ;
158+ println ! ( " ✓ From: {}" , TEST_BUNDLER ) ;
159+ println ! ( " ✓ To: {}" , TEST_ENTRY_POINT ) ;
160+ println ! ( " ✓ Contains handleOps() calldata" ) ;
148161
149162 println ! ( "\n Step 8: Simulating block building with midpoint insertion..." ) ;
150- use tips_builder:: InsertUserOpBundle ;
163+ use tips_builder:: { InsertUserOpBundle , TransactionCollector } ;
151164
152165 let userops_step = InsertUserOpBundle :: new ( TEST_BUNDLER ) ;
153166 userops_step. add_bundle ( bundle) ;
167+ println ! ( " ✓ Bundle added to InsertUserOpBundle pipeline" ) ;
168+
169+ let mut collector = TransactionCollector :: new ( userops_step. clone ( ) ) ;
170+ println ! ( " ✓ TransactionCollector initialized" ) ;
171+
172+ println ! ( "\n Step 9: Verifying midpoint insertion logic..." ) ;
173+ println ! ( " Simulating block with 6 regular transactions:" ) ;
174+ println ! ( " [TX0, TX1, TX2, BUNDLER, TX3, TX4, TX5]" ) ;
175+ println ! ( " ^^^^^^^" ) ;
176+ println ! ( " Inserted at position 3 (midpoint of 6 txs)" ) ;
177+
178+ let total_txs = 6 ;
179+ let expected_midpoint = total_txs / 2 ;
180+ collector. set_total_expected ( total_txs) ;
181+
182+ for i in 0 ..expected_midpoint {
183+ assert ! (
184+ !collector. should_insert_bundle( ) ,
185+ "Should not insert before midpoint"
186+ ) ;
187+ collector. increment_count ( ) ;
188+ println ! ( " ✓ Regular TX {} collected (before midpoint)" , i) ;
189+ }
190+
191+ assert ! (
192+ collector. should_insert_bundle( ) ,
193+ "Should insert at midpoint"
194+ ) ;
195+ println ! ( " ✓ Midpoint reached - bundler TX should be inserted" ) ;
196+
197+ collector. mark_bundle_inserted ( ) ;
154198
155- println ! ( " ✓ Bundle added to pipeline" ) ;
156- println ! ( " ✓ Bundler transaction will be inserted at block midpoint" ) ;
199+ for i in expected_midpoint..total_txs {
200+ assert ! (
201+ !collector. should_insert_bundle( ) ,
202+ "Should not insert after bundle"
203+ ) ;
204+ collector. increment_count ( ) ;
205+ println ! ( " ✓ Regular TX {} collected (after midpoint)" , i) ;
206+ }
207+
208+ println ! ( "\n ✓ VERIFIED: Bundler transaction inserted at block midpoint" ) ;
157209
158210 println ! ( "\n ========================================" ) ;
159211 println ! ( "✓ END-TO-END TEST PASSED" ) ;
@@ -171,7 +223,7 @@ async fn test_e2e_userop_to_block() -> Result<(), Box<dyn std::error::Error>> {
171223
172224#[ tokio:: test]
173225#[ ignore]
174- async fn test_e2e_multiple_batches ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
226+ async fn test_e2e_multiple_batches ( ) -> anyhow :: Result < ( ) > {
175227 println ! ( "\n ========================================" ) ;
176228 println ! ( "E2E TEST: Multiple Batches" ) ;
177229 println ! ( "========================================\n " ) ;
@@ -258,50 +310,31 @@ async fn test_e2e_multiple_batches() -> Result<(), Box<dyn std::error::Error>> {
258310
259311#[ tokio:: test]
260312#[ ignore]
261- async fn test_e2e_bundle_hash_verification ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
313+ async fn test_e2e_userop_hash_verification ( ) -> anyhow :: Result < ( ) > {
262314 println ! ( "\n ========================================" ) ;
263- println ! ( "E2E TEST: Bundle Hash Verification" ) ;
315+ println ! ( "E2E TEST: UserOp Hash Verification" ) ;
264316 println ! ( "========================================\n " ) ;
265317
266- use tips_builder:: UserOpBundle ;
267-
268318 let user_op1 = create_test_user_op ( TEST_SENDER , 0 ) ;
269- let user_op2 = create_test_user_op ( TEST_SENDER , 1 ) ;
270- let user_op3 = create_test_user_op ( TEST_SENDER , 2 ) ;
271-
272- println ! ( "Creating two identical bundles..." ) ;
273- let bundle1 = UserOpBundle :: new ( TEST_ENTRY_POINT , TEST_BUNDLER )
274- . with_user_op ( user_op1. clone ( ) )
275- . with_user_op ( user_op2. clone ( ) )
276- . with_user_op ( user_op3. clone ( ) ) ;
277-
278- let bundle2 = UserOpBundle :: new ( TEST_ENTRY_POINT , TEST_BUNDLER )
279- . with_user_op ( user_op1. clone ( ) )
280- . with_user_op ( user_op2. clone ( ) )
281- . with_user_op ( user_op3. clone ( ) ) ;
319+ let user_op2 = create_test_user_op ( TEST_SENDER , 0 ) ;
282320
283- println ! ( "Verifying bundle hashes ..." ) ;
284- let hash1 = bundle1 . hash ( ) ;
285- let hash2 = bundle2 . hash ( ) ;
321+ println ! ( "Verifying UserOp hash determinism ..." ) ;
322+ let hash1 = user_op1 . hash ( ) ? ;
323+ let hash2 = user_op2 . hash ( ) ? ;
286324
287- assert_eq ! ( hash1, hash2, "Identical bundles should have same hash" ) ;
288- println ! ( " ✓ Bundle hash: {}" , hash1) ;
325+ assert_eq ! ( hash1, hash2, "Identical UserOps should have same hash" ) ;
326+ println ! ( " ✓ UserOp hash (nonce=0) : {}" , hash1) ;
289327
290- println ! ( "\n Creating bundle with different UserOp..." ) ;
291328 let user_op_different = create_test_user_op ( TEST_SENDER , 99 ) ;
292- let bundle3 = UserOpBundle :: new ( TEST_ENTRY_POINT , TEST_BUNDLER )
293- . with_user_op ( user_op1. clone ( ) )
294- . with_user_op ( user_op2. clone ( ) )
295- . with_user_op ( user_op_different) ;
329+ let hash3 = user_op_different. hash ( ) ?;
296330
297- let hash3 = bundle3. hash ( ) ;
298331 assert_ne ! (
299332 hash1, hash3,
300- "Different bundles should have different hashes"
333+ "Different UserOps should have different hashes"
301334 ) ;
302- println ! ( " ✓ Different bundle hash: {}" , hash3) ;
335+ println ! ( " ✓ UserOp hash (nonce=99) : {}" , hash3) ;
303336
304- println ! ( "\n ✓ Bundle hash verification passed" ) ;
337+ println ! ( "\n ✓ UserOp hash verification passed" ) ;
305338
306339 Ok ( ( ) )
307340}
0 commit comments