Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions accounts/store_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type SQLQueries interface {
UpdateAccountBalance(ctx context.Context, arg sqlc.UpdateAccountBalanceParams) (int64, error)
UpdateAccountExpiry(ctx context.Context, arg sqlc.UpdateAccountExpiryParams) (int64, error)
UpdateAccountLastUpdate(ctx context.Context, arg sqlc.UpdateAccountLastUpdateParams) (int64, error)
// UpdateAccountAliasForTests is a query intended only for testing
// purposes, to change the account alias.
UpdateAccountAliasForTests(ctx context.Context, arg sqlc.UpdateAccountAliasForTestsParams) (int64, error)
UpsertAccountPayment(ctx context.Context, arg sqlc.UpsertAccountPaymentParams) error
GetAccountInvoice(ctx context.Context, arg sqlc.GetAccountInvoiceParams) (sqlc.AccountInvoice, error)
}
Expand Down
20 changes: 20 additions & 0 deletions db/sqlc/accounts.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions db/sqlc/actions.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions db/sqlc/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions db/sqlc/queries/accounts.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ RETURNING id;
INSERT INTO account_invoices (account_id, hash)
VALUES ($1, $2);

-- name: UpdateAccountAliasForTests :one
-- NOTE: This query is only intended for testing purposes.
UPDATE accounts
SET alias = $1
WHERE id = $2
RETURNING id;

-- name: DeleteAccountPayment :exec
DELETE FROM account_payments
WHERE hash = $1
Expand Down
6 changes: 6 additions & 0 deletions db/sqlc/queries/actions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ UPDATE actions
SET action_state = $1,
error_reason = $2
WHERE id = $3;


-- name: GetAction :one
SELECT *
FROM actions
WHERE id = $1;
19 changes: 16 additions & 3 deletions firewall/request_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"

