Migrate all btcd dependencies to the new per-package v2 modules (wire/v2,
txscript/v2, chaincfg/v2, chainhash/v2, btcutil/v2, psbt/v2, btcec/v2)
introduced by btcd v0.26.0, and pin the tagged ecosystem versions:
btcwallet v0.17.0, neutrino v0.18.0 and lightning-onion v1.4.0.
The bulk of the import rewrite was produced by the scripted diff from
https://github.com/btcsuite/btcd/pull/2547 (followed by 'make rpc'). The
address symbols that moved out of btcutil into the new address package
are imported as btcaddr where a local "address" variable would otherwise
shadow them. The go.mod/go.sum updates and the remaining manual
compilation fixes are folded into this single commit so it builds on its
own (the migration was previously split into a reproducible scripted-diff
plus follow-ups, intended to be squashed on merge).
In this commit, we extend TestAwaitFuture to cover the case where the
future is completed with an fn.Err result. The existing test only
exercised the fn.Ok (success) and context cancellation paths.
The new case calls promise.Complete(fn.Err[string](sentinel)) directly
and verifies that AwaitFuture surfaces the error as the second return
value while returning the zero string value in the first, which is the
documented contract for Result[T].Unpack().
In this commit, we add test coverage for the new helper functions
introduced as part of the chan error -> Future[error] migration.
discovery/gossip_result_test.go covers AwaitGossipResult (success,
error propagation, and context cancellation) and the idempotency of
completeGossipResult (a second call must never block or overwrite the
first result).
lnutils/context_test.go covers ContextFromQuit, verifying that closing
the quit channel cancels the derived context and that calling cancel()
allows the internal goroutine to exit cleanly without leaking.
actor/future_test.go removes a stale doc comment that was left over
from a prior edit pass.
In this commit, we add two package-level generic helpers to the actor
module as part of the broader chan error -> Future[error] migration in
the discovery package.
CompleteWith[T](p Promise[T], val T) is a one-liner convenience wrapper
over p.Complete(fn.Ok(val)). It lets callers complete a promise with a
plain value without constructing an fn.Result inline, which cuts noise
at every completion site.
AwaitFuture[T](ctx, f Future[T]) (T, error) provides the symmetric
receive side: it blocks until the future resolves or the context is
cancelled and returns the value and any context error unpacked from
the fn.Result, matching the (val, err) convention callers expect.
Both functions are deliberately thin (no policy, no timeout, no new
state) so they compose freely with higher-level helpers built on top,
e.g. discovery.AwaitGossipResult.
go.mod is updated to pin the actor module via a local replace directive
so the rest of the lnd module picks up these additions without waiting
for a tagged release.
Add BackpressureMailbox, a Mailbox implementation backed by
queue.BackpressureQueue that consults a queue.DropCheckFunc on every
Send/TrySend to enable RED-style load shedding before the mailbox is
full.
Add MailboxFactory type and ActorOption functional options
(WithMailboxFactory, WithMailboxSize) so callers can inject custom
mailbox implementations when spawning actors via RegisterWithSystem
or ServiceKey.Spawn.
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.
This commit refactors the Actor implementation to use the new Mailbox
interface instead of directly managing a channel. This change
significantly simplifies the actor's message processing loop and
improves separation of concerns.
The main changes include replacing the direct channel field with a
Mailbox interface, updating NewActor to create a ChannelMailbox
instance, and refactoring the process method to use the iterator
pattern provided by mailbox.Receive. The new implementation uses a
clean for-range loop over the mailbox's message iterator, eliminating
the complex select statement that previously handled both message
reception and context cancellation.
The Tell and Ask methods in actorRefImpl have been simplified to use
the mailbox's Send method, which internally handles both the caller's
context and the actor's context. This eliminates the need for complex
select statements in these methods and ensures consistent context
handling throughout the actor system.
Message draining during shutdown is now handled through the mailbox's
Drain method, providing a cleaner separation between normal message
processing and cleanup operations. The actor still properly sends
unprocessed messages to the Dead Letter Office and completes pending
promises with appropriate errors during shutdown.
This commit adds thorough test coverage for the new Mailbox interface
and ChannelMailbox implementation. The tests verify correct behavior
across various scenarios including successful sends, context
cancellation, mailbox closure, and concurrent operations.
The test suite specifically validates that the mailbox respects both
the caller's context and the actor's context during send and receive
operations. This ensures that actors properly shut down when their
context is cancelled, and that callers can cancel operations without
affecting the actor's lifecycle.
Additional tests cover edge cases such as zero-capacity mailboxes
(which default to a capacity of 1), draining messages after closure,
and concurrent sends from multiple goroutines. The concurrent test
uses 10 senders each sending 100 messages to verify thread-safety
and proper message ordering.
All tests pass with the race detector enabled, confirming the
implementation is free from data races.
This commit introduces a new Mailbox interface that abstracts the
message queue implementation for actors. Previously, actors used a
direct channel for their mailbox, which limited flexibility and made
it difficult to implement alternative mailbox strategies.
The new Mailbox interface provides methods for sending, receiving, and
draining messages, with full context support for cancellation. The
Receive method leverages Go 1.23's iter.Seq pattern, providing a clean
iterator-based API that allows natural for-range loops over messages.
The ChannelMailbox implementation maintains the existing channel-based
behavior while conforming to the new interface. It stores the actor's
context internally, ensuring both caller and actor contexts are
properly respected during send and receive operations. This simplifies
context handling compared to complex context merging approaches.
This abstraction enables future implementations such as priority
mailboxes, persistent mailboxes, or bounded mailboxes with overflow
strategies, without requiring changes to the actor implementation.
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.