1- use std:: { ffi:: CStr , time:: Duration } ;
2-
3- use chrono:: { DateTime , Local , TimeZone } ;
1+ use chrono:: { DateTime , Local } ;
42use lazy_static:: lazy_static;
53use monad_event_ring:: {
64 DecodedEventRing , EventDescriptor , EventDescriptorInfo , EventNextResult , EventPayloadResult ,
@@ -11,8 +9,13 @@ use monad_exec_events::{
119 ffi:: { g_monad_exec_event_metadata, MONAD_EXEC_EVENT_COUNT } ,
1210 ExecEventDecoder , ExecEventDescriptorExt , ExecEventRing , ExecSnapshotEventRing ,
1311} ;
12+ use serde:: { Deserialize , Serialize } ;
13+ use std:: { ffi:: CStr , time:: Duration } ;
1414use tracing:: { debug, error, info, warn} ;
1515
16+ use super :: timestamp:: get_unix_time_ns;
17+ use super :: timestamp:: NanoTimestamp ;
18+
1619lazy_static ! {
1720 static ref EXEC_EVENT_NAMES : [ & ' static str ; MONAD_EXEC_EVENT_COUNT ] =
1821 std:: array:: from_fn( |event_type| unsafe {
@@ -22,11 +25,105 @@ lazy_static! {
2225 } ) ;
2326}
2427
28+ /// Type-safe enum for event names based on ExecEvent variants
29+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize ) ]
30+ #[ serde( rename_all = "PascalCase" ) ]
31+ pub enum EventName {
32+ RecordError ,
33+ BlockStart ,
34+ BlockReject ,
35+ BlockPerfEvmEnter ,
36+ BlockPerfEvmExit ,
37+ BlockEnd ,
38+ BlockQC ,
39+ BlockFinalized ,
40+ BlockVerified ,
41+ TxnHeaderStart ,
42+ TxnAccessListEntry ,
43+ TxnAuthListEntry ,
44+ TxnHeaderEnd ,
45+ TxnReject ,
46+ TxnPerfEvmEnter ,
47+ TxnPerfEvmExit ,
48+ TxnEvmOutput ,
49+ TxnLog ,
50+ TxnCallFrame ,
51+ TxnEnd ,
52+ AccountAccessListHeader ,
53+ AccountAccess ,
54+ StorageAccess ,
55+ EvmError ,
56+ }
57+
58+ impl EventName {
59+ /// Convert EventName to string representation
60+ pub fn as_str ( & self ) -> & ' static str {
61+ match self {
62+ EventName :: RecordError => "RecordError" ,
63+ EventName :: BlockStart => "BlockStart" ,
64+ EventName :: BlockReject => "BlockReject" ,
65+ EventName :: BlockPerfEvmEnter => "BlockPerfEvmEnter" ,
66+ EventName :: BlockPerfEvmExit => "BlockPerfEvmExit" ,
67+ EventName :: BlockEnd => "BlockEnd" ,
68+ EventName :: BlockQC => "BlockQC" ,
69+ EventName :: BlockFinalized => "BlockFinalized" ,
70+ EventName :: BlockVerified => "BlockVerified" ,
71+ EventName :: TxnHeaderStart => "TxnHeaderStart" ,
72+ EventName :: TxnAccessListEntry => "TxnAccessListEntry" ,
73+ EventName :: TxnAuthListEntry => "TxnAuthListEntry" ,
74+ EventName :: TxnHeaderEnd => "TxnHeaderEnd" ,
75+ EventName :: TxnReject => "TxnReject" ,
76+ EventName :: TxnPerfEvmEnter => "TxnPerfEvmEnter" ,
77+ EventName :: TxnPerfEvmExit => "TxnPerfEvmExit" ,
78+ EventName :: TxnEvmOutput => "TxnEvmOutput" ,
79+ EventName :: TxnLog => "TxnLog" ,
80+ EventName :: TxnCallFrame => "TxnCallFrame" ,
81+ EventName :: TxnEnd => "TxnEnd" ,
82+ EventName :: AccountAccessListHeader => "AccountAccessListHeader" ,
83+ EventName :: AccountAccess => "AccountAccess" ,
84+ EventName :: StorageAccess => "StorageAccess" ,
85+ EventName :: EvmError => "EvmError" ,
86+ }
87+ }
88+
89+ pub fn from_str ( s : & str ) -> Option < Self > {
90+ match s {
91+ "RECORD_ERROR" => Some ( EventName :: RecordError ) ,
92+ "BLOCK_START" => Some ( EventName :: BlockStart ) ,
93+ "BLOCK_REJECT" => Some ( EventName :: BlockReject ) ,
94+ "BLOCK_PERF_EVM_ENTER" => Some ( EventName :: BlockPerfEvmEnter ) ,
95+ "BLOCK_PERF_EVM_EXIT" => Some ( EventName :: BlockPerfEvmExit ) ,
96+ "BLOCK_END" => Some ( EventName :: BlockEnd ) ,
97+ "BLOCK_QC" => Some ( EventName :: BlockQC ) ,
98+ "BLOCK_FINALIZED" => Some ( EventName :: BlockFinalized ) ,
99+ "BLOCK_VERIFIED" => Some ( EventName :: BlockVerified ) ,
100+ "TXN_HEADER_START" => Some ( EventName :: TxnHeaderStart ) ,
101+ "TXN_ACCESS_LIST_ENTRY" => Some ( EventName :: TxnAccessListEntry ) ,
102+ "TXN_AUTH_LIST_ENTRY" => Some ( EventName :: TxnAuthListEntry ) ,
103+ "TXN_HEADER_END" => Some ( EventName :: TxnHeaderEnd ) ,
104+ "TXN_REJECT" => Some ( EventName :: TxnReject ) ,
105+ "TXN_PERF_EVM_ENTER" => Some ( EventName :: TxnPerfEvmEnter ) ,
106+ "TXN_PERF_EVM_EXIT" => Some ( EventName :: TxnPerfEvmExit ) ,
107+ "TXN_EVM_OUTPUT" => Some ( EventName :: TxnEvmOutput ) ,
108+ "TXN_LOG" => Some ( EventName :: TxnLog ) ,
109+ "TXN_CALL_FRAME" => Some ( EventName :: TxnCallFrame ) ,
110+ "TXN_END" => Some ( EventName :: TxnEnd ) ,
111+ "ACCOUNT_ACCESS_LIST_HEADER" => Some ( EventName :: AccountAccessListHeader ) ,
112+ "ACCOUNT_ACCESS" => Some ( EventName :: AccountAccess ) ,
113+ "STORAGE_ACCESS" => Some ( EventName :: StorageAccess ) ,
114+ "EVM_ERROR" => Some ( EventName :: EvmError ) ,
115+ _ => {
116+ warn ! ( "Unknown event name: {}" , s) ;
117+ None
118+ }
119+ }
120+ }
121+ }
122+
25123#[ derive( Debug , Clone ) ]
26124pub struct EventData {
27- pub timestamp : String ,
28- pub event_name : String ,
29- pub event_type : u16 ,
125+ pub timestamp_ns : NanoTimestamp ,
126+ pub event_name : EventName ,
30127 pub seqno : u64 ,
31128 pub block_number : Option < u64 > ,
32129 pub txn_idx : Option < usize > ,
@@ -55,16 +152,14 @@ fn event_to_data(event: &EventDescriptor<ExecEventDecoder>) -> Option<EventData>
55152 let EventDescriptorInfo {
56153 seqno,
57154 event_type,
58- record_epoch_nanos,
155+ record_epoch_nanos : _ ,
59156 flow_info,
60157 } = event. info ( ) ;
61158
62- let timestamp = Local
63- . timestamp_nanos ( record_epoch_nanos as i64 )
64- . format ( "%H:%M:%S.%9f" )
65- . to_string ( ) ;
159+ let timestamp_ns = get_unix_time_ns ( ) ;
66160
67- let event_name = EXEC_EVENT_NAMES [ event_type as usize ] . to_string ( ) ;
161+ // Convert event_type to EventName enum for type safety
162+ let event_name = EventName :: from_str ( EXEC_EVENT_NAMES [ event_type as usize ] ) ?;
68163
69164 // Get block number if present
70165 let block_number = if flow_info. block_seqno != 0 {
@@ -86,19 +181,18 @@ fn event_to_data(event: &EventDescriptor<ExecEventDecoder>) -> Option<EventData>
86181 } ;
87182
88183 Some ( EventData {
89- timestamp ,
184+ timestamp_ns ,
90185 event_name,
91- event_type,
92186 seqno,
93187 block_number,
94188 txn_idx,
95189 payload,
96190 } )
97191}
98192
99- pub fn start_event_listener (
193+ pub fn run_event_listener (
100194 event_ring_path : EventRingPath ,
101- tx : tokio:: sync:: mpsc:: Sender < EventData > ,
195+ event_sender : tokio:: sync:: mpsc:: Sender < EventData > ,
102196) -> std:: thread:: JoinHandle < ( ) > {
103197 std:: thread:: spawn ( move || {
104198 info ! ( "Starting event listener thread" ) ;
@@ -196,7 +290,7 @@ pub fn start_event_listener(
196290 if let Some ( event_data) = event_to_data ( & event) {
197291 // Send to channel; if receiver is dropped, exit thread
198292 // Use blocking_send since we're in a blocking thread
199- if tx . blocking_send ( event_data) . is_err ( ) {
293+ if event_sender . blocking_send ( event_data) . is_err ( ) {
200294 warn ! ( "Channel receiver dropped, exiting listener thread" ) ;
201295 return ;
202296 }
0 commit comments