@@ -382,10 +382,18 @@ impl Worker {
382382 self . check_time_flush( ) . await ;
383383 }
384384
385- // Handle incoming transactions
385+ // Handle incoming transactions - drain all ready TXs at once
386386 tx = self . tx_receiver. recv( ) => {
387387 if let Some ( tx) = tx {
388- self . handle_transaction( tx) . await ;
388+ // Drain additional ready transactions to amortize select! overhead
389+ let mut txs = vec![ tx] ;
390+ while let Ok ( t) = self . tx_receiver. try_recv( ) {
391+ txs. push( t) ;
392+ if txs. len( ) >= self . config. max_batch_txs {
393+ break ;
394+ }
395+ }
396+ self . handle_transactions_batch( txs) . await ;
389397 } else {
390398 warn!( worker_id = self . config. worker_id, "tx_receiver closed" ) ;
391399 self . shutdown = true ;
@@ -420,9 +428,10 @@ impl Worker {
420428 info ! ( worker_id = self . config. worker_id, "Worker shutting down" ) ;
421429 }
422430
423- /// Handle incoming transaction
431+ /// Handle incoming transaction (used by tests only; production uses handle_transactions_batch)
432+ #[ cfg( test) ]
424433 async fn handle_transaction ( & mut self , tx : Transaction ) {
425- info ! (
434+ trace ! (
426435 worker_id = self . config. worker_id,
427436 tx_size = tx. len( ) ,
428437 "Worker received transaction from channel"
@@ -457,14 +466,60 @@ impl Worker {
457466 ) ;
458467 self . process_batch ( batch) . await ;
459468 } else {
460- info ! (
469+ trace ! (
461470 worker_id = self . config. worker_id,
462471 pending_txs = self . batch_maker. pending_count( ) ,
463472 "Transaction added to batch maker, waiting for more or flush"
464473 ) ;
465474 }
466475 }
467476
477+ /// Handle a batch of incoming transactions drained from the channel.
478+ ///
479+ /// Validates each transaction, adds all valid ones to the batch maker,
480+ /// and processes any resulting batches. This amortizes the per-transaction
481+ /// overhead of the select! loop and logging.
482+ async fn handle_transactions_batch ( & mut self , txs : Vec < Transaction > ) {
483+ let total = txs. len ( ) ;
484+ debug ! (
485+ worker_id = self . config. worker_id,
486+ tx_count = total,
487+ "Processing drained transaction batch"
488+ ) ;
489+
490+ // Validate and collect valid transactions
491+ let mut valid_txs = Vec :: with_capacity ( total) ;
492+ for tx in txs {
493+ if let Some ( ref validator) = self . validator {
494+ match validator. validate_transaction ( & tx) . await {
495+ Ok ( ( ) ) => valid_txs. push ( tx) ,
496+ Err ( e) => {
497+ warn ! (
498+ worker_id = self . config. worker_id,
499+ error = %e,
500+ "Transaction validation failed, rejecting"
501+ ) ;
502+ }
503+ }
504+ } else {
505+ valid_txs. push ( tx) ;
506+ }
507+ }
508+
509+ // Add all valid transactions and collect any completed batches
510+ let batches = self . batch_maker . add_transactions ( valid_txs) ;
511+
512+ // Process all completed batches
513+ for batch in batches {
514+ info ! (
515+ worker_id = self . config. worker_id,
516+ tx_count = batch. transactions. len( ) ,
517+ "Batch ready, processing"
518+ ) ;
519+ self . process_batch ( batch) . await ;
520+ }
521+ }
522+
468523 /// Handle message from Primary
469524 async fn handle_primary_message ( & mut self , msg : PrimaryToWorker ) {
470525 match msg {
@@ -694,9 +749,8 @@ impl Worker {
694749 let has_pending = self . batch_maker . has_pending ( ) ;
695750 let elapsed = self . batch_maker . time_since_batch_start ( ) ;
696751
697- // Log every call so we can see the tick is working
698752 if has_pending {
699- info ! (
753+ trace ! (
700754 worker_id = self . config. worker_id,
701755 should_flush,
702756 has_pending,
@@ -706,7 +760,7 @@ impl Worker {
706760 }
707761
708762 if should_flush && has_pending {
709- info ! (
763+ debug ! (
710764 worker_id = self . config. worker_id,
711765 pending_txs = self . batch_maker. pending_count( ) ,
712766 "Time flush triggered, creating batch"
@@ -783,7 +837,7 @@ impl Worker {
783837 if let Some ( ref storage) = self . storage {
784838 match storage. put_batch ( batch. clone ( ) ) . await {
785839 Ok ( _) => {
786- info ! (
840+ debug ! (
787841 worker_id = self . config. worker_id,
788842 digest = %digest. digest,
789843 tx_count = batch. transactions. len( ) ,
@@ -812,20 +866,20 @@ impl Worker {
812866 self . state . store_batch ( batch. clone ( ) ) ;
813867
814868 // Broadcast to peer Workers
815- info ! (
869+ debug ! (
816870 worker_id = self . config. worker_id,
817871 digest = %digest. digest,
818872 "Broadcasting batch to peer Workers..."
819873 ) ;
820874 self . network . broadcast_batch ( & batch) . await ;
821- info ! (
875+ debug ! (
822876 worker_id = self . config. worker_id,
823877 digest = %digest. digest,
824878 "Broadcast complete"
825879 ) ;
826880
827881 // Report to Primary
828- info ! (
882+ debug ! (
829883 worker_id = self . config. worker_id,
830884 digest = %digest. digest,
831885 "Sending BatchDigest to Primary"
@@ -846,7 +900,7 @@ impl Worker {
846900 "Failed to send BatchDigest to Primary - channel closed"
847901 ) ;
848902 } else {
849- info ! (
903+ debug ! (
850904 worker_id = self . config. worker_id,
851905 "BatchDigest sent to Primary successfully"
852906 ) ;
0 commit comments