@@ -323,6 +323,21 @@ func (t *UDPv5) TalkRequest(n *enode.Node, protocol string, request []byte) ([]b
323323 }
324324}
325325
326+ // TalkRequest sends a talk request to a node and waits for a response but will return when ctx timeout.
327+ func (t * UDPv5 ) TalkRequestWithContext (ctx context.Context , n * enode.Node , protocol string , request []byte ) ([]byte , error ) {
328+ req := & v5wire.TalkRequest {Protocol : protocol , Message : request }
329+ resp := t .callToNode (n , v5wire .TalkResponseMsg , req )
330+ defer t .callDone (resp )
331+ select {
332+ case respMsg := <- resp .ch :
333+ return respMsg .(* v5wire.TalkResponse ).Message , nil
334+ case err := <- resp .err :
335+ return nil , err
336+ case <- ctx .Done ():
337+ return nil , ctx .Err ()
338+ }
339+ }
340+
326341// TalkRequestToID sends a talk request to a node and waits for a response.
327342func (t * UDPv5 ) TalkRequestToID (id enode.ID , addr netip.AddrPort , protocol string , request []byte ) ([]byte , error ) {
328343 req := & v5wire.TalkRequest {Protocol : protocol , Message : request }
@@ -606,13 +621,14 @@ func (t *UDPv5) dispatch() {
606621
607622 case c := <- t .callDoneCh :
608623 active := t .activeCallByNode [c .id ]
609- if active != c {
610- panic ("BUG: callDone for inactive call" )
624+ if active == c {
625+ t .sendNextCall (c .id )
626+ }
627+ if c .timeout != nil {
628+ c .timeout .Stop ()
611629 }
612- c .timeout .Stop ()
613630 delete (t .activeCallByAuth , c .nonce )
614631 delete (t .activeCallByNode , c .id )
615- t .sendNextCall (c .id )
616632
617633 case r := <- t .sendCh :
618634 t .send (r .destID , r .destAddr , r .msg , nil )
0 commit comments