@@ -477,6 +477,49 @@ impl OpManager {
477477 Ok ( ( ) )
478478 }
479479
480+ /// Peek at the next hop address for an operation without removing it.
481+ /// Used by hop-by-hop routing to determine where to send initial outbound messages.
482+ /// Returns None if the operation doesn't exist or doesn't have a next hop address.
483+ pub fn peek_next_hop_addr ( & self , id : & Transaction ) -> Option < std:: net:: SocketAddr > {
484+ if self . ops . completed . contains ( id) || self . ops . under_progress . contains ( id) {
485+ return None ;
486+ }
487+ match id. transaction_type ( ) {
488+ TransactionType :: Connect => self
489+ . ops
490+ . connect
491+ . get ( id)
492+ . and_then ( |op| op. get_next_hop_addr ( ) ) ,
493+ TransactionType :: Put => self . ops . put . get ( id) . and_then ( |op| op. get_next_hop_addr ( ) ) ,
494+ TransactionType :: Get => self . ops . get . get ( id) . and_then ( |op| op. get_next_hop_addr ( ) ) ,
495+ TransactionType :: Subscribe => self
496+ . ops
497+ . subscribe
498+ . get ( id)
499+ . and_then ( |op| op. get_next_hop_addr ( ) ) ,
500+ TransactionType :: Update => self
501+ . ops
502+ . update
503+ . get ( id)
504+ . and_then ( |op| op. get_next_hop_addr ( ) ) ,
505+ }
506+ }
507+
508+ /// Peek at the full target peer (including public key) without removing the operation.
509+ /// Used when establishing new connections where we need the public key for handshake.
510+ pub fn peek_target_peer ( & self , id : & Transaction ) -> Option < PeerKeyLocation > {
511+ if self . ops . completed . contains ( id) || self . ops . under_progress . contains ( id) {
512+ return None ;
513+ }
514+ match id. transaction_type ( ) {
515+ TransactionType :: Connect => {
516+ self . ops . connect . get ( id) . and_then ( |op| op. get_target_peer ( ) )
517+ }
518+ // Other operations only store addresses, not full peer info
519+ _ => None ,
520+ }
521+ }
522+
480523 pub fn pop ( & self , id : & Transaction ) -> Result < Option < OpEnum > , OpNotAvailable > {
481524 if self . ops . completed . contains ( id) {
482525 return Err ( OpNotAvailable :: Completed ) ;
@@ -653,9 +696,11 @@ impl OpManager {
653696 /// Notify the operation manager that a transaction is being transacted over the network.
654697 pub fn sending_transaction ( & self , peer : & PeerKeyLocation , msg : & NetMessage ) {
655698 let transaction = msg. id ( ) ;
656- if let ( Some ( recipient) , Some ( target) ) = ( msg. target ( ) , msg. requested_location ( ) ) {
699+ // With hop-by-hop routing, record the request using the peer we're sending to
700+ // and the message's requested location (contract location)
701+ if let Some ( target_loc) = msg. requested_location ( ) {
657702 self . ring
658- . record_request ( recipient . clone ( ) , target , transaction. transaction_type ( ) ) ;
703+ . record_request ( peer . clone ( ) , target_loc , transaction. transaction_type ( ) ) ;
659704 }
660705 if let Some ( peer_addr) = peer. socket_addr ( ) {
661706 self . ring
@@ -767,7 +812,13 @@ async fn garbage_cleanup_task<ER: NetEventRegister>(
767812 } else {
768813 ops. under_progress. remove( & tx) ;
769814 ops. completed. remove( & tx) ;
770- tracing:: debug!( "Transaction timed out: {tx}" ) ;
815+ tracing:: info!(
816+ tx = %tx,
817+ tx_type = ?tx. transaction_type( ) ,
818+ elapsed_ms = tx. elapsed( ) . as_millis( ) ,
819+ ttl_ms = crate :: config:: OPERATION_TTL . as_millis( ) ,
820+ "Transaction timed out"
821+ ) ;
771822
772823 // Check if this is a child operation and propagate timeout to parent
773824 if let Some ( parent_tx) = sub_op_tracker. get_parent( tx) {
@@ -812,7 +863,13 @@ async fn garbage_cleanup_task<ER: NetEventRegister>(
812863 TransactionType :: Update => ops. update. remove( & tx) . is_some( ) ,
813864 } ;
814865 if removed {
815- tracing:: debug!( "Transaction timed out: {tx}" ) ;
866+ tracing:: info!(
867+ tx = %tx,
868+ tx_type = ?tx. transaction_type( ) ,
869+ elapsed_ms = tx. elapsed( ) . as_millis( ) ,
870+ ttl_ms = crate :: config:: OPERATION_TTL . as_millis( ) ,
871+ "Transaction timed out"
872+ ) ;
816873
817874 // Check if this is a child operation and propagate timeout to parent
818875 if let Some ( parent_tx) = sub_op_tracker. get_parent( tx) {
0 commit comments