Skip to content

Commit 3c200bb

Browse files
committed
firewalldb: best effor link from actions to accounts
1 parent 7bcb4bd commit 3c200bb

File tree

8 files changed

+73
-26
lines changed

8 files changed

+73
-26
lines changed

config_dev.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ func NewStores(cfg *Config, clock clock.Clock) (*stores, error) {
154154
}
155155

156156
firewallBoltDB, err := firewalldb.NewBoltDB(
157-
networkDir, firewalldb.DBFilename, stores.sessions, clock,
157+
networkDir, firewalldb.DBFilename, stores.sessions,
158+
stores.accounts, clock,
158159
)
159160
if err != nil {
160161
return stores, fmt.Errorf("error creating firewall BoltDB: %v",

config_prod.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ func NewStores(cfg *Config, clock clock.Clock) (*stores, error) {
5656
stores.closeFns["sessions"] = sessStore.Close
5757

5858
firewallDB, err := firewalldb.NewBoltDB(
59-
networkDir, firewalldb.DBFilename, sessStore, clock,
59+
networkDir, firewalldb.DBFilename, stores.sessions,
60+
stores.accounts, clock,
6061
)
6162
if err != nil {
6263
return stores, fmt.Errorf("error creating firewall DB: %v", err)

firewalldb/actions_kvdb.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"io"
1010
"time"
1111

12+
"github.com/lightninglabs/lightning-terminal/accounts"
1213
"github.com/lightninglabs/lightning-terminal/session"
1314
"github.com/lightningnetwork/lnd/fn"
1415
"github.com/lightningnetwork/lnd/tlv"
@@ -69,6 +70,17 @@ func (db *BoltDB) AddAction(ctx context.Context,
6970
return nil, err
7071
}
7172

73+
// If the new action links to an account, the account must exist.
74+
// For the bbolt impl of the store, this is our best effort attempt
75+
// at ensuring each action links to an account. If the account is
76+
// deleted later on, however, then the action will still exist.
77+
req.AccountID.WhenSome(func(id accounts.AccountID) {
78+
_, err = db.accountsDB.Account(ctx, id)
79+
})
80+
if err != nil {
81+
return nil, err
82+
}
83+
7284
action := &Action{
7385
AddActionReq: *req,
7486
AttemptedAt: db.clock.Now().UTC(),

firewalldb/actions_test.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/lightninglabs/lightning-terminal/accounts"
910
"github.com/lightninglabs/lightning-terminal/session"
1011
"github.com/lightningnetwork/lnd/clock"
1112
"github.com/lightningnetwork/lnd/fn"
@@ -24,8 +25,9 @@ func TestActionStorage(t *testing.T) {
2425
ctx := context.Background()
2526
clock := clock.NewTestClock(testTime1)
2627
sessDB := session.NewTestDB(t, clock)
28+
accountsDB := accounts.NewTestDB(t, clock)
2729

28-
db, err := NewBoltDB(t.TempDir(), "test.db", sessDB, clock)
30+
db, err := NewBoltDB(t.TempDir(), "test.db", sessDB, accountsDB, clock)
2931
require.NoError(t, err)
3032
t.Cleanup(func() {
3133
_ = db.Close()
@@ -38,6 +40,13 @@ func TestActionStorage(t *testing.T) {
3840
})
3941
require.ErrorIs(t, err, session.ErrSessionNotFound)
4042

43+
// Assert that attempting to add an action that links to an account
44+
// that does not exist returns an error.
45+
_, err = db.AddAction(ctx, &AddActionReq{
46+
AccountID: fn.Some(accounts.AccountID{1, 2, 3, 4}),
47+
})
48+
require.ErrorIs(t, err, accounts.ErrAccNotFound)
49+
4150
// Add two sessions to the session DB so that we can reference them.
4251
sess1, err := sessDB.NewSession(
4352
ctx, "sess 1", session.TypeAutopilot, time.Unix(1000, 0),
@@ -51,8 +60,13 @@ func TestActionStorage(t *testing.T) {
5160
)
5261
require.NoError(t, err)
5362

63+
// Add an account that we can link to as well.
64+
acct1, err := accountsDB.NewAccount(ctx, 0, time.Time{}, "foo")
65+
require.NoError(t, err)
66+
5467
action1Req := &AddActionReq{
5568
SessionID: fn.Some(sess1.ID),
69+
AccountID: fn.Some(acct1.ID),
5670
MacaroonIdentifier: sess1.ID,
5771
ActorName: "Autopilot",
5872
FeatureName: "auto-fees",
@@ -185,7 +199,7 @@ func TestListActions(t *testing.T) {
185199
clock := clock.NewDefaultClock()
186200
sessDB := session.NewTestDB(t, clock)
187201

188-
db, err := NewBoltDB(tmpDir, "test.db", sessDB, clock)
202+
db, err := NewBoltDB(tmpDir, "test.db", sessDB, nil, clock)
189203
require.NoError(t, err)
190204
t.Cleanup(func() {
191205
_ = db.Close()
@@ -452,7 +466,7 @@ func TestListGroupActions(t *testing.T) {
452466
State: ActionStateInit,
453467
}
454468

455-
db, err := NewBoltDB(t.TempDir(), "test.db", sessDB, clock)
469+
db, err := NewBoltDB(t.TempDir(), "test.db", sessDB, nil, clock)
456470
require.NoError(t, err)
457471
t.Cleanup(func() {
458472
_ = db.Close()
@@ -488,17 +502,3 @@ func TestListGroupActions(t *testing.T) {
488502
assertEqualActions(t, action1, al[0])
489503
assertEqualActions(t, action2, al[1])
490504
}
491-
492-
func assertEqualActions(t *testing.T, expected, got *Action) {
493-
expectedAttemptedAt := expected.AttemptedAt
494-
actualAttemptedAt := got.AttemptedAt
495-
496-
expected.AttemptedAt = time.Time{}
497-
got.AttemptedAt = time.Time{}
498-
499-
require.Equal(t, expected, got)
500-
require.Equal(t, expectedAttemptedAt.Unix(), actualAttemptedAt.Unix())
501-
502-
expected.AttemptedAt = expectedAttemptedAt
503-
got.AttemptedAt = actualAttemptedAt
504-
}

firewalldb/interface.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package firewalldb
33
import (
44
"context"
55

6+
"github.com/lightninglabs/lightning-terminal/accounts"
67
"github.com/lightninglabs/lightning-terminal/session"
78
)
89

@@ -15,6 +16,15 @@ type SessionDB interface {
1516
GetSession(context.Context, session.ID) (*session.Session, error)
1617
}
1718

19+
// AccountsDB is an interface that abstracts the database operations needed
20+
// firewalldb to be able to query the accounts database.
21+
type AccountsDB interface {
22+
// Account fetches the Account with the given id from the accounts
23+
// database.
24+
Account(ctx context.Context,
25+
id accounts.AccountID) (*accounts.OffChainBalanceAccount, error)
26+
}
27+
1828
// DBExecutor provides an Update and View method that will allow the caller
1929
// to perform atomic read and write transactions defined by PrivacyMapTx on the
2030
// underlying BoltDB.

firewalldb/kvdb_store.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ type BoltDB struct {
4141
clock clock.Clock
4242

4343
sessionIDIndex SessionDB
44+
accountsDB AccountsDB
4445
}
4546

4647
// NewBoltDB creates a new bolt database that can be found at the given
4748
// directory.
4849
func NewBoltDB(dir, fileName string, sessionIDIndex SessionDB,
49-
clock clock.Clock) (*BoltDB, error) {
50+
accountsDB AccountsDB, clock clock.Clock) (*BoltDB, error) {
5051

5152
firstInit := false
5253
path := filepath.Join(dir, fileName)
@@ -73,6 +74,7 @@ func NewBoltDB(dir, fileName string, sessionIDIndex SessionDB,
7374
return &BoltDB{
7475
DB: db,
7576
sessionIDIndex: sessionIDIndex,
77+
accountsDB: accountsDB,
7678
clock: clock,
7779
}, nil
7880
}

firewalldb/test_kvdb.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package firewalldb
55
import (
66
"testing"
77

8-
"github.com/lightninglabs/lightning-terminal/session"
98
"github.com/lightningnetwork/lnd/clock"
109
"github.com/stretchr/testify/require"
1110
)
@@ -18,21 +17,21 @@ func NewTestDB(t *testing.T, clock clock.Clock) *BoltDB {
1817
// NewTestDBFromPath is a helper function that creates a new BoltStore with a
1918
// connection to an existing BBolt database for testing.
2019
func NewTestDBFromPath(t *testing.T, dbPath string, clock clock.Clock) *BoltDB {
21-
return newDBFromPathWithSessions(t, dbPath, nil, clock)
20+
return newDBFromPathWithSessions(t, dbPath, nil, nil, clock)
2221
}
2322

2423
// NewTestDBWithSessions creates a new test BoltDB Store with access to an
2524
// existing sessions DB.
26-
func NewTestDBWithSessions(t *testing.T, sessStore session.Store,
25+
func NewTestDBWithSessions(t *testing.T, sessStore SessionDB,
2726
clock clock.Clock) *BoltDB {
2827

29-
return newDBFromPathWithSessions(t, t.TempDir(), sessStore, clock)
28+
return newDBFromPathWithSessions(t, t.TempDir(), sessStore, nil, clock)
3029
}
3130

3231
func newDBFromPathWithSessions(t *testing.T, dbPath string,
33-
sessStore session.Store, clock clock.Clock) *BoltDB {
32+
sessStore SessionDB, acctStore AccountsDB, clock clock.Clock) *BoltDB {
3433

35-
store, err := NewBoltDB(dbPath, DBFilename, sessStore, clock)
34+
store, err := NewBoltDB(dbPath, DBFilename, sessStore, acctStore, clock)
3635
require.NoError(t, err)
3736

3837
t.Cleanup(func() {
@@ -41,3 +40,10 @@ func newDBFromPathWithSessions(t *testing.T, dbPath string,
4140

4241
return store
4342
}
43+
44+
func assertEqualActions(t *testing.T, expected, got *Action) {
45+
// Accounts are not explicitly linked in our bbolt DB implementation.
46+
got.AccountID = expected.AccountID
47+
48+
require.Equal(t, expected, got)
49+
}

firewalldb/test_sql.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package firewalldb
44

55
import (
66
"testing"
7+
"time"
78

89
"github.com/lightninglabs/lightning-terminal/session"
910
"github.com/lightningnetwork/lnd/clock"
@@ -20,3 +21,17 @@ func NewTestDBWithSessions(t *testing.T, sessionStore session.Store,
2021

2122
return NewSQLDB(sessions.BaseDB, clock)
2223
}
24+
25+
func assertEqualActions(t *testing.T, expected, got *Action) {
26+
expectedAttemptedAt := expected.AttemptedAt
27+
actualAttemptedAt := got.AttemptedAt
28+
29+
expected.AttemptedAt = time.Time{}
30+
got.AttemptedAt = time.Time{}
31+
32+
require.Equal(t, expected, got)
33+
require.Equal(t, expectedAttemptedAt.Unix(), actualAttemptedAt.Unix())
34+
35+
expected.AttemptedAt = expectedAttemptedAt
36+
got.AttemptedAt = actualAttemptedAt
37+
}

0 commit comments

Comments
 (0)