
    (iL                     $   d dl mZmZ d dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZmZ d dlmZmZ d dlmZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZm Z m!Z!m"Z" d d
l#m$Z$ d dl%m&Z& d dl'm(Z(m)Z)m*Z*m+Z+ erd dl,m-Z- d dl.m/Z/ dZ0 G d de$e      Z1y)    )ABCabstractmethodN)	TYPE_CHECKINGAnyCallable	CoroutineListOptionalTupleUnioncast)ConnectionClosedWebSocketException)BATCH_REQUEST_ID#sort_batch_response_by_response_ids)generate_cache_key)async_handle_recv_cachingasync_handle_send_caching)(validate_rpc_response_and_raise_if_error)PersistentConnectionClosedOKProviderConnectionErrorTaskNotRunningTimeExhaustedWeb3AttributeError)AsyncJSONBaseProvider)RequestProcessor)RPCEndpointRPCId
RPCRequestRPCResponse)	AsyncWeb3)MiddlewareOniong      >@c                       e Zd ZU  ej                  d      ZdZdZee	e
   e	edeeeef   f      f   ed<   dZee	e
   e	edeeeef   f      f   ed<   dZee	e
   e	edeeeee   f   f      f   ed<   dZee	e
   e	edeeeee   f   f      f   ed<   ed	d
dd	fdede
dede
de
deddf fdZdddddedeeeef   f   fdZdddddefdZdddddedeeeee   f   f   fdZdddddedeeeee   f   f   fdZdefdZd;dZd;dZ e!d e"d!edefd"       Z#e$d#edefd$       Z%d e"d!edefd%Z&d&eee"ef      dee   fd'Z'd(ee   dee   fd)Z(d&eee"ef      dee   fd*Z)e*d+e+ddfd,       Z,e*defd-       Z-d;d.Z.d;d/Z/defd0Z0d;d1Z1	 	 	 	 d<d2Z2d;d3Z3d;d4Z4d5e5ddfd6Z6d;d7Z7	 d=d8e8e9ee9   f   d9e	e   defd:Z: xZ;S )>PersistentConnectionProviderz+web3.providers.PersistentConnectionProviderT)NN._send_func_cache_recv_func_cache_send_batch_func_cache_recv_batch_func_cachei  F   request_timeout subscription_response_queue_size silence_listener_task_exceptionsmax_connection_retriesrequest_information_cache_sizekwargsreturnNc                     t        |   di | t        | ||      | _        d | _        t        j                         | _        || _        || _	        || _
        y )N)r+   r.    )super__init__r   _request_processor_message_listener_taskasyncioEvent_listen_event_max_connection_retriesr*   r,   )selfr*   r+   r,   r-   r.   r/   	__class__s          U/var/www/br/venv/lib/python3.12/site-packages/web3/providers/persistent/persistent.pyr4   z%PersistentConnectionProvider.__init__T   s]     	"6""2-M+I#

 GK#,3MMO'=$.0P-    async_w3zAsyncWeb3[Any]middleware_onionr"   c                     K   |j                         t        t        d D                    }| j                  d   k7  r#dt        dt
        dt        f fd}||f _         j                  d   S w)z8
        Cache the middleware chain for `send`.
        c              3   2   K   | ]  }t        |        y wNid.0mws     r=   	<genexpr>z9PersistentConnectionProvider.send_func.<locals>.<genexpr>s        ;"r"v;   r   methodparamsr0   c                    K   D ]'  } |      }|j                  | |       d {   \  } }) j                  | |       d {   S 7 #7 wrC   )async_request_processorsend_request)rL   rM   rH   initializedr?   
