-
Notifications
You must be signed in to change notification settings - Fork 103
accounts: add functionality to update balance by given amount #962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
accounts: add functionality to update balance by given amount #962
Conversation
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.
The current go.sum file was out of sync with the go.mod file. This commit updates the go.sum file by running `go mod tidy` to match the go.mod file.
This commit introduces the structure for a new endpoint in the accounts subsystem, enabling balance adjustments by adding or deducting a specified amount. This contrasts with the existing `UpdateAccount` implementation, which directly sets the balance to a fixed value. For more details on the drawbacks of the current implementation, see [issue lightninglabs#648](lightninglabs#648). The actual implementation of the endpoint will be introduced in subsequent commits.
This commit implements the `updatebalance` command in `litcli`. The command is implemented with two different subcommands: `add`, which increases an existing off-chain account’s balance, and `deduct`, which decreases it accordingly.
To support updating an existing off-chain account’s balance by a specified amount in the database, we'll implement a corresponding functions for the different stores. This commit introduces the `AdjustAccountBalance` function in the kvdb store.
db/sqlc/queries/accounts.sql
Outdated
-- name: AdjustAccountBalance :one | ||
UPDATE accounts | ||
SET current_balance_msat = current_balance_msat + CASE | ||
WHEN sqlc.arg(is_addition)::BOOLEAN THEN sqlc.arg(amount) -- If IsAddition is true, add the amount | ||
ELSE -sqlc.arg(amount) -- If IsAddition is false, subtract the amount | ||
END | ||
WHERE id = sqlc.arg(id) | ||
RETURNING id; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you prefer that I use the current functionality instead to fetch the current balance, and then set the balance to the currentBalance +- amount
.
My motivation for introducing this was to discourage such functionality in the future, which directly sets the balance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed re having specific queries for how we prefer to use it 👍
see comment re splitting this out though
This commit introduces the `AdjustAccountBalance` function in the sqlc store, to support updating an existing off-chain account’s balance by a specified amount for sql backends.
With all underlying functionality in place to support updating an existing off-chain account’s balance by a specified amount, this commit implements the `UpdateBalance` endpoint to utilize that functionality.
a851302
to
aed7ef3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
took quick peek (before review was requested - hope you dont mind!) - just leaving some drive by comments in the mean time.
I think we can split this up into 2 PRs: 1) DB + Service additions & tests for those. 2) expose new functionality via RPC + CLI calling code
|
||
switch reqType := req.GetUpdate().(type) { | ||
case *litrpc.UpdateAccountBalanceRequest_Add: | ||
log.Infof("[addbalance] id=%s, label=%v, amount=%d", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think of using "credit/debit" instead of "add/deduct"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah definitely! I was struggling with naming, and agree that credit & debit is better.
@@ -71,6 +72,18 @@ func TestAccountStore(t *testing.T) { | |||
) | |||
require.NoError(t, err) | |||
|
|||
// Adjust the account balance by first adding 10000, and then deducting | |||
// 5000. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for review it's nicer if unit tests are in the same commit as the new addition :)
updateAccountCommand, | ||
updateBalanceCommands, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if we cant fit this under the existing update
category somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, how about just having explicit credit/debit sub commands?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, how about just having explicit credit/debit sub commands?
Went with this option!
@@ -132,6 +132,14 @@ func (s *RPCServer) UpdateAccount(ctx context.Context, | |||
return marshalAccount(account), nil | |||
} | |||
|
|||
// UpdateBalance adds or deducts an amount from an existing account in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just an idea for standard PR flow: we always try to (as much as possible at least) to keep commits ordered such that things are working commit by commit. For 2 reasons: 1) reverting back to any single commit isnt a problem and 2) review story telling.
so the ideal flow for RPC additions is:
- add DB/Service functionality along with any tests for those (in small PR world, that could honestly be the whole PR - since that is like 1 unit of code that is easy to reason about and also lets us continue the on the accounts SQL PR while we iterate on the second unit here which is proto/CLI design).
- add proto definitions & call the new code from the rpc server code
- add CLI calling code
the high level pattern im describing here is:
- server implements new functionality but doesnt expose it yet
- server exposes new functionality
- client starts calling new functionality
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if amount <= 0 { | ||
return nil, fmt.Errorf("amount %v must be greater than 0", | ||
int64(amount/1000)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use uints in the proto definitions then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! Addressed in the new PR.
-- name: AdjustAccountBalance :one | ||
UPDATE accounts | ||
SET current_balance_msat = current_balance_msat + CASE | ||
WHEN sqlc.arg(is_addition) THEN sqlc.arg(amount) -- If IsAddition is true, add the amount | ||
ELSE -sqlc.arg(amount) -- If IsAddition is false, subtract the amount | ||
END | ||
WHERE id = sqlc.arg(id) | ||
RETURNING id; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think let's keep things simple with just having
CreditAccount
and DebitAccount
queries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in the new PR :)
@@ -148,6 +154,28 @@ message UpdateAccountRequest { | |||
string label = 4; | |||
} | |||
|
|||
message UpdateAccountBalanceRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so expanding on my other comment: it doesnt really make sense to starting off the PR with rpc definitions as we dont really know how this is going to be used yet etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in the new PR :)
oneof update { | ||
// Increase the account's balance by the given amount. | ||
int64 add = 3; | ||
|
||
// Deducts the given amount from the account balance. | ||
int64 deduct = 4; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when defining enums like this, it's good to ask: is there a future where more than 2 options will actually be needed? if not, then this can either be a boolean. Or we can even just have separate Credit
/Debit
definitions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so either:
Update {
- ID
- Amount
- Credit/Debit bool
}
or
Credit { ID, Amount }
_and_
Debit {ID, Amount}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redit { ID, Amount }
and
Debit {ID, Amount}
Thanks! Went with the second option :)
good idea. I think we always want to give notice of deprecated endpoints though. So i think in the proto definitions here, you can add a deprecated annotation along with the release where it will be completely removed. Then in the release notes, add a notice about this planned depreciation. Then our next release (or couple releases) will include supporting both to give folks a chance to update to the new endpoint |
Fixes #648
Based on #954
This PR introduces functionality to update an account's balance by a given amount, rather than the current update method, which sets the balance to a specific value.
My plan is to deprecate the old functionality in a follow-up PR after this one is merged.