# LP-0012: Event/Log mechanism: Structured events for LEZ program execution [OPEN] **`Logos Circle: N/A`** ## Overview This prize is for designing and implementing a *structured event system* that lets LEZ programs emit events describing what happened during execution in a way that is both *human-interpretable* (debugging, wallet UX) and *machine-readable* (indexers, explorers, apps). Events must be retrievable by clients after execution and must still be emitted even when a transaction fails. Other ecosystems demonstrate the value of making execution metadata available to clients: Solana exposes per-transaction `meta.logMessages` (alongside `meta.err`) via RPC, which is widely used for debugging. Cosmos SDK treats events as a first-class client interface for explorers and wallets, returning structured type/attribute events in ABCI results rather than storing them in state. ## Motivation Currently, program-level feedback is too limited for good UX and tooling: developers and users struggle to understand *why* execution failed, indexers cannot reliably classify activity, and explorers/wallets cannot provide meaningful post-transaction narratives. A prize is appropriate because there are multiple plausible designs with important trade-offs (format/encoding, namespacing, ordering, size limits, failure semantics, privacy considerations). We want builders to propose and implement competing approaches, then adopt the one that is simplest, robust, and most indexer-friendly. ## Example ```rust fn main() { let ( ProgramInput { pre_states, instruction: Withdraw { amount }, }, instruction_data, ) = read_nssa_inputs::(); let [pre_state] = pre_states.try_into().unwrap(); let balance = read_balance(&pre_state.account); if balance < amount { // <<<<<< EVENT HERE emit_event(InsufficientFunds { account: pre_state.account.address, requested: amount, available: balance, }); panic!("Insufficient funds"); } write_nssa_outputs(instruction_data, vec![pre_state], vec![post_state]); } ``` ## Success Criteria ### Functionality - [ ] Event API for programs: Provide a Rust-facing API usable inside LEZ programs, e.g. `emit_event(MyEvent { ... })`, that supports emitting typed events with structured fields. - [ ] Machine-readable format: Events are encoded deterministically with: - stable versioning, - stable ordering, - explicit program attribution (e.g., `program_id` included or enforced by runtime), - and a documented schema strategy (e.g., discriminant + bytes payload; or key-value attributes with ordering). - [ ] Human-friendly rendering: Provide a reference decoder/formatter that renders events into a readable form (CLI output or JSON) for debugging. - [ ] Available post-execution: After transaction execution, clients can retrieve emitted events via a documented interface (e.g., tx receipt / RPC / block data access). - [ ] Emittable on failure: If a transaction fails (program aborts / returns error), events emitted prior to failure are still available to clients (i.e., not discarded with state reversion). - [ ] Testing: Include tests covering: - deterministic encoding/decoding, - event ordering, - size-limit behaviour, - failure-path persistence (“emit then fail” still returns events). ### Usability - [ ] Provide a module/SDK (the event emission API and decoder library) with a documented interface that any LEZ program can import without modifications to the runtime. ### Reliability - [ ] Events emitted prior to a program abort are preserved and retrievable even when the transaction fails — they are never silently discarded. - [ ] Exceeding the per-transaction event size limit produces a documented, deterministic error rather than silent truncation or a panic. ### Performance - [ ] Document the compute unit (CU) cost of emitting an event (per event and per transaction) on LEZ devnet/testnet. Note: LEZ's per-transaction compute budget may change during testnet. ### Supportability - [ ] The event system is deployed and tested on LEZ devnet/testnet with a reference program. - [ ] End-to-end integration tests run against a LEZ sequencer (standalone mode) and are included in CI. - [ ] CI must be green on the default branch. - [ ] A README documents end-to-end usage: how to emit events from a program, retrieve them after execution, and decode them with the reference formatter. - [ ] A reproducible end-to-end demo script is provided and works against a real local sequencer with `RISC0_DEV_MODE=0`. - [ ] A recorded video demo of the end-to-end flow is included in the submission; the recording must show terminal output (including proof generation) to confirm `RISC0_DEV_MODE=0` was active. ## Scope ### In Scope - A clear event model (record structure, attribution rules, encoding). - Rust SDK hooks for emitting events from programs (public and, where relevant, privacy-preserving execution environments). - Runtime/sequencer integration sufficient to make events retrievable after execution and to preserve them in failure cases. - Decoder tooling and documentation for clients/indexers. ### Out of Scope - A full hosted explorer, production indexer stack, or managed data service. - Heavy, framework-wide “magic” (auto-generated IDLs, large macro DSLs) not necessary for event emission. - Privacy-leaking defaults: designs must be explicit about what is emitted and what is safe to emit (especially for private execution), but this prize does not require solving private analytics beyond sensible defaults. ## Prize Structure - **Total Prize:** $1,200 - **Effort:** Large ## Eligibility Open to any individual or team. Submissions must be original work. Teams must hold the rights to all submitted code and agree to license it under MIT or Apache-2.0. ## Submission Requirements - Public repository containing: - implementation (SDK + any runtime/sequencer glue), - event format specification (`docs/event-format.md`), - decoder/formatter tool (CLI or library), - at least one example program demonstrating: - success-path events, - failure-path events (emit then fail), - reference indexer example (can be minimal). - A narrated video walkthrough in which the builder explains what they built and why, walks through the architecture and key implementation decisions, and demonstrates the full end-to-end flow. A silent screencast is not sufficient (see [demo requirements](../README.md#evaluation-policies)). ## Evaluation Process By default, submissions are evaluated first-come-first-served against the success criteria. The first submission that meets **all** criteria wins. Evaluators will independently clone the repository and run the demo script from a clean environment; the script must succeed without modification. Evaluators may also ask technical follow-up questions to verify authorship and understanding of the implementation. The following policies apply to all prizes (see [evaluation policies](../README.md#evaluation-policies)): - **Submissions:** each builder (or team) is allowed a maximum of **3 submissions** per prize, with at most **one submission/review per week**. - **Feedback:** initial evaluation feedback is limited to a pass/fail indication against the success criteria. ## Resources - [LEZ Github repository](https://github.com/logos-blockchain/logos-execution-zone) ## Potential for Subsequent λPrizes This prize targets the current LEZ testnet. Should a future testnet version introduce breaking changes, a subsequent λPrize may be opened to cover the necessary adaptation and redeployment.