middlewarer;   s       r=   send_functionz=PersistentConnectionProvider.send_func.<locals>.send_functionw   s`     $ B"$X,K+6+N+N, &NFF "..vv>>>	& ?s!   #AA
AAAA   )as_tuple_of_middlewarehashtupler%   r   r   r   )r;   r?   r@   	cache_keyrS   rR   s   ``   @r=   	send_funcz&PersistentConnectionProvider.send_funcl   sy      &<<>
;
;;<	--a00?K ? ? ? &/$>D!$$Q''s   A0A5c                     K   |j                         t        t        d D                    }| j                  d   k7  rdt        dt
        f fd}||f _         j                  d   S w)zD
        Cache and compose the middleware stack for `recv`.
        c              3   2   K   | ]  }t        |        y wrC   rD   rF   s     r=   rI   z9PersistentConnectionProvider.recv_func.<locals>.<genexpr>   rJ   rK   r   rpc_requestr0   c                    K   j                  |        d {   }| d   }t              D ]$  } |      }|j                  ||       d {   }& |S 7 =7 
wNrL   )recv_for_requestreversedasync_response_processor)r\   responserL   rH   rQ   r?   rR   r;   s        r=   recv_functionz=PersistentConnectionProvider.recv_func.<locals>.recv_function   sn     !%!6!6{!CC$X.":. B"$X,K%0%I%I&  H
   D s!   AA4AA	AArT   )rU   rV   rW   r&   r   r    r;   r?   r@   rX   rc   rR   s   ``   @r=   	recv_funcz&PersistentConnectionProvider.recv_func   sr      &<<>
;
;;<	--a00	  	  	  &/$>D!$$Q''s   A*A/c                    K   |j                         t        t        d D                    }| j                  d   k7  r8dt        t
        t        t        f      dt        t           f fd}||f _         j                  d   S w)Nc              3   2   K   | ]  }t        |        y wrC   rD   rF   s     r=   rI   z?PersistentConnectionProvider.send_batch_func.<locals>.<genexpr>   rJ   rK   r   requestsr0   c           	         K   D ]6  } |      }| D cg c]  \  }}|j                  ||       d {   ! } }}8 j                  |        d {   S 7 $c c}}w 7 wrC   )rO   send_batch_request)rh   rH   rQ   rL   rM   r?   rR   r;   s        r=   rY   z?PersistentConnectionProvider.send_batch_func.<locals>.send_func   s}      % B"$X,K 19 ,VV *AA&&QQQ H   "44X>>> R  ?s1   A"AAAA"A A"AA"rT   )	rU   rV   rW   r'   r	   r   r   r   r   )r;   r?   r@   rX   rY   rR   s   ``   @r=   send_batch_funcz,PersistentConnectionProvider.send_batch_func   s      &<<>
;
;;<	33A66	?u[#%567	?j!	? ,5i*@D'**1--s   BB
c                     K   |j                         t        t        d D                    }| j                  d   k7  r+dt        t
           dt        t           f fd}||f _         j                  d   S w)Nc              3   2   K   | ]  }t        |        y wrC   rD   rF   s     r=   rI   z?PersistentConnectionProvider.recv_batch_func.<locals>.<genexpr>   rJ   rK   r   rpc_requestsr0   c           	      H  K   | D cg c]  }|d   	 }}
j                  |        d {   }t        	      D ]T  }t        |t              s|c S  |      }t	        ||      D cg c]  \  }}|j                  ||       d {   ! }}}V |S c c}w 7 m7 c c}}w wr^   )recv_for_batch_requestr`   
isinstancelistzipra   )rn   r\   methods	responsesrH   rQ   mrr?   rR   r;   s           r=   rc   zCPersistentConnectionProvider.recv_batch_func.<locals>.recv_function   s      EQQ[;x0QQ"&"="=l"KK	":. 	B%i6(("$X,K %($;! Aq *BB1aHHH!I !	 !  RK I!s=   B"BB"B=B"(BBBB"BB"rT   )rU   rV   rW   r(   r	   r   r    rd   s   ``   @r=   recv_batch_funcz,PersistentConnectionProvider.recv_batch_func   s~      &<<>
;
;;<	33A66!":.!k"!" ,5m*DD'**1--s   A8A=c                     t        | d      rt        | j                        S t        | d      rt        | j                        S t	        d      )Nendpoint_uriipc_pathzW`PersistentConnectionProvider` must have either `endpoint_uri` or `ipc_path` attribute.)hasattrstrrz   r{   r   r;   s    r=   get_endpoint_uri_or_ipc_pathz9PersistentConnectionProvider.get_endpoint_uri_or_ipc_path   sH    4(t(())T:&t}}%%$( r>   c           	        K   | j                         }d}d}d}|| j                  k7  r	 |dz  }| j                  j                  d|       | j	                          d {    t        j                  | j                               | _        | j                  j                  | j                         | j                  j                  d|       y y y 7 p# t        t        f$ r}|| j                  k(  rt        d| d| j                   d      || j                  j                  d	|t        |d      d
       t        j                  |       d {  7   ||z  }Y d }~nd }~ww xY w|| j                  k7  rMw)Nr   g      ?rT   zConnecting to: %szSuccessfully connected to: %szCould not connect to: z. Retries exceeded max of .z1Could not connect to: %s. Retrying in %s seconds.T)exc_info)r   r:   loggerinfo_provider_specific_connectr7   create_task_message_listenerr6   add_done_callback_message_listener_callbackr   OSErrorr   roundsleep)r;   endpoint_connection_attempts_backoff_rate_change_backoff_timees         r=   connectz$PersistentConnectionProvider.connect   s    446 #"d&B&BB6$)$  !4h?55777.5.A.A**,/+ ++==33   !@(K C 8 '0 6'4+G+GG10
 ;3373O3O2PPQS    G-+!	 !  mmM222!556 #d&B&BBsN   &E64C CA-C E6C E!A-EE
