[1.12.0] cherry-pick #140: fix(x/audit) bridge cascade_kademlia_db_bytes from HostReport to SupernodeMetricsState#141
Merged
mateeullahmalik merged 2 commits intoMay 12, 2026
Conversation
…ernodeMetricsState LEP-6 §12 (PR #122) removed cascade_kademlia_db_bytes from the audit HostReport and rewrote x/supernode getLatestCascadeBytesFromAudit to read from SupernodeMetricsState. The migration was half-completed: no chain-side writer was added to populate SupernodeMetricsState.CascadeKademliaDbBytes from the audit epoch-report channel. The only remaining writer is the now-operationally-dead legacy MsgReportSupernodeMetrics handler. Result on chain 1.12.0 / master today: every Everlight payout-period distribution sees getLatestCascadeBytesFromAudit return found=false for every SuperNode → distributePool skips every candidate → pool is never disbursed. Confirmed live on devnet. This change: 1. Restores HostReport.cascade_kademlia_db_bytes (field 6) on the audit epoch-report proto purely as a metric-courier. The audit module does NOT consume the value for its own consensus logic (LEP-6 §12 intent preserved); it only carries the value into the chain on the audit submission channel that SuperNodes already use. 2. Adds validation in SubmitEpochReport: cascade_kademlia_db_bytes must be a finite number ≥ 0 (NaN, +Inf, -Inf, negative rejected with new ErrInvalidHostMetric). Zero is valid (empty Kademlia store). 3. Adds bridgeCascadeBytesToSupernodeMetrics: after the epoch report is successfully persisted, the audit handler upserts the reporter's SupernodeMetricsState via supernodeKeeper.SetMetricsState — read- modify-write so any non-cascade fields previously persisted are preserved. Bumps Height to current block and ReportCount. 4. Defensive no-op (with audit_cascade_bytes_bridge_skipped event for observability) when the SuperNode record has empty/invalid ValidatorAddress — that is a pre-existing x/supernode invariant violation outside audit's scope; the bridge surfaces it via event but does not fail the epoch report on someone else's data corruption. This is now the SOLE writer of SupernodeMetricsState.CascadeKademliaDbBytes post-LEP-6 §12 (legacy MsgReportSupernodeMetrics handler remains in the codec but no SN sends it; left for a follow-up cleanup PR). Tests: - 4 unit tests covering invariant violations (NaN, +Inf, -Inf, negative) - 1 happy-path test (value bridged into MetricsState with correct validator address, height, ReportCount) - 1 zero-valid test - 1 read-modify-write preservation test (non-cascade fields preserved) - 1 defensive no-op test (empty ValidatorAddress emits event, accepts report, does not call Get/SetMetricsState) - Existing 2 storagefull-transition tests updated with Get/SetMetricsState AnyTimes expectations. make integration-tests passes (incl. tests/integration/everlight, tests/integration/audit, tests/integration/supernode). go vet -tags system_test ./... clean in tests/systemtests/.
After the audit→supernode metrics bridge added in this PR, the SupernodeMetricsState is written on every accepted epoch report. The sn-eligibility query now reaches the threshold gate (rawBytes=0) and returns 'cascade bytes below minimum threshold' instead of the pre-bridge 'no audit epoch report found' (which was a symptom of no writer existing). Substantive outcome — SN ineligible, no payout while storage-full — is unchanged. Only the rejection reason advances by one step. Fixes: failing system test TestEverlightSystem_PayoutAndHistoryWhileStorageFull on PR #140 CI.
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
Cherry-pick of #140 (
2c5ee772) onto the1.12.0release branch.PR #140 (merged to
master) restores thecascade_kademlia_db_bytesbridge fromHostReport(audit module) →SupernodeMetricsState(supernode module). Without this bridge, Everlight reward distribution reads zero cascade-bytes and pays out zero to all SNs.Behavior change
HostReportproto regains field 6 (cascade_kademlia_db_bytes,double) as a metric-courier. The audit module does not consume this field for any audit decision — preserving LEP-6 §12 intent. It is bridged throughSubmitEpochReportintoSupernodeMetricsState.CascadeKademliaDbBytes, wheregetLatestCascadeBytesFromAudit(Everlight) reads it.SubmitEpochReportbecomes the single writer ofSupernodeMetricsState.CascadeKademliaDbBytes. The disabled legacyMsgReportSupernodeMetricshandler is no longer the silent zero-source.Rationale
After LEP-6 consolidation (#117, #122),
getLatestCascadeBytesFromAuditwas repointed atSupernodeMetricsState, but no writer was wired up post-disable ofMsgReportSupernodeMetrics. Result: Everlight payout = 0 for every SN, every period. Devnet validation confirmed this end-to-end.Risks
HostReport. Mainnet rollout MUST go via a coordinatedMsgSoftwareUpgradehalt-height upgrade (NOT a rolling restart). A mixed-binary window will produce an app-hash split — verified the hard way on devnet 2026-05-12.Migration
None required —
SupernodeMetricsStatealready exists; only its write path is restored. No state schema change.Rollback
Revert this commit; pool→SN distribution returns to pre-bridge behavior (pays out zero). Chain state remains consistent.
Validation
go test ./x/audit/... ./x/supernode/...→ all green1.12.0-cherrypick-pr140-2c5ee772binary, deployed across all 5 validatorsepoch_idreports with field 6 — no proto-decode errorssn-api-server→ SDK → SN → chain), SHA-256 hash match on every downloadlumera167yww…), ~98% → active SN. 19 successful cascades grew pool from0 → 4819 ulume.Files
proto/lumera/audit/v1/audit.proto— field 6 addedx/audit/v1/keeper/msg_submit_epoch_report.go— validation + bridge callx/audit/v1/keeper/msg_submit_epoch_report_cascade_bytes_test.go— new (10 invariant tests)x/audit/v1/types/errors.go— new typed errorx/audit/v1/types/audit.pb.go,docs/static/openapi.ymlObservability
SubmitEpochReportalready emits typed events for accepted/rejected reports. New rejection path logs the typed error.Parent PR
Master-branch equivalent: #140