11"""JSON-RPC methods and helper functions for EEST consume based hive simulators."""
22
33import json
4+ import logging
45import time
56from itertools import count
7+ from pathlib import Path
68from pprint import pprint
79from typing import Any , ClassVar , Dict , List , Literal , Union
810
@@ -34,22 +36,55 @@ class SendTransactionExceptionError(Exception):
3436
3537 tx : Transaction | None = None
3638 tx_rlp : Bytes | None = None
39+ shorten_errors : bool = False
40+ log_rlp_data : bool = False
3741
38- def __init__ (self , * args , tx : Transaction | None = None , tx_rlp : Bytes | None = None ):
42+ def __init__ (
43+ self ,
44+ * args ,
45+ tx : Transaction | None = None ,
46+ tx_rlp : Bytes | None = None ,
47+ shorten_errors : bool = False ,
48+ log_rlp_data : bool = False ,
49+ ):
3950 """Initialize SendTransactionExceptionError class with the given transaction."""
4051 super ().__init__ (* args )
4152 self .tx = tx
4253 self .tx_rlp = tx_rlp
54+ self .shorten_errors = shorten_errors
55+ self .log_rlp_data = log_rlp_data
4356
4457 def __str__ (self ):
4558 """Return string representation of the exception."""
59+ # create ./logs/rlp folder for detailed rlp logging
60+ rlp_logs_folder = Path ("." ) / "logs" / "rlp"
61+ rlp_logs_folder .mkdir (parents = True , exist_ok = True )
62+
4663 if self .tx is not None :
4764 f"{ super ().__str__ ()} Transaction={ self .tx .model_dump_json ()} "
4865 elif self .tx_rlp is not None :
4966 tx_rlp_hex = self .tx_rlp .hex ()
50- if len (tx_rlp_hex ) > 1000 :
51- tx_rlp_hex = tx_rlp_hex [:50 ] # if it's very long just print first few chars
67+
68+ # log rpc call data to file (each rlp object gets dumped in its own file)
69+ if self .log_rlp_data :
70+ # create and config a temporary logger (unique filename via timestamp)
71+ timestamp = time .time_ns ()
72+ file_name = rlp_logs_folder / f"{ timestamp } _rlp_data.log"
73+ temp_logger = logging .getLogger (f"rlp_{ timestamp } " )
74+ temp_logger .setLevel (logging .ERROR )
75+ temp_logger .propagate = False
76+ file_handler = logging .FileHandler (file_name )
77+ temp_logger .addHandler (file_handler )
78+ # log rlp to file
79+ temp_logger .error (tx_rlp_hex )
80+ # cleanup
81+ temp_logger .removeHandler (file_handler )
82+ file_handler .close ()
83+
84+ if self .shorten_errors :
85+ tx_rlp_hex = tx_rlp_hex [:50 ] # just print first few chars
5286 return f"{ super ().__str__ ()} Transaction RLP={ tx_rlp_hex } "
87+
5388 return super ().__str__ ()
5489
5590
@@ -198,9 +233,8 @@ def send_raw_transaction(self, transaction_rlp: Bytes) -> Hash:
198233 assert result_hash is not None , "result_hash seems to be None, critical error!"
199234 return result_hash
200235 except Exception as e :
201- shortened_rlp_error_message = str (e ) # signal in console that you don't see full rlp
202236 raise SendTransactionExceptionError (
203- shortened_rlp_error_message , tx_rlp = transaction_rlp
237+ str ( e ) , tx_rlp = transaction_rlp , shorten_errors = True , log_rlp_data = True
204238 ) from e
205239
206240 def send_transaction (self , transaction : Transaction ) -> Hash :
@@ -213,7 +247,9 @@ def send_transaction(self, transaction: Transaction) -> Hash:
213247 assert result_hash is not None
214248 return transaction .hash
215249 except Exception as e :
216- raise SendTransactionExceptionError (str (e ), tx = transaction ) from e
250+ raise SendTransactionExceptionError (
251+ str (e ), tx = transaction , shorten_errors = True , log_rlp_data = True
252+ ) from e
217253
218254 def send_transactions (self , transactions : List [Transaction ]) -> List [Hash ]:
219255 """Use `eth_sendRawTransaction` to send a list of transactions to the client."""
0 commit comments