EE6E!!E6c                   K   	 | j                   r.| j                   j                          | j                    d {    d | _         | j                  j                  d       | j                          d {    | j                  j                          | j                  j                  d| j                                y 7 # t        j                  t        t
        f$ r Y w xY w# d | _         | j                  j                  d       w xY w7 w)Nz8Message listener background task successfully shut down.z"Successfully disconnected from: %s)r6   cancelr7   CancelledErrorStopAsyncIterationr   r   r   _provider_specific_disconnectr5   clear_cachesr   r~   s    r=   
disconnectz'PersistentConnectionProvider.disconnect  s     	Y**++2241111 +/D'KKWX00222,,.0--/	
 2&&(:<LM 		 +/D'KKWX2sP   D5B? B=B? 5D3D
4A	D=B? ?C C# C  C# #$DDrL   rM   c                    K   | j                  ||      }| j                  | j                  |             d {    |S 7 wrC   )form_requestsocket_sendencode_rpc_dict)r;   rL   rM   request_dicts       r=   rP   z)PersistentConnectionProvider.send_request  sC     ((8t33LABBB 	Cs   6A?Ar\   c                 F   K   | j                  |d          d {   S 7 w)NrE   )_get_response_for_request_id)r;   r\   s     r=   r_   z-PersistentConnectionProvider.recv_for_request  s"     66{47HIIIIs   !!c                 x   K   | j                  ||       d {   }| j                  |       d {   S 7 7 wrC   )rP   r_   )r;   rL   rM   r\   s       r=   make_requestz)PersistentConnectionProvider.make_request   s:     
 !--ff==**;777 >7s   :6:8::rh   c                    K   |D cg c]  \  }}| j                  ||       }}}| j                  |      }| j                  |       d {    |S c c}}w 7 wrC   )r   encode_batch_request_dictsr   )r;   rh   rL   rM   request_dictsrequest_datas         r=   rj   z/PersistentConnectionProvider.send_batch_request*  sk      GO
2B66Dff-
 
 66}E|,,,
 	-s   AA(AAA_request_dictsc                 v   K   t        t        t           | j                  t               d {         }|S 7 
wrC   )r   r	   r    r   r   )r;   r   rb   s      r=   rp   z3PersistentConnectionProvider.recv_for_batch_request4  s9      334DEE
  Fs   *97
