mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
Merge pull request #1078 from lightninglabs/sql40
[sql-40] firewalldb: action store prep commits
This commit is contained in:
commit
bd704c41e3
5 changed files with 66 additions and 26 deletions
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/lightninglabs/lightning-terminal/firewalldb"
|
||||
mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware"
|
||||
"github.com/lightninglabs/lightning-terminal/session"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/macaroons"
|
||||
)
|
||||
|
|
@ -181,16 +182,15 @@ func (r *RequestLogger) Intercept(ctx context.Context,
|
|||
func (r *RequestLogger) addNewAction(ctx context.Context, ri *RequestInfo,
|
||||
withPayloadData bool) error {
|
||||
|
||||
// If no macaroon is provided, then an empty 4-byte array is used as the
|
||||
// macaroon ID. Otherwise, the last 4 bytes of the macaroon's root key
|
||||
// ID are used.
|
||||
var macaroonID [4]byte
|
||||
var macaroonID fn.Option[[4]byte]
|
||||
if ri.Macaroon != nil {
|
||||
var err error
|
||||
macaroonID, err = session.IDFromMacaroon(ri.Macaroon)
|
||||
macID, err := session.IDFromMacaroon(ri.Macaroon)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not extract ID from macaroon")
|
||||
}
|
||||
|
||||
macaroonID = fn.Some([4]byte(macID))
|
||||
}
|
||||
|
||||
actionReq := &firewalldb.AddActionReq{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ const (
|
|||
type AddActionReq struct {
|
||||
// MacaroonIdentifier is a 4 byte identifier created from the last 4
|
||||
// bytes of the root key ID of the macaroon used to perform the action.
|
||||
MacaroonIdentifier [4]byte
|
||||
// If no macaroon was used for the action, then this will not be set.
|
||||
MacaroonIdentifier fn.Option[[4]byte]
|
||||
|
||||
// SessionID holds the optional session ID of the session that this
|
||||
// action was performed with.
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ var (
|
|||
func (db *BoltDB) AddAction(ctx context.Context,
|
||||
req *AddActionReq) (ActionLocator, error) {
|
||||
|
||||
// If no macaroon is provided, then an empty 4-byte array is used as the
|
||||
// macaroon ID.
|
||||
var macaroonID [4]byte
|
||||
req.MacaroonIdentifier.WhenSome(func(id [4]byte) {
|
||||
macaroonID = id
|
||||
})
|
||||
|
||||
// If the new action links to a session, the session must exist.
|
||||
// For the bbolt impl of the store, this is our best effort attempt
|
||||
// at ensuring each action links to a session. If the session is
|
||||
|
|
@ -105,7 +112,7 @@ func (db *BoltDB) AddAction(ctx context.Context,
|
|||
}
|
||||
|
||||
sessBucket, err := actionsBucket.CreateBucketIfNotExists(
|
||||
action.MacaroonIdentifier[:],
|
||||
macaroonID[:],
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -134,7 +141,7 @@ func (db *BoltDB) AddAction(ctx context.Context,
|
|||
}
|
||||
|
||||
locator = kvdbActionLocator{
|
||||
sessionID: action.MacaroonIdentifier,
|
||||
sessionID: macaroonID,
|
||||
actionID: nextActionIndex,
|
||||
}
|
||||
|
||||
|
|
@ -323,7 +330,13 @@ func (db *BoltDB) ListActions(ctx context.Context, query *ListActionsQuery,
|
|||
)
|
||||
}
|
||||
if opts.groupID != session.EmptyID {
|
||||
actions, err := db.listGroupActions(ctx, opts.groupID, filterFn)
|
||||
var reversed bool
|
||||
if query != nil {
|
||||
reversed = query.Reversed
|
||||
}
|
||||
actions, err := db.listGroupActions(
|
||||
ctx, opts.groupID, filterFn, reversed,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
|
@ -432,11 +445,11 @@ func (db *BoltDB) listSessionActions(sessionID session.ID,
|
|||
//
|
||||
// TODO: update to allow for pagination.
|
||||
func (db *BoltDB) listGroupActions(ctx context.Context, groupID session.ID,
|
||||
filterFn listActionsFilterFn) ([]*Action, error) {
|
||||
filterFn listActionsFilterFn, reversed bool) ([]*Action, error) {
|
||||
|
||||
if filterFn == nil {
|
||||
filterFn = func(a *Action, reversed bool) (bool, bool) {
|
||||
return true, true
|
||||
return true, reversed
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,9 +488,18 @@ func (db *BoltDB) listGroupActions(ctx context.Context, groupID session.ID,
|
|||
return err
|
||||
}
|
||||
|
||||
include, cont := filterFn(action, false)
|
||||
include, cont := filterFn(action, reversed)
|
||||
if include {
|
||||
actions = append(actions, action)
|
||||
if !reversed {
|
||||
actions = append(
|
||||
actions, action,
|
||||
)
|
||||
} else {
|
||||
actions = append(
|
||||
[]*Action{action},
|
||||
actions...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if !cont {
|
||||
|
|
@ -574,7 +596,7 @@ func DeserializeAction(r io.Reader, sessionID session.ID) (*Action, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
action.MacaroonIdentifier = sessionID
|
||||
action.MacaroonIdentifier = fn.Some([4]byte(sessionID))
|
||||
action.SessionID = fn.Some(sessionID)
|
||||
action.ActorName = string(actor)
|
||||
action.FeatureName = string(featureName)
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
testTime1 = time.Unix(32100, 0)
|
||||
testTime2 = time.Unix(12300, 0)
|
||||
testTime1 = time.Unix(12300, 0)
|
||||
testTime2 = time.Unix(32100, 0)
|
||||
)
|
||||
|
||||
// TestActionStorage tests that the ActionsListDB CRUD logic.
|
||||
|
|
@ -67,7 +67,7 @@ func TestActionStorage(t *testing.T) {
|
|||
action1Req := &AddActionReq{
|
||||
SessionID: fn.Some(sess1.ID),
|
||||
AccountID: fn.Some(acct1.ID),
|
||||
MacaroonIdentifier: sess1.ID,
|
||||
MacaroonIdentifier: fn.Some([4]byte(sess1.ID)),
|
||||
ActorName: "Autopilot",
|
||||
FeatureName: "auto-fees",
|
||||
Trigger: "fee too low",
|
||||
|
|
@ -85,7 +85,7 @@ func TestActionStorage(t *testing.T) {
|
|||
|
||||
action2Req := &AddActionReq{
|
||||
SessionID: fn.Some(sess2.ID),
|
||||
MacaroonIdentifier: sess2.ID,
|
||||
MacaroonIdentifier: fn.Some([4]byte(sess2.ID)),
|
||||
ActorName: "Autopilot",
|
||||
FeatureName: "rebalancer",
|
||||
Trigger: "channels not balanced",
|
||||
|
|
@ -161,7 +161,7 @@ func TestActionStorage(t *testing.T) {
|
|||
|
||||
// Check that providing no session id and no filter function returns
|
||||
// all the actions.
|
||||
actions, _, _, err = db.ListActions(nil, &ListActionsQuery{
|
||||
actions, _, _, err = db.ListActions(ctx, &ListActionsQuery{
|
||||
IndexOffset: 0,
|
||||
MaxNum: 100,
|
||||
Reversed: false,
|
||||
|
|
@ -223,7 +223,7 @@ func TestListActions(t *testing.T) {
|
|||
actionIds++
|
||||
|
||||
actionReq := &AddActionReq{
|
||||
MacaroonIdentifier: sessionID,
|
||||
MacaroonIdentifier: fn.Some(sessionID),
|
||||
ActorName: "Autopilot",
|
||||
FeatureName: fmt.Sprintf("%d", actionIds),
|
||||
Trigger: "fee too low",
|
||||
|
|
@ -245,9 +245,11 @@ func TestListActions(t *testing.T) {
|
|||
assertActions := func(dbActions []*Action, al []*action) {
|
||||
require.Len(t, dbActions, len(al))
|
||||
for i, a := range al {
|
||||
require.EqualValues(
|
||||
t, a.sessionID, dbActions[i].MacaroonIdentifier,
|
||||
mID, err := dbActions[i].MacaroonIdentifier.UnwrapOrErr(
|
||||
fmt.Errorf("macaroon identifier is none"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, a.sessionID, mID)
|
||||
require.Equal(t, a.actionID, dbActions[i].FeatureName)
|
||||
}
|
||||
}
|
||||
|
|
@ -433,7 +435,7 @@ func TestListGroupActions(t *testing.T) {
|
|||
|
||||
action1Req := &AddActionReq{
|
||||
SessionID: fn.Some(sess1.ID),
|
||||
MacaroonIdentifier: sess1.ID,
|
||||
MacaroonIdentifier: fn.Some([4]byte(sess1.ID)),
|
||||
ActorName: "Autopilot",
|
||||
FeatureName: "auto-fees",
|
||||
Trigger: "fee too low",
|
||||
|
|
@ -451,7 +453,7 @@ func TestListGroupActions(t *testing.T) {
|
|||
|
||||
action2Req := &AddActionReq{
|
||||
SessionID: fn.Some(sess2.ID),
|
||||
MacaroonIdentifier: sess2.ID,
|
||||
MacaroonIdentifier: fn.Some([4]byte(sess2.ID)),
|
||||
ActorName: "Autopilot",
|
||||
FeatureName: "rebalancer",
|
||||
Trigger: "channels not balanced",
|
||||
|
|
@ -495,12 +497,22 @@ func TestListGroupActions(t *testing.T) {
|
|||
_, err = db.AddAction(ctx, action2Req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// There should now be actions in the group.
|
||||
// There should now be two actions in the group.
|
||||
al, _, _, err = db.ListActions(ctx, nil, WithActionGroupID(group1))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, al, 2)
|
||||
assertEqualActions(t, action1, al[0])
|
||||
assertEqualActions(t, action2, al[1])
|
||||
|
||||
// Try the reversed query too.
|
||||
al, _, _, err = db.ListActions(
|
||||
ctx, &ListActionsQuery{Reversed: true},
|
||||
WithActionGroupID(group1),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, al, 2)
|
||||
assertEqualActions(t, action2, al[0])
|
||||
assertEqualActions(t, action1, al[1])
|
||||
}
|
||||
|
||||
func assertEqualActions(t *testing.T, expected, got *Action) {
|
||||
|
|
|
|||
|
|
@ -806,9 +806,14 @@ func (s *sessionRpcServer) ListActions(ctx context.Context,
|
|||
sessionID = id
|
||||
})
|
||||
|
||||
var macID [4]byte
|
||||
a.MacaroonIdentifier.WhenSome(func(id [4]byte) {
|
||||
macID = id
|
||||
})
|
||||
|
||||
resp[i] = &litrpc.Action{
|
||||
SessionId: sessionID[:],
|
||||
MacaroonIdentifier: a.MacaroonIdentifier[:],
|
||||
MacaroonIdentifier: macID[:],
|
||||
ActorName: a.ActorName,
|
||||
FeatureName: a.FeatureName,
|
||||
Trigger: a.Trigger,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue