channel: Add test for channel state max
What changed, and why it matters
This commit adds a new automated test to the Core Lightning project. The test checks that a project-wide constant called CHANNEL_STATE_MAX correctly reflects the highest numbered channel state. If a developer adds a new channel state but forgets to update the constant, the test will fail in continuous integration. It is a defensive code-quality change, not a fix for an active security issue.
No security action required. Treat as normal test-coverage improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change is confined to common/test/run-channel_type.c. It introduces calc_channel_state_max(), which iterates enum channel_state values starting at 1 and stops when it reaches an unlisted state. It then asserts that this discovered maximum equals CHANNEL_STATE_MAX. This is purely a regression guard against enum/constant drift; no functional channel logic is modified.
Changed components
common/test/run-channel_type.cInspect captured patch +36 / −0
diff --git a/common/test/run-channel_type.c b/common/test/run-channel_type.c
index 9e2bea28..46edef12 100644
--- a/common/test/run-channel_type.c
+++ b/common/test/run-channel_type.c
@@ -4,6 +4,7 @@
#include <ccan/tal/str/str.h>
#include <common/setup.h>
#include <stdio.h>
+#include <lightningd/channel_state.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_asset_is_main */
@@ -114,6 +115,39 @@ static void assert_names_eq(const char **names, const char *expected)
assert(streq(expected_names[i], names[i]));
}
+static enum channel_state calc_channel_state_max(void)
+{
+ enum channel_state largest_state = 0;
+
+ assert(DUALOPEND_OPEN_INIT == 1);
+ for (enum channel_state state = 1;; state++) {
+ bool known_state = false;
+ switch(state) {
+ case DUALOPEND_OPEN_INIT:
+ case CHANNELD_AWAITING_LOCKIN:
+ case CHANNELD_NORMAL:
+ case CHANNELD_SHUTTING_DOWN:
+ case CLOSINGD_SIGEXCHANGE:
+ case CLOSINGD_COMPLETE:
+ case AWAITING_UNILATERAL:
+ case FUNDING_SPEND_SEEN:
+ case ONCHAIN:
+ case CLOSED:
+ case DUALOPEND_OPEN_COMMITTED:
+ case DUALOPEND_AWAITING_LOCKIN:
+ case CHANNELD_AWAITING_SPLICE:
+ case DUALOPEND_OPEN_COMMIT_READY:
+ largest_state = state;
+ known_state = true;
+ break;
+ }
+ if (!known_state)
+ break;
+ }
+
+ return largest_state;
+}
+
int main(int argc, char *argv[])
{
struct channel_type t;
@@ -125,6 +159,8 @@ int main(int argc, char *argv[])
assert_names_eq(channel_type_name(tmpctx, channel_type_anchors_zero_fee_htlc(tmpctx)),
"static_remotekey/even anchors/even");
+ assert(calc_channel_state_max() == CHANNEL_STATE_MAX);
+
t.features = tal_arr(tmpctx, u8, 0);
set_feature_bit(&t.features, 1000);
assert_names_eq(channel_type_name(tmpctx, &t), "unknown_1000/even");
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.