9c                 v   K   | j                  |       d {   }| j                  |       d {   S 7 7 wrC   )rj   rp   )r;   rh   r   s      r=   make_batch_requestz/PersistentConnectionProvider.make_batch_request=  s9      #55h??00??? @?s   959799r   c                     K   t        d      w)z]
        Send an encoded RPC request to the provider over the persistent connection.
        !Must be implemented by subclassesNotImplementedError)r;   r   s     r=   r   z(PersistentConnectionProvider.socket_sendE  s     
 ""EFF   c                     K   t        d      w)zw
        Receive, decode, and return an RPC response from the provider over the
        persistent connection.
        r   r   r~   s    r=   socket_recvz(PersistentConnectionProvider.socket_recvL  s      ""EFFr   c                     K   t        d      wNr   r   r~   s    r=   r   z7PersistentConnectionProvider._provider_specific_connectV       !"EFFr   c                     K   t        d      wr   r   r~   s    r=   r   z:PersistentConnectionProvider._provider_specific_disconnectY  s     !"EFFr   c                     K   t        d      wr   r   r~   s    r=    _provider_specific_socket_readerz=PersistentConnectionProvider._provider_specific_socket_reader]  r   r   c                 l    dt         dt        dt        dd f fdt        j                  t        j                        t        j                  t        j
                        t        j                  t        j                  fd       t        j                  t        j
                  fd       y )Nsigframeexisting_handlerr0   c                     t        j                         }t        |      r	 || |       |j                  j	                                y rC   )r7   get_event_loopcallabler   r   )r   r   r   loopr;   s       r=   extended_handlerzKPersistentConnectionProvider._set_signal_handlers.<locals>.extended_handlera  s;    ))+D () e,T__./r>   c                      | |      S rC   r2   )r   r   existing_sigint_handlerr   s     r=   <lambda>zCPersistentConnectionProvider._set_signal_handlers.<locals>.<lambda>o  s    /U<ST r>   c                      | |      S rC   r2   )r   r   existing_sigterm_handlerr   s     r=   r   zCPersistentConnectionProvider._set_signal_handlers.<locals>.<lambda>s  s    /U<TU r>   )intr   signal	getsignalSIGINTSIGTERM)r;   r   r   r   s   `@@@r=   _set_signal_handlersz1PersistentConnectionProvider._set_signal_handlers`  s    	0# 	0c 	0S 	0T 	0 #)"2"26=="A#)#3#3FNN#C  	MMT	
 	NNU	
r>   c                     d}| j                   j                  j                  t        ||             | j                   j                  j                  t        ||             y )Nz Message listener task has ended.)message)r5   _subscription_response_queue
put_nowaitr   _handler_subscription_queue)r;   message_listener_taskr   s      r=   r   z7PersistentConnectionProvider._message_listener_callbackv  sU    
 5<<GG0'B	
 	;;FF0'B	
