Build with --configure --enable-debugbuild and uv run make. Much faster with uv run make RUST=0.
Env vars for tests: RUST=0 (if RUST plugins were not built), VALGRIND=0 (much faster), TIMEOUT=10 to speed failures (or 100 if VALGRIND=1).
*gen.[ch] files are generated by the Makefile.
ccan/ is imported from ccan repo: PRs should go there, then make update-ccan.
Insert BOLT quotes (current version is checked out in .tmp.lightningrfc/) in source when dealing with protocol work, for make check-source-bolt. This ensures we keep up with spec changes. ... means skip some, but not over a section boundary. ... at the start means "continues directly from previous quote".
make check-source does formatting checks.
assert-based unit tests can "#include ../file.c", OR add objects to Makefile targets: make update-mocks will regenerate mocks for functions from link errors.
Commits should be reviewable, bisectable, and include tests. Pattern: one commit adds a python test with @pytest.mark.xfail(strict=True), next commit fixes the problem and removes that line.
Commits which fix crashes or bug MUST quote the bug for later searches: do not rely on being able to find the bug report in future!
Commits which create signficant user (not developer!) visible changes should have Changelog-(Added|Deprecated|Changed|Fixed|EXPERIMENTAL) for assembling CHANGELOG.md at release time.
Deprecations must use the deprecation infrastructure, and append to the table in doc/developers-guide/deprecated-features.md
Adding a new JSON-RPC command requires the most careful design: start with doc/schemas/NAME.json and add doc/NAME.json to MARKDOWNPAGES in doc/Makefile. make doc-all will regen the rest.
In pytest integration tests, name nodes l1, l2, etc in creation order. This matches the log prefixes they use (lightningd-1 etc) and on test failure the logs and other ephemera will in /tmp/ltests-/TESTNAME/lightning-1/.
In pytest, never assert that a command raises an exception without specifying exactly what it raises! Use with pytest.raises(RpcError, match='xxx'):
tal_bytelen / tal_count of NULL are defined to be zero, and you may assume this.