bookkeeper: fix reloading of rebalances.
What changed, and why it matters
This commit fixes a simple off-by-one bug in the bookkeeper plugin. When restarting, the plugin reloads saved 'rebalance' records from its database. The code was reading the wrong part of the database key, so it could not split the two stored numbers apart and would log a 'weird' error and skip the record. The fix changes one number so it reads the correct key segment. A previously-failing test is now enabled. There is no direct security exploit here; the main risk is that accounting records could be missing or inconsistent after a restart.
No immediate security action required. This is a correctness fix for internal accounting. Operators relying on bookkeeper rebalance records should ensure they upgrade so restart reloads rebalances correctly. Reviewers may want to confirm no other key offsets in the same file use the same off-by-one pattern.
Security signals we found
Off-by-one parsing error in database key deserialization
Potential accounting/reconciliation inconsistency on node restart
Test previously marked as expected failure now enabled
Evidence from the diff
In plugins/bkpr/rebalances.c, init_rebalances() parses a database key structured as [“bookkeeper”, “rebalances”, “
Changed components
plugins/bkpr/rebalances.cbookkeeper plugin rebalance reload logictests/test_bookkeeper.py::test_rebalance_trackingInspect captured patch +1 / −2
diff --git a/plugins/bkpr/rebalances.c b/plugins/bkpr/rebalances.c
index d61c330b..38bbdcd8 100644
--- a/plugins/bkpr/rebalances.c
+++ b/plugins/bkpr/rebalances.c
@@ -135,7 +135,7 @@ struct rebalances *init_rebalances(const tal_t *ctx,
goto weird;
/* key = ["bookkeeper", "rebalances", "<lesser>-<greater>"] */
- if (!split_tok(buf, keytok + 2, '-', &lessertok, &greatertok))
+ if (!split_tok(buf, keytok + 3, '-', &lessertok, &greatertok))
goto weird;
if (!json_to_u64(buf, &lessertok, &lesser)
diff --git a/tests/test_bookkeeper.py b/tests/test_bookkeeper.py
index 2ac03467..c7ba58b2 100644
--- a/tests/test_bookkeeper.py
+++ b/tests/test_bookkeeper.py
@@ -760,7 +760,6 @@ def test_empty_node(node_factory, bitcoind):
l1.rpc.bkpr_inspect('wallet')
-@pytest.mark.xfail(strict=True)
def test_rebalance_tracking(node_factory, bitcoind):
"""
We identify rebalances (invoices paid and received by our node),
Why this scored 21/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.