"github.com/lightninglabs/lightning-terminal/firewalldb"
litd_macaroons "github.com/lightninglabs/lightning-terminal/macaroons"
mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware"
"github.com/lightninglabs/lightning-terminal/session"
"github.com/lightningnetwork/lnd/fn"
Expand Down Expand Up @@ -182,21 +183,33 @@ func (r *RequestLogger) Intercept(ctx context.Context,
func (r *RequestLogger) addNewAction(ctx context.Context, ri *RequestInfo,
withPayloadData bool) error {

var macaroonID fn.Option[[4]byte]
var (
rootKeyID fn.Option[uint64]
macaroonID fn.Option[[4]byte]
)

if ri.Macaroon != nil {
var err error
macID, err := session.IDFromMacaroon(ri.Macaroon)

fullRootKeyID, err := litd_macaroons.RootKeyIDFromMacaroon(
ri.Macaroon,
)
if err != nil {
return fmt.Errorf("could not extract ID from macaroon")
return fmt.Errorf("could not extract root key ID from "+
"macaroon: %w", err)
}

macID := session.IDFromMacRootKeyID(fullRootKeyID)

rootKeyID = fn.Some(fullRootKeyID)
macaroonID = fn.Some([4]byte(macID))
}

actionReq := &firewalldb.AddActionReq{
SessionID: ri.SessionID,
AccountID: ri.AccountID,
MacaroonIdentifier: macaroonID,
MacaroonRootKeyID: rootKeyID,
RPCMethod: ri.URI,
}

Expand Down
5 changes: 5 additions & 0 deletions firewalldb/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ type AddActionReq struct {
// If no macaroon was used for the action, then this will not be set.
MacaroonIdentifier fn.Option[[4]byte]

// MacaroonRootKeyID is the uint64 / full 8 bytes of the root key ID of
// the macaroon used to perform the action.
// If no macaroon was used for the action, then this will not be set.
MacaroonRootKeyID fn.Option[uint64]

// SessionID holds the optional session ID of the session that this
// action was performed with.
//
Expand Down
21 changes: 17 additions & 4 deletions firewalldb/actions_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package firewalldb
import (
"context"
"database/sql"
"encoding/binary"
"errors"
"fmt"
"math"
Expand Down Expand Up @@ -34,6 +35,7 @@ type SQLActionQueries interface {
SetActionState(ctx context.Context, arg sqlc.SetActionStateParams) error
ListActions(ctx context.Context, arg sqlc.ListActionsParams) ([]sqlc.Action, error)
CountActions(ctx context.Context, arg sqlc.ActionQueryParams) (int64, error)
GetAction(ctx context.Context, id int64) (sqlc.Action, error)
}

// sqlActionLocator helps us find an action in the SQL DB.
Expand Down Expand Up @@ -140,8 +142,11 @@ func (s *SQLDB) AddAction(ctx context.Context,
}

var macID []byte
req.MacaroonIdentifier.WhenSome(func(id [4]byte) {
macID = id[:]
req.MacaroonRootKeyID.WhenSome(func(rootKeyID uint64) {
rootKeyBytes := make([]byte, 8)
binary.BigEndian.PutUint64(rootKeyBytes[:], rootKeyID)

macID = rootKeyBytes
})

id, err := db.InsertAction(ctx, sqlc.InsertActionParams{
Expand Down Expand Up @@ -393,9 +398,17 @@ func unmarshalAction(ctx context.Context, db SQLActionQueries,
legacyAcctID = fn.Some(acctID)
}

// While we store the full 8 byte macaroon root key ID in the sql
// actions DB, the kvdb version only stored the last 4 bytes. So
// we'll only return that here to maintain compatibility with any
// existing callers.
//
// TODO(viktor): Remove this when we no longer need to be compatible
// with the kvdb version.
var macID fn.Option[[4]byte]
if len(dbAction.MacaroonIdentifier) > 0 {
macID = fn.Some([4]byte(dbAction.MacaroonIdentifier))
if len(dbAction.MacaroonIdentifier) >= 4 {
dbMacID := dbAction.MacaroonIdentifier
macID = fn.Some([4]byte(dbMacID[len(dbMacID)-4:]))
}

return &Action{
Expand Down
27 changes: 27 additions & 0 deletions firewalldb/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package firewalldb

import (
"context"
"encoding/binary"
"fmt"
"testing"
"time"
Expand Down Expand Up @@ -60,10 +61,13 @@ func TestActionStorage(t *testing.T) {
acct1, err := accountsDB.NewAccount(ctx, 0, time.Time{}, "foo")
require.NoError(t, err)

sess1RootKeyID := macIDToRootKeyID(sess1.ID)

action1Req := &AddActionReq{
SessionID: fn.Some(sess1.ID),
AccountID: fn.Some(acct1.ID),
MacaroonIdentifier: fn.Some([4]byte(sess1.ID)),
MacaroonRootKeyID: fn.Some(sess1RootKeyID),
ActorName: "Autopilot",
FeatureName: "auto-fees",
Trigger: "fee too low",
Expand All @@ -79,9 +83,12 @@ func TestActionStorage(t *testing.T) {
State: ActionStateDone,
}

sess2RootKeyID := macIDToRootKeyID(sess2.ID)

action2Req := &AddActionReq{
SessionID: fn.Some(sess2.ID),
MacaroonIdentifier: fn.Some([4]byte(sess2.ID)),
MacaroonRootKeyID: fn.Some(sess2RootKeyID),
ActorName: "Autopilot",
FeatureName: "rebalancer",
Trigger: "channels not balanced",
Expand Down Expand Up @@ -213,8 +220,11 @@ func TestListActions(t *testing.T) {
addAction := func(sessionID [4]byte) {
actionIds++

sessRootKeyID := macIDToRootKeyID(sessionID)

actionReq := &AddActionReq{
MacaroonIdentifier: fn.Some(sessionID),
MacaroonRootKeyID: fn.Some(sessRootKeyID),
ActorName: "Autopilot",
FeatureName: fmt.Sprintf("%d", actionIds),
Trigger: "fee too low",
Expand Down Expand Up @@ -424,9 +434,12 @@ func TestListGroupActions(t *testing.T) {
)
require.NoError(t, err)

sess1RootKeyID := macIDToRootKeyID(sess1.ID)

action1Req := &AddActionReq{
SessionID: fn.Some(sess1.ID),
MacaroonIdentifier: fn.Some([4]byte(sess1.ID)),
MacaroonRootKeyID: fn.Some(sess1RootKeyID),
ActorName: "Autopilot",
FeatureName: "auto-fees",
Trigger: "fee too low",
Expand All @@ -442,9 +455,12 @@ func TestListGroupActions(t *testing.T) {
State: ActionStateDone,
}

sess2RootKeyID := macIDToRootKeyID(sess2.ID)

action2Req := &AddActionReq{
SessionID: fn.Some(sess2.ID),
MacaroonIdentifier: fn.Some([4]byte(sess2.ID)),
MacaroonRootKeyID: fn.Some(sess2RootKeyID),
ActorName: "Autopilot",
FeatureName: "rebalancer",
Trigger: "channels not balanced",
Expand Down Expand Up @@ -501,3 +517,14 @@ func TestListGroupActions(t *testing.T) {
assertEqualActions(t, action2, al[0])
assertEqualActions(t, action1, al[1])
}

// macIDToRootKeyID is a helper function for tests that converts a 4 byte
// macaroon ID to a full macaroon root key ID by padding it to 8 bytes.
// Note that the first 4 bytes of the returned root key ID will be zeros,
// followed by the 4 bytes passed in.
func macIDToRootKeyID(macID [4]byte) uint64 {
rootKeyIDBytes := make([]byte, 8)
copy(rootKeyIDBytes[4:], macID[:])

return binary.BigEndian.Uint64(rootKeyIDBytes)
}
Loading
Loading