Add an opt-in check that prevents the sum of all account balances from
exceeding the node's available local (outbound) channel balance. When
enabled via the new accounts.check-channel-balance config option, the
service rejects balance allocations that would over-provision the node:
creating an account, an administrative credit, or an administrative
balance increase now fails with ErrBalanceReservationExceeded if it
would push the total allocated balance above the node's local channel
balance.
Note that the total channel balance may still decrease below the already
allocated account balance. This can occur if the node operator decreases
the total channel balance through non-account related activity.
The check is a no-op by default to preserve the historical behaviour
where the operator manages over-provisioning themselves (accounts can
legitimately be created before channels are funded). Invoice-driven
credits are unaffected, as they are backed by real inbound payments.
Add an opt-in cap on the total amount a single account payment may
debit, including routing fees, enforced at the account interceptor for
both SendPaymentV2 and SendToRouteV2. When the new
accounts.max-payment-size-msat config option is set to a non-zero
value, payments whose amount plus fees exceeds it are rejected with
ErrPaymentExceedsMaxSize before the balance check and before any funds
are reserved.
For SendPaymentV2, the configured fee limit is included in the capped
amount. For SendToRouteV2, the route's stated fee is included.
This gives operators a guard rail against a compromised or misbehaving
account macaroon draining its balance in a single large payment. The
cap defaults to 0 (disabled), preserving existing behaviour, and is a
first step towards the finer-grained per-account spending controls
requested in the issue.
Automatically bake a super macaroon on startup if it doesn't already
exist on disk and the `bake-super-macaroon` option is configured.
On startup, the node verifies if the super macaroon file exists. If
it does, it parses the macaroon, extracts and verifies the version and
root key ID, and asserts that the macaroon permissions exactly match
the expected active permissions. If there is a mismatch, the macaroon
is regenerated and overwritten on disk. If the file does not exist, a
new super macaroon is baked and written directly to disk.
Also validate that the `bake-super-macaroon` option is not enabled when
LND is running in stateless initialization mode, failing startup early
if they are used together.
readyChan/unlockChan only guarantee lnd's gRPC listener socket is bound,
not that lnd's RPC interceptor has left WAITING_TO_START. Callers that
poll litd's status (itest's WaitForLNDWalletReady, litcli status, the UI)
could observe "Wallet Ready" and then immediately hit a "waiting to
start, RPC services not available" error, which was the root cause of a
flake in TestLightningTerminal/.../terminal_stateless_init_mode (CI run
29286599979, PR #1322). Poll lnd's StateService, which is exempt from
both the macaroon and RPC-readiness checks, until it reports leaving
WAITING_TO_START before advertising the wallet as ready.
Treat a declined kvdb-to-SQL migration prompt as a startup-abort
condition that shuts litd down fully. This prevents litd from leaving
the status server running after the operator refuses the migration
prompt.
The reason why this is motivated, is that `litd` at this stage of the
startup process will not be ready to handle an `litcli stop` RPC call.
Prompt before automatically migrating legacy kvdb state to SQL when
litd starts with a SQL backend and active bbolt data is still present.
Detect prior migrations by checking for the SQL tombstone marker so
already-migrated stores can start without prompting. Add unit coverage
for the prompt flow and wire stdin through the itest harness so the
migration restart path can acknowledge the prompt automatically.
Make the `NewStores` function into a struct member of the `Config`
struct, as the choice of database backend is now part of the production
configuration.
This introduces a new firewall.request-logger.disable config option to
completely disable request logging. When disabled, the request logger
interceptor is not instantiated, avoiding all logging overhead including
database writes and request processing.
This is implemented as a separate disable flag rather than adding a new
log level because the goal is to bypass the logging system entirely for
performance reasons, not just filter events. A log level would still
process and filter each request through the interceptor.
The change also adds validation to ensure autopilot remains enabled only
when request logging is active, since autopilot relies on action logs
for rule enforcement and auditing.
- Replace occurrences of `// nolint:lll` with `// nolint:ll` across
files for consistency.
- Reformat multiline strings, comments, and function parameters to
improve clarity and adhere to style guidelines.
- Add `// nolint:ll` comments where necessary to prevent linter
warnings.
In preparation for the next commit which bumps golang to a newer
version, we want to make some code changes that would otherwise render
some log-related calls problematic. With go1.24 a new govet rule was
added that disallows non-constant strings (i.e including a tag like
"%s") in calls to printf. See more in the related issue
https://github.com/golang/go/issues/60529.
In the upcoming actions migration, we will need to fetch LND's macaroons
prior creating litd's stores, and therefore we need to connect to LND
prior to creating the stores.
To avoid having to wait for LND to fully sync before creating the stores
(and, by extension, Litd's RPC servers), we separate the basic LND
client setup from the full LND client setup. Only the full setup
requires a fully synced LND.
In the upcoming actions migration, we need fetch LNDs macaroons prior to
initializing the stores, as the macaroons will be required during the
migration.
This requires that we setup the connection to LND before we initialize
the stores, as we can only fetch the macaroons after the LND connection
is established.
This commit refactors the litd startup process, so that the stores are
initialized after the LND connection is established.
Similar to how the previous commit separated the initialization and
starting of the account RPC server, this commit separates the
initialization and starting of the sessions RPC server.
In the upcoming actions migration, we need fetch LNDs macaroons prior to
initializing the stores, as the macaroons will be required during the
migration.
This requires that we setup the connection to LND before we initialize
the stores, as we can only fetch the macaroons after the LND connection
is established.
In preparation of doing so, we cannot reference the stores when
initializing/creating the accounts RPC server object, as we do so prior
to setting up the LND connection.
This commit therefore refactors the accounts RPC server so that we
separate the initializing from the starting of the RPC server, and only
require the store reference during the actual startup of the RPC server.
Note that we still keep the init of the accounts RPC server reference
prior to setting up the LND connection, as not doing so would require
that we'd refactor the registering of `GrpcSubserver`s in a more complex
and in a less elegant way.
As it's quite confusing by just looking at `litd` codebase that LND will
execute `litd`'s `RegisterGrpcSubserver` function during the setup of
the LND connection, we add a comment to clarify this.
Add the `commit_hash` field to the GetInfoResponse. The `commit_hash`
field will contain the most recent commit_hash that the build was based
on. If the build had uncommitted changes, this field will contain the
most recent commit hash, suffixed by "-dirty".
The semantics of the `version` field is also updated to always contain
the most recent semantic version of the litd node, following the
semantic versioning 2.0.0 spec (http://semver.org/).
Previously, the `Proxy` service was not accessible over LNC, as we did
not want to expose the `stop` and `bakesupermacaroon` endpoints over
LNC. This also meant that the `getinfo` endpoint was not accessible over
LNC. As we now have demand to expose the `getinfo` endpoint over LNC, we
have decided to expose the `Proxy` service over LNC, and let the user
fine-tune the access to the `stop` and `bakesupermacaroon` endpoints
via the macaroon for the LNC session instead.
In this commit, we add a `DB` struct in the `firewalldb` package. This
struct will be responsible for housing abstract implementations of the
various stores in the `firewalldb`. For now, we start with just the
RulesDB. We also add Start&Stop methods for the struct in preparation
for future additions here - for now, these do nothing.
In the main LiT setup, we move the firewall.BoltDB and the new
firewalldb.DB to the `stores` struct and implement them in the two
`config_` files. For now, both varients create the Bbolt version of the
firewallDB and this is used to init the `firewalldb.DB` struct. This
will be changed in future commits where we will add a sql
implementation.
In preparation for a db-backend agnostic DB struct along with a SQL
implementation of the various stores in the package which will be housed
under a struct named `SQLDB`.
This commit updates:
- LND
- pool
- loop
- taproot-assets
- faraday
- lighting-node-connect
- aperture
- lndclient
- btclog
We start using the new btclog v2 library and the associated breaking
changes in the lnd/build package.
With this commit, we deprecate the `--remote.lit-maxlogfiles` and
`--remote.lit-maxlogfilesize` options and introduce new logging options
under the `--remote.lit-logging` namespace.
Finally, the LND update introduced a new `MaxBlocksMinedPerTest`
variable in the `lntest` package that we now need to override in order
for our itests to pass.
When we link a session to an account, we want to be able to validate
that the account actually does exist. So in preparation for that, we
first give the session store access to the accounts store.
Add the ability to specify the db backend to run use for accounts when
running itests.
With this commit, you can run something like: `make itest
dbbackend=sqlite`.
Give the sessionRpcServer access to the session store via the
session.Store interface instead of the raw DB pointer. This will make it
possible to swop out the implementation (which is currently bbolt) with
something else such as a SQL implementation. We move the responsibility
of closing the DB to the main LiT server.
In this commit, we refactor various uses of the session.MacaroonRecipe
type outside of the session package. This is to decouple the baking of a
super macaroon from the sessions package and will help avoid import
cycles in future.
We want to be able to pass different DB implementations to NewService.
In preparation for this, we make it implementation agnostic by letting
it take a `Store` instead of constructing one itself.
This this change, we also let LiT handle the closing of the accounts
Store instead of the accounts service