Replace curl with wget for downloading release manifests and
signatures in verify-install.sh. wget handles redirects, retries, and
error reporting more robustly by default, which avoids silent download
failures that caused misleading "Invalid signature!" errors.
Also add error checking to all download calls so failures are reported
immediately with the URL that failed, and log which signature file and
user failed gpg verification.
When gpg --verify fails, include the signature filename, username,
and full GPG output in the error message. Previously only a generic
"Invalid signature!" was printed, making it hard to identify which
signer's signature was invalid.
Add a workflow that triggers when a release is published. It runs
verify-install.sh inside the official Docker image to validate
signatures and binary hashes. If verification fails, the release
is automatically set back to draft.
With Go 1.26 now released, this bumps the minimum required Go version
from 1.24.11 to 1.25.5 across all go.mod files and updates the
installation documentation with the correct download links and SHA256
hashes for Go 1.25.5 binaries.
The build system (Dockerfiles, Makefile, CI) was already using Go 1.25.5,
so this change aligns the go.mod minimum version to match.
In this commit, we add a readme which serves as a general introduction
to the pacakge, and also the motivation of the package. It serves as a
manual for developers that may wish to interact with the package.
In this commit, we add the actor system (along with the receiptionist)
and the router.
An actor can be registered with the system, which allows other callers
to locate it to send message to it via the receptionist. Custom routers
can be created for when there're actors that rely on the same service
key and also req+resp type. This can be used to implement something
similar to a worker pool.
In this commit, we add the actual Actor implementation. We define a
series of types and interfaces, that in concert, describe our actor. An
actor has some ID, a reference (used to send messages to it), and also a
set of defined messages that it'll accept.
An actor can be implemented using a simple function if it's stateless.
Otherwise, a struct can implement the Receive method, and handle its
internal message passing and state that way.
In this commit, we add two new fundamental data structures: Future[T]
and Promise[T].
A future is a response that might be ready at some point in the future.
This is already a common pattern in Go, we just make a type safe wrapper
around the typical operations: block w/ a timeout, add a call back for
execution, pipeline the response to a new future.
A promise is an intent to complete a future. Typically the caller
receives the future, and the callee is able to complete the future using
a promise.
In this commit, we add an integration test that verifies the
wallet_synced field in GetInfoResponse correctly reflects the wallet's
sync state.
The test creates a node, verifies wallet_synced becomes true after
initial sync, then stops the node and mines blocks while it's offline.
After restart, the test polls GetInfo to observe the wallet catching up,
ideally capturing the transition from wallet_synced=false to true.
The test is registered in the "wallet sync" test case group.
In this commit, we extend the chainSyncInfo struct with a new
isWalletSynced field that tracks the wallet's sync state independently
from the composite isSynced field. The GetInfo RPC handler now populates
the WalletSynced response field from this new struct field.
A debug log line is added to GetInfo to help diagnose sync state issues,
showing both the composite sync status and the wallet-specific sync
status.
Currently isWalletSynced mirrors isSynced since both ultimately derive
from the same underlying wallet sync check. This prepares the plumbing
for future differentiation where wallet sync state could be tracked
separately from router and blockbeat dispatcher states.
In this commit, we add a new `wallet_synced` boolean field to the
GetInfoResponse message. This field exposes the wallet's internal sync
state with the backing chain source, providing visibility into whether
the wallet has caught up to the current chain tip.
This is distinct from the existing `synced_to_chain` field, which
represents a composite sync state that also considers the router and
blockbeat dispatcher. The new field allows callers to distinguish
between wallet sync delays and other subsystem sync states.
Use the StateService stream to wait for LOCKED before sending the unlock
request, then wait for UNLOCKED/RPC_ACTIVE before reporting success.
If the state shows the wallet is already unlocked, skip sending the
unlock request and return an error immediately.
This avoids lost unlocks during slow startup.
Fix https://github.com/lightningnetwork/lnd/issues/7749
Guard access to remoteUpdateHorizon to prevent a race when
the gossiper is flushing a pending batch of announcements
while concurrently processing a GossipTimestampRange message
from a peer.
Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
Only post a severity classification comment when the bot hasn't
commented before or when the severity actually changed. Previously
every push (synchronize event) would post a new comment even if the
classification was identical.
The prompt now instructs the classifier to:
- Check for existing bot comments via the pr-severity-bot marker
- Compare the new severity against the existing severity label
- Skip commenting if both match, while still ensuring labels are correct
- Include a severity changed banner when re-commenting due to a change
When running `make lint` in a git worktree, the diff processor fails
with "no version control repository found" because the Docker container
only mounts the worktree directory, not the main git directory that the
worktree's .git file references.
This causes golangci-lint's `new-from-rev` filter to not work, resulting
in all ~32k existing lint issues being reported instead of only newly
introduced ones.
Fix by detecting when we're in a worktree (.git is a file, not a
directory) and mounting the main .git directory into the container so
revgrep can access the git history.
Claude keeps trying to use `gh api` to add severity labels, which gets
denied by the allowed tools restriction. Instead of retrying with the
permitted `gh pr edit --add-label` command, it silently gives up and
only posts the comment. The result is that severity comments appear on
PRs but the actual labels are never applied.
Add an explicit tool constraints section at the top of the prompt so
Claude knows upfront that only `gh pr view`, `gh pr edit`, and
`gh pr comment` are available.
This commit fixes a backwards compatibility issue that prevented nodes
from upgrading from v0.19.x to v0.20.x.
In v0.19.x, channel edge features were serialized as raw feature bytes
without a length prefix. In v0.20.x (commit 2f2845dfc), the serialization
changed to use Features.Encode() which adds a 2-byte big-endian length
prefix before the feature bits. The deserialization code was updated to
use Features.Decode() which expects this length prefix.
When v0.20.x reads a database created by v0.19.x, Decode() tries to read
a length prefix that doesn't exist, causing an EOF error:
unable to decode features: EOF
The fix adds a deserializeChanEdgeFeatures() helper that detects which
format is being read and decodes accordingly:
- New format (v0.20+): First 2 bytes encode the length of the remaining
bytes. Detected when uint16(bytes[0:2]) == len(bytes)-2.
- Legacy format (pre-v0.20): Raw feature bits without length prefix.
Uses DecodeBase256 with the known length.
The format detection is safe because in the legacy format, the first byte
always has at least one bit set (the serialization uses minimum bytes),
so the first two bytes can never encode a value equal to len-2.
Fixes#10528.
When processing a remote network announcement, it is possible for two
error messages to be sent back on the errChan. Since Brontide doesn't
actually read from errChan, and since errChan only buffered one error
message, the sending goroutine would deadlock forever. This would only
become apparent when the gossiper attempted to shut down and got hung
up.
For now, we can fix this simply by buffering up to two error messages on
errChan. There is an existing TODO to restructure this logic entirely
to use the actor model, and we can do a more thorough fix as part of
that work.
This bug was discovered while doing full node fuzz testing and was
triggered by sending a specific channel_announcement message and then
shutting down LND.
The PR severity classifier was failing for external contributors because
the claude-code-action checks that the actor has write permissions. Since
this workflow only reads PR metadata via the API and doesn't execute any
code from the PR (and has restricted tool permissions), it's safe to allow
any user to trigger classification.
When a PR originates from a fork, the PR branch doesn't exist in the
origin remote. This adds a step that uses `gh pr checkout` before
running the Claude action, which properly handles fork PRs by adding
the fork as a remote and fetching the branch from there.