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.
Implement the AccountPayments handler on the Accounts RPC server.
The handler resolves accounts by ID or label, loads its payment hashes,
applies pagination constraints, and fetches complete payment details
concurrently from LND's TrackPaymentV2. It also returns pagination
metadata including the total count of payments.
Introduce the ListAccountPayments and CountAccountPayments methods to
the accounts Store interface.
ListAccountPayments enables retrieval of a paginated list of payment
entries associated with a given account ID, supporting offset and
limit. CountAccountPayments returns the total number of payments
associated with the account.
Implement ListAccountPayments in the Bolt-based kvdb account store.
The retrieved account payments are sorted in ascending lexicographical
order of their payment hash.
Add sqlc queries to select account payment hashes from the database.
Implement the ListAccountPayments method in the SQLStore, allowing
retrieval of stored payment hashes for SQLite and Postgres backends.
Also define the AccountPaymentEntry helper struct in
accounts/interface.go to wrap payment hashes and details.
checkLabel rejects labels that could be mistaken for a hex-encoded
account ID. Add a table-driven test covering the accepted cases (empty,
plain text, short hex, and non-hex strings of account-ID length) as well
as the rejected cases (lower- and upper-case hex strings of account-ID
length).
Signed-off-by: 0xfandom <kashyapshivank01@gmail.com>
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.
Bumps lnd to v0.21.0-beta, lndclient to v0.21.0-1, and
taproot-assets to v0.8.0 across the root, litrpc, and perms
modules. taprpc uses the proper v1.1.0 tag.
lnd removed the deprecated SendPaymentSync, SendToRouteSync,
SendPayment (streaming), and SendToRoute (streaming) RPCs. The
account interceptor checkers and their tests for these RPCs are
removed since no client can call them anymore. The V2 checkers
already handle account tracking for payments.
The itest harness is updated for lnd v0.21's miner API changes
(SendOutputs -> SendOutput, Miner.Client.Generate -> GenerateBlocks,
waitForNTxsInMempool replaced by Miner.AssertNumTxsInMempool) and
TimeLockDelta bumped from 20 to 40 since lnd v0.21 raised
MinCLTVDelta from 18 to 24.
Add clearer progress logging across the KVDB to SQL migration paths
for accounts, sessions, and firewalldb.
Log the total number of items to migrate where it is cheap to
determine up front, and emit progress updates every 100 migrated
items.
commit 21933e8 in PR 1281 in master resolved the following issue:
"Get returns a byte slice that points directly into bbolt's
mmap'd file. This slice is only valid for the lifetime of the
transaction. In Account() and LastIndexes(), the slices were escaping
the View callback and being read after the transaction closed. Under
concurrent write transactions the file gets remapped, invalidating
the pointer and causing a segmentation fault.
Copy the byte slices inside the transaction so deserialization
operates on stable, heap-allocated memory."
This commit also updates the SQL migration to apply the same fix when
reading the Last Indexes.
Mark the legacy kvdb stores as deprecated once the kvdb -> SQL
migration commits successfully. This prevents normal bbolt startup
from reopening accounts.db, session.db, or rules.db after their data
has already been migrated.
Add explicit deprecation checks to the three kvdb store open paths and
provide migration-only constructors that can still reopen deprecated
files when the SQL database is deleted or downgraded and the migration
must be rerun.
Use store-specific tombstones for the deprecation markers and add
tests that verify deprecated stores are rejected while migration
reruns continue to work.
Add a store test that verifies that Accounts groups invoices and
payments by account ID and does not leak linked data across accounts
when using the store.Accounts function.
Optimize SQL account listing by preloading linked invoices and payments
for all accounts in bulk.
Before this change, Accounts() queried ListAllAccounts and then did two
extra queries per account (ListAccountInvoices/ListAccountPayments),
which scales poorly as account count grows.
Add ListAllAccountInvoices and ListAllAccountPayments queries, group
their rows by account_id in memory, and marshal each account from the
preloaded data. Keep conversion logic shared through
marshalDBAccountWithLinkedData to preserve behavior between
single-account and list-account paths.
This reduces query count from 1 + 2N to 3 and improves list-path
performance without changing external semantics.
The next commit that adds the kvdb to sql code migration will need to
initialize the accounts kvdb DB.
This commit exports that struct so that it can be referenced outside of
the accounts package.
In upcoming commits, we will introduce a new migration stream package
that will need to reference the db package, as well as the accounts,
session and firewalldb package in future commits. To avoid circular
dependencies, we therefore introduce a new migration stream that unit
tests can use, in order to avoid having to import the new migration
stream package.
As no code path uses the sqlc.UpdateAccountAliasForTests query, now that
migrations tests have been updated to use the sqlcmig6 version, we can
remove the query from the sqlc package. As this query is only intended
to be used for testing, it is beneficial to not expose it to the rest of
the codebase to avoid accidental usage in the future.
As the legacy `NewTestPostgresDB` function is no longer used and has
been removed, it no longer makes sense to have a `V2` suffix on the
`NewTestPostgresV2DB` function. This commit renames it to
`NewTestPostgresDB`, to indicate that this function now replaces the
legacy function.
This commit updates the account update command description and ArgsUsage
for better clarity.
Additionally, a formatting nit is fixed in the checkLabel error message
to ensure no line starts with a space character.
bucket.Get returns a byte slice that points directly into bbolt's
mmap'd file. This slice is only valid for the lifetime of the
transaction. In Account() and LastIndexes(), the slices were escaping
the View callback and being read after the transaction closed. Under
concurrent write transactions the file gets remapped, invalidating
the pointer and causing a segmentation fault.
Copy the byte slices inside the transaction so deserialization
operates on stable, heap-allocated memory.
Exercises the Account() and LastIndexes() code paths under concurrent
write pressure. Writers create accounts in a tight loop, growing the
database and forcing bbolt to remap the underlying file. Readers
simultaneously fetch a known account and verify its fields are not
corrupted.
Without the copy fix in the previous commit, this test triggers a
segfault or data corruption because the mmap'd memory backing the
byte slices returned by bucket.Get is invalidated by the remap.
Run with
go test ./accounts/ -run TestAccountReadConcurrentWrite -v -count=1 -race
- 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 the upcoming kvdb to SQL migration of the actions store, we need to
simulate in tests that two or more accounts have colliding account
aliases for the first 4 bytes of the alias. In order to allow creation
of such accounts, we need to be able to update the alias of an account
in tests, and this commit adds the a SQL query enabling this
functionality.
Note that the `UpdateAccountAliasForTests` query is only intended for
use in tests and should not be used in production code.
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.
We add a helper function to the functions that creates the test SQL
stores, in order to ensure that the store is properly closed when the
test is cleaned up.
Update the SQL migration to instead of using the public functions of the
BoltStore struct, we instead iterate over the buckets directly. This
ensures that the BoltStore struct Acccounts & LastIndexes functions of
the BoltStore implementation can be changed, without effecting the
SQL migration.
This commit introduces the migration logic for transitioning the
accounts store from kvdb to SQL.
Note that as of this commit, the migration is not yet triggered by any
production code, i.e. only tests execute the migration logic.
In preparation for upcoming migration tests from a kvdb to an SQL store,
this commit updates the NewTestDB function to return the Store interface
rather than a concrete store implementation.
This change ensures that migration tests can call NewTestDB under any
build tag while receiving a consistent return type.
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.
And use that from the existing accountFromMacaroon helper (which will
then test the new helper by proxy).
We add this helper so that we can use it later on from the sessions
package where we want to extract an account ID from a caveat (we wont
have a full macaroon available).
In this commit, we add the SQLStore type which implements the
accounts.Store interface. To demonstrate that it works as expected, we
also plug this implementation into all the account unit tests to show
that they pass against the sqlite and postgres backends.
One can use `make unit pkg=accounts tags=test_db_postgres` or
`make unit pkg=accounts tags=test_db_sqlite` to test locally.
Note that 2 small timestamp related changes are made to the unit tests.
This is to compensate for timestamp precision in postgres.
This commit introduces the `DebitAccount` function in the kvdb store,
to support decreasing an existing off-chain account’s balance by a
specified amount in the database.
In preparation for the upcoming credit/debit accounts feature, rename
the store `IncreaseAccountBalance` method to `CreditAccount` to better
reflect its purpose.