Skip to content

cuprated: add node event streaming API (Node::events())#10

Open
orrinfrazier wants to merge 1 commit into
mainfrom
fix/S07-1-node-event-streaming
Open

cuprated: add node event streaming API (Node::events())#10
orrinfrazier wants to merge 1 commit into
mainfrom
fix/S07-1-node-event-streaming

Conversation

@orrinfrazier
Copy link
Copy Markdown
Owner

@orrinfrazier orrinfrazier commented May 24, 2026

Closes #20

Summary

Changes

Piece 1 — event types + Node plumbing (events.rs, lib.rs)

  • New events module: NodeEvent { NewBlock { height, hash }, Reorg { split_height, new_top_hash, new_chain_height } }; a pub(crate) NodeEventSender wrapping tokio::sync::broadcast (capacity 256); a public NodeEventListener (recv / try_recv / resubscribe).
  • The sender is created once in launch(), stored in LaunchContext, and Node::events() returns a fresh, forward-looking listener.

Piece 2 — manager publishes events (manager.rs, manager/handler.rs)

  • BlockchainManager gains a node_events sender (clone of the launch sender — single shared channel).
  • NewBlock is published from add_valid_block_to_main_chain only for live BlockSource::Incoming blocks (peer relay or RPC submit_block) — mirroring the existing peer-broadcast filter.
  • Reorg is published from try_do_reorg on the success arm.

Design decisions

  • broadcast, not watch — discrete events with multiple independent consumers; watch would drop blocks.
  • NewBlock excludes batch-sync and reorg re-applies — initial-sync progress is already observable via the existing node.syncer handle (target_height() / wait_for_synced()), and a reorg surfaces as a single Reorg event. This keeps the stream low-noise and non-overlapping.
  • Deferred by design (rationale): SyncProgress/Synced (already pollable via SyncerHandle) and PeerConnected/Disconnected (no clean source exists in cuprated — would require cuprate-p2p changes). Good follow-ups once there's demand.

Testing

  • 7 new tests + the 3 pre-existing reorg tests pass (18 lib tests + 2 doc-tests green).
  • Event-API unit tests: prior subscriber receives, multiple subscribers, no-subscriber is a no-op, late subscriber misses prior events (forward-looking), capacity constant.
  • Manager integration tests (via the existing mock_manager harness): adding a live block emits exactly one NewBlock{ height: 1, hash }; a reorg emits a Reorg{ split_height: 2, .. } and no NewBlock for re-applied blocks.
  • cargo clippy --package cuprated --all-targets -- -D warnings and cargo fmt --check clean. No new dependencies (tokio already present).

How to test

let node = Node::launch(config).await?;
let mut events = node.events();
while let Ok(ev) = events.recv().await {
    match ev {
        NodeEvent::NewBlock { height, hash } => { /* ... */ }
        NodeEvent::Reorg { split_height, new_chain_height, .. } => { /* ... */ }
    }
}

Reviewer notes

Reviewed via 3-way cross-family consensus (Claude + Gemini + Codex) with an opus adjudicator: 0 blockers. One low doc nit was accepted and applied (the NewBlock doc now notes Incoming includes locally-submitted RPC blocks, not only peer relay). One finding (a claim that resubscribe() inherits lag state) was rejected — tokio's resubscribe is forward-looking from the current tail.

Related: Cuprate#616 (tracking), Cuprate#554 (API proposal), Cuprate#592 (merged launch).

Add a NodeEvent enum and Node::events() returning a subscribable
NodeEventListener so embedders can observe node activity without polling.

- New events module: NodeEvent { NewBlock, Reorg }, a pub(crate)
  NodeEventSender wrapping tokio::sync::broadcast (cap 256), and a public
  NodeEventListener (recv/try_recv/resubscribe).
- Sender threaded through LaunchContext into the BlockchainManager;
  Node::events() returns a fresh forward-looking listener.
- NewBlock is published from add_valid_block_to_main_chain only for live
  BlockSource::Incoming blocks (peer relay or RPC submit_block); Reorg is
  published from try_do_reorg on success. Batch-sync and reorg re-applies
  do not emit NewBlock.

Implements the event-streaming item of the Cuprate#616 tracking issue and the
Cuprate#554 proposal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cuprated library: add node event streaming API (Node::events())

1 participant