Skip to content

Commit be966f6

Browse files
committed
firewalldb: best effort link from actions to accounts
1 parent f2efd41 commit be966f6

File tree

7 files changed

+54
-12
lines changed

7 files changed

+54
-12
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: 20 additions & 3 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()
@@ -490,6 +504,9 @@ func TestListGroupActions(t *testing.T) {
490504
}
491505

492506
func assertEqualActions(t *testing.T, expected, got *Action) {
507+
// Accounts are not explicitly linked in our bbolt DB implementation.
508+
got.AccountID = expected.AccountID
509+
493510
expectedAttemptedAt := expected.AttemptedAt
494511
actualAttemptedAt := got.AttemptedAt
495512

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: 5 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() {

0 commit comments

Comments
 (0)