Core concepts
There are two central objects in the event ring C API. They are:- struct
monad_event_ring- represents an event ring whose shared memory segments have been mapped into the address space of the current process; the primary thing the client does with this object is use it to initialize iterators that point into the event ring, using themonad_event_ring_init_iteratorfunction - struct
monad_event_iterator- the star of the show: this iterator object is used to read sequential events. The iterator’stry_nextoperation copies the current event descriptor (if it is available) and if successful, advances the iterator. Conceptually, it behaves like the expressiondescriptor = *i++, if an event descriptor is ready immediately (it does nothing otherwise)
eventwatch example program. This program dumps ASCII representations of
execution events to stdout, as they are written by a execution daemon
running on the same host.
In eventwatch, the event descriptors are fully decoded, but the event
payloads are only shown in hexdump form, because this simple program that does
not include pretty-printing logic for all event payload types. The program is
only 250 lines of code, and reading through it should explain how the various
API calls fit together.
The SDK also includes C++20
std::formatter
specializations which can fully decode event payloads into human-readable form.
These are used by the monad-event-cli utility program.
Using the API in your project
libmonad_event is designed for third party integration, so it does not have
any library dependencies aside from a recent version of glibc. This also means
it has no dependency on the rest of the monad repository or on its build
system: the sole requirement is a C compiler supporting C23.
The “Getting start” guide to building the C example program
discusses several ways
to use the SDK library as a third-party dependency in your code. Alternatively,
the source files that make up the library target can be copied into your own
codebase. A Rust client library is also available.
API overview
Event ring APIs
| API | Purpose |
|---|---|
monad_event_ring_mmap | Given a file descriptor to an open event ring file, map its shared memory segments into the current process, initializing a struct monad_event_ring |
monad_event_ring_init_iterator | Given a pointer to a struct monad_event_ring, initialize an iterator that can read from the event ring |
monad_event_ring_try_copy | Given a specific sequence number, try to copy the event descriptor for it, if it hasn’t been overwritten |
monad_event_ring_payload_peek | Get a zero-copy pointer to an event payload |
monad_event_ring_payload_check | Check if an event payload referred to by a zero-copy pointer has been overwritten |
monad_event_ring_memcpy | memcpy the event payload to a buffer, succeeding only if the payload is not expired |
monad_event_ring_get_last_error | Return a human-readable string describing the last error that occurred on this thread |
errno(3) domain error code
diagnosing the reason for failure. The function
monad_event_ring_get_last_error can be called to provide a human-readable
string explanation of what failed.
Event iterator APIs
| API | Purpose |
|---|---|
monad_event_iterator_try_next | If an event descriptor if is available, copy it and advance the iterator; behaves like *i++, but only if *i is ready |
monad_event_iterator_try_copy | Copy the event descriptor at the current iteration point, without advancing the iterator |
monad_event_iterator_reset | Reset the iterator to point to the most recently produced event descriptor; used for gap recovery |
monad_exec_iter_consensus_prev | Rewinds an iterator to the previous consensus event (BLOCK_START, BLOCK_QC, BLOCK_FINALIZED, or BLOCK_VERIFIED) |
monad_exec_iter_block_number_prev | Rewinds an iterator to the previous consensus event for the given block number |
monad_exec_iter_block_id_prev | Rewinds an iterator to the previous consensus event for the given block ID |
monad_exec_iter_rewind_for_simple_replay | Rewinds an iterator to replay events you may have missed, based on the last finalized block you saw |
Event ring utility APIs
| API | Purpose |
|---|---|
monad_event_ring_check_content_type | Check if the binary layouts of event definitions used by the library match what is recorded in a mapped event ring |
monad_event_ring_find_writer_pids | Find processes that have opened an event ring file descriptor for writing; used for detecting publisher exit |
monad_check_path_supports_map_hugetlb | Check if a path is on a filesystem that allows its files to be mmap’ed with MAP_HUGETLB |
monad_event_open_hugetlbfs_dir_fd | Open the default hugetlbfs directory where event ring files are created1 |
monad_event_resolve_ring_file | If a path contains no / character (i.e., if it is a “pure” filename), resolve it relative to some default event ring directory2 |
monad_event_is_snapshot_file | Check if a path refers to an event ring snapshot file |
monad_event_decompress_snapshot_fd | Decompress the event ring snapshot contained in the given file descriptor |
monad_event_decompress_snapshot_mem | Decompress the event ring snapshot contained in the given memory buffer |
Library organization
Event ring files inlibmonad_event:
| File | Contains |
|---|---|
event_ring.{h,c} | Definitions of core shared memory structures for event rings, and the API that initializes and mmaps event ring files |
event_iterator.h | Defines the basic event iterator object and its API |
event_iterator_inline.h | Definitions of the event_iterator.h functions, all of which are inlined for performance reasons |
event_metadata.h | Structures that describe event metadata (string names of events, descriptions of events, etc.) |
exec_iter_help.h | API for rewinding the the iterator to point to block executions or consensus events |
libmonad_event:
| File | Contains |
|---|---|
base_ctypes.h | Definitions of basic vocabulary types common in Ethereum data (e.g., 256 bit integer types, etc). |
eth_ctypes.h | Definitions of structures used in the Ethereum virtual machine |
exec_event_ctypes.h | Definition of execution event payload structures, and the event type enumeration enum monad_exec_event_type |
exec_event_ctypes_metadata.c | Defines static metadata about execution events, and the schema hash value array |
monad_ctypes.h | Definitions of Monad blockchain extensions to Ethereum |
libmonad_event:
| File | Contains |
|---|---|
event_ring_util.{h,c} | Convenience functions that are useful in most event ring programs, but which are not part of the core API |
format_err.{h,c} | Helper utility from the execution codebase used to implement the monad_event_ring_get_last_error() function |
srcloc.h | Helper utility used with the format_err.h API, for capturing source code locations in C |
| File | Contents |
|---|---|
eventwatch.c | A sample program that shows how to use the API |
*_fmt.hpp files | Files ending in _fmt.hpp are used with C++ <format> and contain std::formatter specializations for SDK types |
hex.hpp | <format> hexdump utility used by the _fmt.hpp files to dump uint8_t[] values |

