-
Notifications
You must be signed in to change notification settings - Fork 37
feat(1474): expose ledger-emitted events from the node #1849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
m2ux
wants to merge
21
commits into
main
Choose a base branch
from
feat/1474-ledger-events-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
7bad928
chore(1474): initialize work package branch
m2ux 2464e1f
feat(events): T1 surface ledger event stream from apply sites (midnigβ¦
m2ux 2c3c23c
feat(events): T2 define LedgerEvent wire types and additive events fiβ¦
m2ux b45bdd1
feat(events): T3 tagged-serialise ledger events into the return strucβ¦
m2ux d1fe4f9
feat(events): T5 deposit one LedgerEvent per ledger event on pallet-mβ¦
m2ux 3926a27
feat(events): T6 deposit LedgerEvent on pallet-midnight-system (midniβ¦
m2ux d9bb073
feat(events): T7 add bench_block_full_of_events pricing guardrail (miβ¦
m2ux cf1bcd4
docs(events): T8 document ledger-event surface and pricing (midnight-β¦
m2ux 7ae9a5f
docs(events): T9 add runtime change-file entry (midnight-node#1474)
m2ux 06f67ce
refactor(events): trim comment verbosity per manual review (midnight-β¦
m2ux 216fdfd
test(events): ledger-crate coverage for ledger events (midnight-node#β¦
m2ux 6d7457e
test(events): pallet-midnight coverage for ledger events (midnight-noβ¦
m2ux ae03405
Merge branch 'main' into feat/1474-ledger-events-v2
m2ux 84169dd
fix(events): allow clippy::type_complexity on ledger apply return typβ¦
m2ux 61c9c34
chore: rebuild metadata (midnight-node#1474)
m2ux 0ea9a90
fix(1474): remediate runtime-review findings on ledger events (#1474)
m2ux 233f28d
Merge origin/main into feat/1474-ledger-events-v2
m2ux 47b42cd
Merge origin/main into feat/1474-ledger-events-v2
m2ux ca06032
Merge branch 'main' of github.com:midnightntwrk/midnight-node into feβ¦
m2ux 5a3941a
fix(1474): link ledger-events doc in README and sync openrpc.json to β¦
m2ux bc3821f
fix(1474): bound system-tx event weight to the governance-motion prooβ¦
m2ux File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
m2ux marked this conversation as resolved.
m2ux marked this conversation as resolved.
m2ux marked this conversation as resolved.
m2ux marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #runtime | ||
| # Expose ledger events as runtime events | ||
|
|
||
| The runtime now surfaces the per-transaction event stream that the ledger | ||
| produces when it applies a transaction. Each ledger event is deposited as a | ||
| Substrate runtime event: `pallet_midnight::Event::LedgerEvent` for user | ||
| transactions and `pallet_midnight_system::Event::LedgerEvent` for system | ||
| transactions. Both variants are appended last, so the existing event variants | ||
| and their indices are unchanged. | ||
|
|
||
| A `LedgerEvent` carries a SCALE routing header (`transaction_hash`, | ||
| `logical_segment`, `physical_segment`) plus the ledger's own tagged | ||
| serialisation of the event details as opaque bytes, so the wire shape is stable | ||
| across ledger versions. Consumers read events from `frame_system::Events` via | ||
| `state_subscribeStorage` / `state_getStorage` instead of re-applying | ||
| transactions. Emission is non-consensus and unpriced; see `docs/ledger-events.md`. | ||
|
|
||
| Requires a metadata rebuild. | ||
|
|
||
| PR: https://github.com/midnightntwrk/midnight-node/pull/1849 | ||
| Issue: https://github.com/midnightntwrk/midnight-node/issues/1474 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| #toolkit #runtime | ||
| # Bump runtime spec version to 2.2.0 | ||
|
|
||
| The merged runtime combines the 2.1.0 changes (pallet-babe, session-keys migration) with the new `System.Events` ABI (the `LedgerEvent` variants) and the versioned ledger host function, so it takes the next distinct runtime identity `2_002_000`. | ||
|
|
||
| PR: https://github.com/midnightntwrk/midnight-node/pull/1474 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # Ledger events | ||
|
|
||
| The node surfaces the per-transaction event stream that the [midnight-ledger](https://github.com/midnightntwrk/midnight-ledger) produces when it applies a transaction. Each ledger event is deposited as a Substrate runtime event, so consumers read it through standard Substrate tooling instead of re-applying transactions locally. | ||
|
|
||
| ## What is emitted | ||
|
|
||
| When a transaction is applied, the ledger emits a `Vec<Event>` describing the effects (Zswap inputs and outputs, contract deploys, contract logs, parameter changes, dust events). The node forwards each of these as one runtime event: | ||
|
|
||
| - `pallet_midnight::Event::LedgerEvent(LedgerEvent)` β for user transactions applied through `send_mn_transaction`. | ||
| - `pallet_midnight_system::Event::LedgerEvent(LedgerEvent)` β for system transactions (parameter changes, initial dust UTXOs, dust generation). | ||
|
|
||
| Both variants are appended last on their event enums, so the existing event variants and their indices are unchanged. | ||
|
|
||
| A `LedgerEvent` is: | ||
|
|
||
| ```rust | ||
| pub struct LedgerEvent { | ||
| pub source: LedgerEventSource, | ||
| pub content_tagged_bytes: Vec<u8>, | ||
| } | ||
|
|
||
| pub struct LedgerEventSource { | ||
| pub transaction_hash: [u8; 32], | ||
| pub logical_segment: u16, | ||
| pub physical_segment: u16, | ||
| } | ||
| ``` | ||
|
|
||
| `source` is the routing header β a SCALE mirror of the ledger's `EventSource` (tag `event-source[v1]`, stable across every ledger version the node links). It lets a consumer route on `(transaction_hash, logical_segment, physical_segment)` without decoding the payload. | ||
|
|
||
| `content_tagged_bytes` is the ledger's own tagged serialisation of the event's `EventDetails`. It is left opaque to the runtime: the runtime never needs to inspect event contents, and keeping the payload opaque means a future ledger upgrade that extends the event enum does not change this wire shape. | ||
|
|
||
| Only committed transactions emit events. A failed transaction emits none, a partially-successful transaction emits events only for the segments that succeeded, and dry-run / mempool-validation paths never emit events. | ||
|
|
||
| ## Consuming events (indexer authors) | ||
|
|
||
| Read the events for a block from `frame_system::Events`, either by subscribing to storage changes or by reading the storage value at a finalised block hash: | ||
|
|
||
| - `state_subscribeStorage([System.Events])` for a live feed. | ||
| - `state_getStorage(System.Events, blockHash)` for a specific block. | ||
|
|
||
| `frame_system::Events` is cleared at the start of each block, so it holds only the events for the block being queried. Runtime events live in the state trie, not in the gossiped block body β every full node re-derives them locally by executing the block's extrinsics. | ||
|
|
||
| For each `LedgerEvent` record, decode `content_tagged_bytes` with the matching ledger version's `tagged_deserialize::<EventDetails>`. The tag is a self-describing byte-prefix: it identifies both the type and the ledger version that produced it (`event-details[v9]` for the v7/v8-era ledgers, `event-details[v14]` for the v9-era ledger). A version-aware consumer dispatches on the prefix and selects the matching decoder; the node applies no version logic of its own. | ||
|
|
||
| ## Contract event namespacing (contract authors) | ||
|
|
||
| A contract event arrives as an `EventDetails::ContractLog` inside `content_tagged_bytes`, carrying the emitting contract's `address` and the `entry_point` that produced it. Combined with the `source` routing header, the `(address, entry_point)` pair is the namespace for a contract-emitted event: two contracts that emit under the same `entry_point` remain distinguishable by their `address`. There is no separate node-side topic field β the address and entry point already travel inside the event payload. | ||
|
|
||
| ## Pricing | ||
|
|
||
| Event emission is deliberately left unpriced: `deposit_event` carries no per-event weight term and there is no event cap. This matches the upstream FRAME convention for `frame_system::Events` (whitelisted, unbounded storage that is excluded from weight benchmarking). Event volume is transitively bounded by the ledger's per-block synthetic-cost limits (`bytes_churned`), which the transaction fee already pays for, and midnight-node is not a parachain, so there is no proof-of-validity inflation concern. | ||
|
|
||
| The `bench_block_full_of_events` benchmark in `pallets/midnight/src/benchmarking.rs` is the guardrail for this decision: it fills a block with a worst-case event stream and measures the deposit cost against the block weight budget. If a future ledger version ever decouples event volume from state churn, the documented fallback is to add a per-event weight term to the transaction weight β a runtime-side change that does not affect the wire shape above. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.