You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(audit): keep disk pressure out of postponed state (#146)
* fix(audit): keep disk pressure out of postponed state
* test(systemtests): align bootstrap-recovery test with LEP-6 §17 disk-pressure invariant
The PR removes disk from selfHostViolatesMinimums / selfHostCompliant so
disk pressure is owned exclusively by the STORAGE_FULL transition path.
TestAuditEmptyActiveSetBootstrap_NonCompliantHostStaysPostponed was
written under the old invariant (disk-non-compliance → stays POSTPONED)
and started observing POSTPONED → STORAGE_FULL after this PR landed in CI.
Mirrors the unit-level refactor of TestEnforceEpochEnd_EmptyActiveSet_NonCompliantSelf_NoRecover
already in this PR (disk → cpu swap).
Changes:
- Swap the violating metric in
TestAuditEmptyActiveSetBootstrap_NonCompliantHostStaysPostponed from
disk_usage_percent=95 / MinDiskFreePercent=20 to
cpu_usage_percent=95 / MinCpuFreePercent=20. The intent of the test
(self-compliance still gates the bootstrap exception) is preserved on
a metric that still postpones.
- Add TestAuditEmptyActiveSetBootstrap_DiskPressureGoesToStorageFull,
the end-to-end mirror of unit-level
TestEnforceEpochEnd_RecoversPostponedToStorageFullWhenDiskStillHigh:
empty active set + POSTPONED self + disk > MaxStorageUsagePercent →
recovers to STORAGE_FULL (not ACTIVE, not stuck POSTPONED).
- Replace helper setAuditParamsForFastEpochsWithMinDiskFree with
setAuditParamsForFastEpochsWithMinCpuFree (the old helper had a single
caller and contradicted the new invariant).
- Add auditHostReportWithCpuUsageJSON; keep auditHostReportWithDiskUsageJSON
for the new STORAGE_FULL test.
* fix(audit): align storage-full contract surfaces
* fix(audit): address storage-full review comments
* fix(supernode): remove stale storage-full nolint
* fix(audit): preserve released v1.11.1 handler
Copy file name to clipboardExpand all lines: x/audit/v1/POSTPONEMENT_RULES.md
+10-5Lines changed: 10 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Postponement and Recovery Rules (audit/v1)
2
2
3
-
This document describes the on-chain rules implemented by the audit module (v1) for switching a supernode between `ACTIVE` and `POSTPONED`, and for recovering back to `ACTIVE`.
3
+
This document describes the on-chain rules implemented by the audit module (v1) for switching a supernode between `ACTIVE` and `POSTPONED`, and for recovering out of `POSTPONED`.
4
4
5
5
## Definitions
6
6
@@ -33,10 +33,11 @@ This is evaluated by checking for a stored report in each of the last `N` epochs
33
33
34
34
### 2) Host Report requirements
35
35
36
-
If a submitted host report violates any enabled minimum free% threshold, the supernode is set to `POSTPONED`.
36
+
If a submitted host report violates any enabled CPU or memory minimum free% threshold, the supernode is set to `POSTPONED`.
- Special case: if `*_usage_percent == 0`, that metric is treated as **unknown** and does not trigger postponement.
40
+
- Disk pressure is not a postponement criterion; it is handled by the `STORAGE_FULL` state path.
40
41
41
42
The following host-report fields are currently ignored by postponement logic:
42
43
-`failed_actions_count`
@@ -50,8 +51,12 @@ An epoch counts toward the consecutive requirement only if:
50
51
- there is at least **1** peer reporter about the target in that epoch, and
51
52
- the share of peer reporters about the target in that epoch that report `PORT_STATE_CLOSED` for port index `i` meets or exceeds `peer_port_postpone_threshold_percent`.
52
53
53
-
## Recovery rule (POSTPONED → ACTIVE)
54
+
## Recovery rule (POSTPONED → ACTIVE or STORAGE_FULL)
54
55
55
-
In a single epoch, a `POSTPONED` supernode becomes `ACTIVE` if:
56
+
In a single epoch, a `POSTPONED` supernode recovers if:
56
57
- it submits one compliant host report (Host Report requirements), and
57
58
- there exists at least **1** peer report about that supernode in the same epoch where **all** required ports are `PORT_STATE_OPEN`.
59
+
60
+
The recovery target is determined from the same-epoch self HostReport:
61
+
- if `disk_usage_percent` is omitted/zero or is at or below `supernode.max_storage_usage_percent`, the supernode becomes `ACTIVE`;
62
+
- if `disk_usage_percent` is above `supernode.max_storage_usage_percent`, the supernode becomes `STORAGE_FULL`.
-**Peer port thresholds**: a required port is treated as CLOSED if peer observations meet `peer_port_postpone_threshold_percent`, and this happens for `consecutive_epochs_to_postpone` consecutive epochs.
92
92
93
-
### Recovery (`POSTPONED -> ACTIVE`)
93
+
### Recovery (`POSTPONED -> ACTIVE` or `STORAGE_FULL`)
94
94
95
95
At epoch end, a supernode can recover:
96
96
97
97
- If postponed due to action-finalization evidence: by the action-finalization recovery window and total-bad-evidence constraint.
98
98
- Otherwise: if it has a compliant self report and at least one peer observation in the epoch where all required ports are `OPEN`.
99
99
100
+
If the same-epoch self HostReport still has `disk_usage_percent` above `supernode.max_storage_usage_percent`, recovery routes to `STORAGE_FULL` instead of `ACTIVE`.
101
+
100
102
Detailed behavior is implemented in the module's epoch-end enforcement logic.
101
103
102
104
## Evidence
@@ -192,7 +194,7 @@ Params are initialized from genesis and may later be updated by governance via `
192
194
- Enforcement:
193
195
-`min_cpu_free_percent`: `0` (disabled)
194
196
-`min_mem_free_percent`: `0` (disabled)
195
-
-`min_disk_free_percent`: `0` (disabled)
197
+
-`min_disk_free_percent`: `0` (legacy/no-op for epoch-end postponement; disk pressure is handled as `STORAGE_FULL`)
0 commit comments