Repository navigation
Conversation
lightningd polls bitcoind every 30 seconds by default, so after the tests mine the blocks a channel needs it can take CLN half a minute to notice them, plus the time to walk them, before it sends `channel_ready`. The tests wait 60 seconds for the resulting `ChannelReady` event, which left a few seconds of margin on a busy CI runner and timed out in `test_basic_channel_cycle`. The same scenario takes 8 seconds against LND and 12 against Eclair, which get notified of blocks over ZMQ. The poll interval is a developer option, and developer mode turns deprecated APIs off, which drops the `bech32` address from `newaddr` and the `tx`/`txid` fields from `close` that the tests read, so deprecated APIs are explicitly allowed again. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`channel_ready` only arrives once the external node has seen the blocks the test mined, but the scenarios started the 60-second event wait right after mining, so an external node that lags its chain backend ate into that budget and a timeout there read as a channel problem. The setup already waits for the peer to reach Bitcoin Core's height before funding; do the same after mining the blocks a channel open or a splice lock needs, so the event wait measures the channel exchange alone and a lagging peer fails with a message that says so. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`exponential_backoff_poll` gave up after 20 tries, about nine seconds in all once the backoff had reached its cap. That is not enough for electrs to index a hundred freshly generated blocks on a busy CI runner: `postgres_node_restart` died in the premine wait and `reorg_test` after generating 139 blocks, both with "Reached max tries". Poll for up to 60 seconds instead; a condition that already holds still returns at once, so passing runs are unaffected. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
I've assigned @tnull as a reviewer! |
a_close_is_classified_for_a_channel_whose_facts_were_never_recorded reconnects a restarted node to its peer and immediately asks for a cooperative close. Connecting returns once the peer handshake is done, but the close is refused until channel_reestablish has been exchanged over the new connection, which takes another message round trip. On a slow runner the close came first and the test failed with ChannelClosingFailed. Poll the channel until it reports usable, which includes having been reestablished, before closing it. Another test already does this after a reconnect. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
TestSyncStore mirrors each write and remove to a filesystem store, a SQLite store and an in-memory store, and asserts on every access that they agree. The mirrors were applied one after another with awaits in between, so a caller that dropped the future partway left the stores disagreeing: the filesystem and SQLite writes had already been handed to blocking threads and landed, while the in-memory one never ran. The node does exactly that when it stops: its cancellable background tasks, several of which persist the node metrics, are dropped wherever they are suspended. The next node built on the same store then failed its first read with a consistency assertion in read_node_metrics, which is how a_sweep_confirmed_while_down_is_classified_for_a_channel_whose_facts_were_never_recorded failed in about one run out of six locally. Run each operation on a runtime the store owns and only await its completion from the caller, so dropping the caller's future no longer interrupts it. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`Node::sync_wallets` returned as soon as a sync that was already in progress finished, taking that sync's result as its own. That sync took its view of the chain when it started, so the caller could get back a node that was still behind the tip. With a Bitcoin Core chain source this is easy to hit: blocks are processed one at a time, with the channel monitors, the sweeper and the on-chain wallet persisted for each, so a background poll that started while a batch of blocks was being mined keeps running long after mining is done. A manual sync arriving in the meantime piggybacked on it and returned with the rest of the batch still unprocessed. The reorg test then timed out on CI: the sweep it waited for could only be broadcast once the remaining blocks had been processed, which now happened inside the wait's time budget rather than in the sync call before it. A sync now waits for the one in progress and then runs its own, so it reflects the tip as of when it was called. A failed or cancelled sync in progress still fails the waiting caller as before. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Since a caller runs its own sync after waiting for the one in progress, that sync's result no longer stands in for the caller's. Returning its error still failed the caller without it having synced at all. With background syncing on, a manual `sync_wallets` call that arrived while a background sync was failing returned that failure as its own. The caller now logs the failure and syncs anyway, so what it returns is the result of its own sync. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The eclair job failed with `sync_wallets failed: WalletOperationFailed` on three unrelated branches on the same day. The node logs which part of the sync failed, but only to its log file under a random directory in the runner's temp dir, which the job discards. So each occurrence leaves nothing to tell a transient electrs error from a failed background sync the manual call piggybacked on. Point the harness's temp dir at a directory under the runner's temp and upload it as an artifact when the tests fail, together with the electrs and external node container logs for the same window. The same for the CLN and LND jobs, which run on the same harness. Written with the help of an AI tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Several recent CI failures on #1079 and #1080 came from the test harness's own waits and sync handling rather than from the code under test; the same commits passed on re-run. CLN polls bitcoind every 30 seconds by default, the harness gave up polling for a block after a fixed number of tries, a cooperative close was attempted before the channel was reestablished, and a manual
sync_walletscould return while the node was still behind the tip, or return a background sync's error without having synced itself.This PR makes those waits budgeted by time rather than by try count, waits for the external node and for the channel state the next step actually needs, and makes
sync_walletsalways run its own sync to the current tip. For the one failure whose cause is still unknown, the eclair job'sWalletOperationFailedpanic, the interop jobs now upload the node's storage directory and the electrs and external node logs when they fail.Measured locally against the CLN v25.12.1 image: the CLN suite takes 70 seconds with the 1 second poll versus 309 seconds with the default.
reorg_testandchannel_full_cyclepass with the new poll budget.🤖 Generated with Claude Code