Skip to content

Commit

Permalink
Merge pull request #395 from ffranr/386-expose-historical-account-mod…
Browse files Browse the repository at this point in the history
…ification-fees-via-rpc

Expose historical account action fees via RPC
  • Loading branch information
guggero authored Nov 15, 2022
2 parents 87f76c7 + cd63205 commit e65f78d
Show file tree
Hide file tree
Showing 10 changed files with 1,439 additions and 712 deletions.
46 changes: 34 additions & 12 deletions account/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/verrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
"github.com/lightningnetwork/lnd/lnwallet"
Expand All @@ -52,6 +53,8 @@ const (
// both extremes for valid account expirations.
minAccountExpiry = 144 // One day worth of blocks.
maxAccountExpiry = 144 * 365 // A year worth of blocks.

txLabelPrefixTag = "poold -- "
)

var (
Expand Down Expand Up @@ -148,27 +151,46 @@ type AccountTxLabel struct {
func actionTxLabel(account *Account, action Action, isExpirySpend bool,
txFee *btcutil.Amount, balanceDiff btcutil.Amount) string {

prefixTag := "poold -- %s"

acctKey := account.TraderKey.PubKey.SerializeCompressed()
key := fmt.Sprintf("%x", acctKey)
label := AccountTxLabel{
Key: key,
Action: action,
ExpiryHeight: account.Expiry,
OutputIndex: account.OutPoint.Index,
IsExpirySpend: isExpirySpend,
TxFee: txFee,
BalanceDiff: balanceDiff,
label := TxLabel{
Account: AccountTxLabel{
Key: key,
Action: action,
ExpiryHeight: account.Expiry,
OutputIndex: account.OutPoint.Index,
IsExpirySpend: isExpirySpend,
TxFee: txFee,
BalanceDiff: balanceDiff,
},
}
labelJson, err := json.Marshal(label)
if err != nil {
log.Errorf("Internal error: failed to serialize json "+
"from %v: %v", label, err)
return fmt.Sprintf(prefixTag, action)
return fmt.Sprintf("%s%s", txLabelPrefixTag, action)
}

return fmt.Sprintf("%s%s", txLabelPrefixTag, labelJson)
}

// IsPoolTx returns true if the given transaction is related to pool.
func IsPoolTx(tx *lnrpc.Transaction) bool {
return strings.HasPrefix(tx.Label, txLabelPrefixTag)
}

// ParseTxLabel parses and returns data fields stored in a given transaction
// label.
func ParseTxLabel(label string) (*TxLabel, error) {
label = strings.TrimPrefix(label, txLabelPrefixTag)

var data TxLabel
err := json.Unmarshal([]byte(label), &data)
if err != nil {
return nil, err
}

return fmt.Sprintf(prefixTag, labelJson)
return &data, nil
}

// ManagerConfig contains all of the required dependencies for the Manager to
Expand Down
66 changes: 60 additions & 6 deletions account/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ var (
)

type testCase struct {
name string
feeExpr FeeExpr
fee btcutil.Amount
version Version
newVersion Version
expectedErr string
name string
feeExpr FeeExpr
fee btcutil.Amount
version Version
newVersion Version
expectedErr string
action Action
isExpirySpend bool

// The following fields are only used by deposit tests.
fundedOutputAmount btcutil.Amount
Expand Down Expand Up @@ -1430,3 +1432,55 @@ func TestMakeTxnLabel(t *testing.T) {
require.Equal(t, genLabel, testCase.label)
}
}

// TestParseTxLabel tests whether an account transaction labels can be
// parsed correctly.
func TestParseTxLabel(t *testing.T) {
t.Parallel()

cases := []*testCase{
{
fee: btcutil.Amount(1027),
action: WITHDRAW,
isExpirySpend: false,
},
{
fee: btcutil.Amount(42),
action: DEPOSIT,
isExpirySpend: false,
},
{
fee: btcutil.Amount(42),
action: RENEW,
isExpirySpend: true,
},
}

runSubTests(t, cases, func(t *testing.T, h *testHarness, tc *testCase) {
expiryHeight := uint32(bestHeight + maxAccountExpiry)
account := h.openAccount(
maxAccountValue, expiryHeight, bestHeight, tc.version,
)
acctKey := account.TraderKey.PubKey.SerializeCompressed()
key := fmt.Sprintf("%x", acctKey)
label := actionTxLabel(
account, tc.action, tc.isExpirySpend, &tc.fee,
btcutil.Amount(10000),
)
actual, err := ParseTxLabel(label)

expected := &TxLabel{
AccountTxLabel{
Key: key,
Action: tc.action,
ExpiryHeight: expiryHeight,
OutputIndex: 0,
IsExpirySpend: tc.isExpirySpend,
TxFee: &tc.fee,
BalanceDiff: btcutil.Amount(10000),
},
}
require.Nil(t, err)
require.Equal(t, expected, actual)
})
}
30 changes: 30 additions & 0 deletions cmd/pool/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var accountsCommands = []cli.Command{
withdrawAccountCommand,
renewAccountCommand,
closeAccountCommand,
listAccountFeesCommand,
bumpAccountFeeCommand,
recoverAccountsCommand,
},
Expand Down Expand Up @@ -819,6 +820,35 @@ func bumpAccountFee(ctx *cli.Context) error {
return nil
}

var listAccountFeesCommand = cli.Command{
Name: "listfees",
ShortName: "f",
Usage: "list the account modification transaction fees",
Description: `
This command prints a map from account key to an ordered list of account
modification transaction fees.
`,
Action: listAccountFees,
}

func listAccountFees(ctx *cli.Context) error {
client, cleanup, err := getClient(ctx)
if err != nil {
return err
}
defer cleanup()

resp, err := client.AccountModificationFees(
context.Background(), &poolrpc.AccountModificationFeesRequest{},
)
if err != nil {
return err
}

printRespJSON(resp)
return nil
}

var recoverAccountsCommand = cli.Command{
Name: "recover",
Usage: "recover accounts after data loss with the help of the " +
Expand Down
4 changes: 4 additions & 0 deletions perms/perms.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ var RequiredPermissions = map[string][]bakery.Op{
Entity: "account",
Action: "write",
}},
"/poolrpc.Trader/AccountModificationFees": {{
Entity: "account",
Action: "read",
}},
"/poolrpc.Trader/SubmitOrder": {{
Entity: "order",
Action: "write",
Expand Down
Loading

0 comments on commit e65f78d

Please sign in to comment.