r>   c                    | j                   j                  j                  j                         D ]  }t	        |t
              sd|vr't        t        t        |      d| j                         ?| j                   j                  j                  t        |d               }d|v su|xt        t        t        |      d| j                          y)z
        Check the request response cache for any errors not tied to current requests
        and raise them if found.
        rE   N)r   error)r5   _request_response_cache_datavaluesrq   dictr   r   r    r   _request_information_cacheget_cache_entryr   )r;   rb   requests      r=   _raise_stray_errors_from_cachez;PersistentConnectionProvider._raise_stray_errors_from_cache  s    
 //GGMMTTV 	H(D)x'<[(3T$++ #55PP``*8D>:G (*w@ h7dkk	r>   c                   K   | j                   j                  d| j                  j                         	 t	        j
                  d       d {    	 | j                          d {   }t        |t              rt        |      }t        |t              s|j                  d      dk(  nd}| j                  j                  ||       d {    | j                          7 7 }7 # t        $ r0}| j                   j                  d|j                         Y d }~y d }~wt         $ r)}| j"                  s|| j%                  |       Y d }~kd }~ww xY ww)Nz{%s listener background task started. Storing all messages in appropriate request processor queues / caches to be processed.r   rL   eth_subscriptionF)subscriptionz9Message listener background task has ended gracefully: %s)r   r   r<   __qualname__r7   r   r   rq   rr   r   getr5   cache_raw_responser   r   user_message	Exceptionr,   "_error_log_listener_task_exception)r;   rb   r   r   s       r=   r   z.PersistentConnectionProvider._message_listener  s@    MNN''	

  --"""?!%!F!F!HHh-B8LH &h5 LL*.@@ 
 --@@< A    335'  # I 0   ONN
  ?<<G;;A>>	?ss   A
EC!EC' %C#&A%C' C%C'  E#C' %C' '	E0&DEE'EEEEr   c                 f    | j                   j                  d|j                  j                  |       y)z
        When silencing listener task exceptions, this method is used to log the
        exception and keep the listener task alive. Override this method to fine-tune
        error logging behavior for the implementation class.
        zhException caught in listener, error logging and keeping listener background task alive.
    error=%s: %sN)r   r   r<   __name__)r;   r   s     r=   r   z?PersistentConnectionProvider._error_log_listener_task_exception  s,     	@KK  		
r>   c                     t        | dd      }|r2|j                         r!|j                         r|j                         yyy)z
        Should be called every time a `PersistentConnectionProvider` is polling for
        messages in the main loop. If the message listener task has completed and an
        exception was recorded, raise the exception in the main loop.
        r6   N)getattrdone	exception)r;   msg_listener_tasks     r=    _handle_listener_task_exceptionsz=PersistentConnectionProvider._handle_listener_task_exceptions  sM     $D*BDI!&&(!++-#--// . ) r>   
request_idtimeoutc                     K   | j                   }dt        f fd}	 t        j                   |       |       d {   S 7 # t        j                  $ r t        d d j                    d      w xY ww)Nr0   c                  <  K   t              } 	 j                          | j                  j                  v rBj                  j                  d       j                  j                  |        d {   }|S t        j                  d       d {    7 $7 w)Nz&Popping response for id %s from cache.)rX   r   )	r   r   r5   r   r   debugpop_raw_responser7   r   )request_cache_keypopped_responser   r;   s     r=    _match_response_id_to_request_idzcPersistentConnectionProvider._get_response_for_request_id.<locals>._match_response_id_to_request_id  s      2: > 557$(?(?(W(WWKK%%@" -1,C,C,T,T"3 -U - 'O +*!--*** '
 +s$   A0B3B4BBBBz0Timed out waiting for response with request id `z` after z second(s). This may be due to the provider not returning a response with the same id that was sent in the request or an exception raised during the request was caught and allowed to continue.)r*   r    r7   wait_forTimeoutErrorr   )r;   r   r   r   s   ``  r=   r   z9PersistentConnectionProvider._get_response_for_request_id  s      ?**G	+ 	+(	 !))*J*LgVVVV## 	B:,h''( )'' 	s-   A9A A A A9A 0A66A9)r0   N)r   zasyncio.Task[None]r0   NrC   )<r   
__module__r   logging	getLoggerr   has_persistent_connectionr%   r   r
   r   r   r   r   r   __annotations__r&   r    r'   r	   r(   %DEFAULT_PERSISTENT_CONNECTION_TIMEOUTfloatboolr4   rY   re   rk   rx   r}   r   r   r   r   r   rP   r   r_   r   rj   rp   r   r   bytesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)r<   s   @r=   r$   r$   C   s	   WLMF $ 	 exiS*8L.M)M NOO 
 	 exiS+8M.N)N OPP 
 	 ExiS$zBR8R.S)S TUU 
 	 ExiS${BS8S.T)T UVV  "G0316&'.1QQ +.Q +/	Q
 !$Q ),Q Q 
Q0(((<M(	#yc:!566	7(0(((<M(	(4.(.<M.	#yc4
+;!;<<	=...(.<M.	#yc4+<!<==	>.>	c 	 6D
*  c j  
 J* J J J88 8 
	8U;#345	j	":.	k	@U;#345@	k	@ Ge G G G G; G GGGG G
,
%9
	
(%?N
I 
$ 
0 QU&tE{ 23&>Fuo&	&r>   r$   )2abcr   r   r7   r   r   typingr   r   r   r   r	   r
   r   r   r   
websocketsr   r   web3._utils.batchingr   r   web3._utils.cachingr   !web3._utils.caching.caching_utilsr   r   web3._utils.validationr   web3.exceptionsr   r   r   r   r   web3.providers.async_baser   +web3.providers.persistent.request_processorr   
web3.typesr   r   r   r    web3r!   web3.middleware.baser"   r   r$   r2   r>   r=   <module>r     s      
 
 

   4 )- %|#8# |r>   