Feature/sma 105 audit log in memory ring buffer for read path#209
Merged
Conversation
…types-config-serde
…-101-audit-log-trait-noop-factory-composition-root-wiring
…-102 Integrate SMA-101 wiring (enabled flag, audit in ElectionRunner) with JsonlAuditLog implementation: factory returns NoopAuditLog when disabled and starts JsonlAuditLog when enabled. Co-authored-by: Cursor <[email protected]>
Take sma-99 audit writer/log hardening (oneshot shutdown, rotated paths, shutdown timeout, flush/recovery). Adapt to SMA-103 event format: AuditFileHeader, system_audit_events_dropped constructor, payload.source() in record diagnostics, header-aware writer tests. Co-authored-by: Cursor <[email protected]>
… events to CLI - Merge feature/sma-104-audit-log-rest-producers-auditactorbuilder into current branch - Resolve conflicts: AppState gains both audit_ring (SMA-105) and actor_builder (SMA-104) - Fix RestApiAuthLoginSuccess → RestApiAuthLoginSucceeded in event.rs and auth_tests.rs - Add recent elections audit events to GET /v1/elections response (recent_events field, newest-first, from ring buffer) - Add elections events table to `nodectl api elections` CLI output Co-authored-by: Cursor <[email protected]>
…cture' into feature/sma-104-audit-log-rest-producers-auditactorbuilder
- Add `use serde::{Deserialize, Serialize}` to enums.rs (bare derives on
StakeSkipReason/ConfigFieldChange/AuditOutcome broke after SMA-103 merge)
- Add ElectionsTickFailed arm to severity() and source() match blocks
- Restore REST event constructors to event.rs (rest_api_auth_login_success,
rest_api_auth_login_rejected, rest_api_token_rejected, rest_api_config_updated)
removed by SMA-103 merge; required by rest_audit.rs (SMA-104)
- Fix RestApiAuthLoginSuccess -> RestApiAuthLoginSucceeded in auth_tests.rs
Co-authored-by: Cursor <[email protected]>
Co-authored-by: Cursor <[email protected]>
…roducers-auditactorbuilder' into feature/sma-105-audit-log-in-memory-ring-buffer-for-read-path
- Rename ElectionsStakeSubmittedParams.stake_nanotons → stake and elections_stake_recovered param amount_nanotons → amount to match the enum field names introduced by sma-104 (which dropped _nanotons suffixes from all payload fields). - Remove dead duplicate function adaptive_split50_defer_reason that was synthesised by the ort merge strategy from both SMA-103 and SMA-104 versions of adaptive_strategy.rs; the identical logic with node_id is already in adaptive_split50_status. - Update runner.rs and event.rs test fixtures to use the renamed fields. All 310 lib tests pass. Co-authored-by: Cursor <[email protected]>
Remove the intermediate AdaptiveStakeZero enum and move its variants (Defer, NoTopUpNeeded, InsufficientFree) directly into AdaptiveStakeResult. Update all call-sites in runner.rs accordingly, renaming adaptive_zero_to_skip → adaptive_result_to_skip. Co-authored-by: Cursor <[email protected]>
…a-105 Pull SMA-104 review fixes merged into sma-99 (test_support refactor, middleware without headers clone, AppError::internal in config handlers, rest_audit noop-update comment) while keeping sma-105 audit ring buffer. Co-authored-by: Cursor <[email protected]>
Keshoid
reviewed
Jun 12, 2026
Keshoid
left a comment
Contributor
There was a problem hiding this comment.
SMA-105 review — ring buffer for the audit read-path. The implementation is solid (correct push-before-send ordering, lock never held across .await, good concurrency test). Inline notes below: the only one I'd treat as a blocker is the missing dedup test; the rest are nits / confirm-intent.
Keshoid
approved these changes
Jun 15, 2026
fdbc6ec
into
feature/sma-99-audit-log-architecture
10 of 11 checks passed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Add AuditEventBuffer — fixed-capacity FIFO buffer (parking_lot::RwLock, never held across .await) that receives every audit event independently of the JSONL writer. JsonlAuditLog::record() pushes to the ring before the channel send, so events appear immediately and survive queue overflow.
AuditLogFactory now returns AuditComponents { log, ring } so the composition root can hand the ring to AppState.audit_ring for the REST read-path (GET /v1/elections) without touching disk on the hot path.
Default ring capacity: 100 events (configurable via ring_buffer_capacity). Lowered from 10_000 to bound in-memory cost on the hot path; also shrinks the in-ring dedup window for stake_skipped (JSONL writer queue unchanged).
Deduplication of repeated stake_skipped
AuditEvent::dedup_identity() returns a stable key for ElectionsStakeSkipped events (node_id, election_id, reason). JsonlAuditLog atomically checks and pushes via push_unless_dedup_duplicate(), preventing per-tick spam for persistent reasons (ElectionsDisabled, RecoverPending, etc.) while still recording on the first occurrence and again after a service restart (empty ring).
Payload field renames
Remove the _nanotons suffix from all payload fields — the unit is implicit and the name "gram" may change soon:
stake_nanotons → stake amount_nanotons → amount required_nanotons → required available_nanotons → available total_nanotons → total
No in-repo consumer keys on the old field names; audit log not yet on main.
Out of scope (carried in via merge)
src/node/tests/test_load_net/scripts/add-nominators-to-pool.ts — highload workchain default 0 + sendBatch chunking. Landed in f6a28f0 post-merge fixup alongside sma-104 renames; unrelated to SMA-105 ring buffer. Fixes singlehost load-driver batch deploy; no audit impact, CI green.
Tests
ring_buffer.rs: push_below_capacity_keeps_all, push_at_capacity_evicts_oldest, snapshot_returns_in_order, filter_collect_only_matching_events, concurrent_push_and_snapshot_no_panic, zero_capacity_buffer_silently_drops, push_unless_dedup_duplicate_keeps_one_per_node_election_reason.
jsonl_log.rs: record_pushes_to_ring_even_when_queue_full, record_deduplicates_stake_skipped_by_node_election_and_reason.
299 tests pass.
Closes SMA-105.