@@ -5,8 +5,10 @@ import (
5
5
"context"
6
6
"fmt"
7
7
"testing"
8
+ "time"
8
9
9
10
"github.com/lightninglabs/lightning-terminal/session"
11
+ "github.com/lightningnetwork/lnd/clock"
10
12
"github.com/stretchr/testify/require"
11
13
)
12
14
@@ -83,15 +85,21 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
83
85
featureName = "auto-fees"
84
86
}
85
87
86
- store := NewTestDB (t )
88
+ sessions := session .NewTestDB (t , clock .NewDefaultClock ())
89
+ store := NewTestDBWithSessions (t , sessions )
87
90
db := NewDB (store )
88
91
require .NoError (t , db .Start (ctx ))
89
92
90
- kvstores := db .GetKVStores (
91
- "test-rule" , [4 ]byte {1 , 1 , 1 , 1 }, featureName ,
93
+ // Create a session that we can reference.
94
+ sess , err := sessions .NewSession (
95
+ ctx , "test" , session .TypeAutopilot , time .Unix (1000 , 0 ),
96
+ "something" ,
92
97
)
98
+ require .NoError (t , err )
99
+
100
+ kvstores := db .GetKVStores ("test-rule" , sess .GroupID , featureName )
93
101
94
- err : = kvstores .Update (ctx , func (ctx context.Context ,
102
+ err = kvstores .Update (ctx , func (ctx context.Context ,
95
103
tx KVStoreTx ) error {
96
104
97
105
// Set an item in the temp store.
@@ -137,7 +145,7 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
137
145
require .NoError (t , db .Stop ())
138
146
})
139
147
140
- kvstores = db .GetKVStores ("test-rule" , [ 4 ] byte { 1 , 1 , 1 , 1 } , featureName )
148
+ kvstores = db .GetKVStores ("test-rule" , sess . GroupID , featureName )
141
149
142
150
// The temp store should no longer have the stored value but the perm
143
151
// store should .
@@ -164,23 +172,31 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
164
172
func TestKVStoreNameSpaces (t * testing.T ) {
165
173
t .Parallel ()
166
174
ctx := context .Background ()
167
- db := NewTestDB (t )
168
175
169
- var (
170
- groupID1 = intToSessionID (1 )
171
- groupID2 = intToSessionID (2 )
176
+ sessions := session .NewTestDB (t , clock .NewDefaultClock ())
177
+ db := NewTestDBWithSessions (t , sessions )
178
+
179
+ // Create 2 sessions that we can reference.
180
+ sess1 , err := sessions .NewSession (
181
+ ctx , "test" , session .TypeAutopilot , time .Unix (1000 , 0 ), "" ,
172
182
)
183
+ require .NoError (t , err )
184
+
185
+ sess2 , err := sessions .NewSession (
186
+ ctx , "test1" , session .TypeAutopilot , time .Unix (1000 , 0 ), "" ,
187
+ )
188
+ require .NoError (t , err )
173
189
174
190
// Two DBs for same group but different features.
175
- rulesDB1 := db .GetKVStores ("test-rule" , groupID1 , "auto-fees" )
176
- rulesDB2 := db .GetKVStores ("test-rule" , groupID1 , "re-balance" )
191
+ rulesDB1 := db .GetKVStores ("test-rule" , sess1 . GroupID , "auto-fees" )
192
+ rulesDB2 := db .GetKVStores ("test-rule" , sess1 . GroupID , "re-balance" )
177
193
178
194
// The third DB is for the same rule but a different group. It is
179
195
// for the same feature as db 2.
180
- rulesDB3 := db .GetKVStores ("test-rule" , groupID2 , "re-balance" )
196
+ rulesDB3 := db .GetKVStores ("test-rule" , sess2 . GroupID , "re-balance" )
181
197
182
198
// Test that the three ruleDBs share the same global space.
183
- err : = rulesDB1 .Update (ctx , func (ctx context.Context ,
199
+ err = rulesDB1 .Update (ctx , func (ctx context.Context ,
184
200
tx KVStoreTx ) error {
185
201
186
202
return tx .Global ().Set (
@@ -311,9 +327,9 @@ func TestKVStoreNameSpaces(t *testing.T) {
311
327
// Test that the group space is shared by the first two dbs but not
312
328
// the third. To do this, we re-init the DB's but leave the feature
313
329
// names out. This way, we will access the group storage.
314
- rulesDB1 = db .GetKVStores ("test-rule" , groupID1 , "" )
315
- rulesDB2 = db .GetKVStores ("test-rule" , groupID1 , "" )
316
- rulesDB3 = db .GetKVStores ("test-rule" , groupID2 , "" )
330
+ rulesDB1 = db .GetKVStores ("test-rule" , sess1 . GroupID , "" )
331
+ rulesDB2 = db .GetKVStores ("test-rule" , sess1 . GroupID , "" )
332
+ rulesDB3 = db .GetKVStores ("test-rule" , sess2 . GroupID , "" )
317
333
318
334
err = rulesDB1 .Update (ctx , func (ctx context.Context ,
319
335
tx KVStoreTx ) error {
@@ -376,6 +392,81 @@ func TestKVStoreNameSpaces(t *testing.T) {
376
392
require .True (t , bytes .Equal (v , []byte ("thing 3" )))
377
393
}
378
394
395
+ // TestKVStoreSessionCoupling tests if we attempt to write to a kvstore that
396
+ // is namespaced by a session that does not exist, then we should get an error.
397
+ func TestKVStoreSessionCoupling (t * testing.T ) {
398
+ t .Parallel ()
399
+ ctx := context .Background ()
400
+
401
+ sessions := session .NewTestDB (t , clock .NewDefaultClock ())
402
+ db := NewTestDBWithSessions (t , sessions )
403
+
404
+ // Get a kvstore namespaced by a session ID for a session that does
405
+ // not exist.
406
+ store := db .GetKVStores ("AutoFees" , [4 ]byte {1 , 1 , 1 , 1 }, "auto-fees" )
407
+
408
+ err := store .Update (ctx , func (ctx context.Context ,
409
+ tx KVStoreTx ) error {
410
+
411
+ // First, show that any call to the global namespace will not
412
+ // error since it is not namespaced by a session.
413
+ res , err := tx .Global ().Get (ctx , "foo" )
414
+ require .NoError (t , err )
415
+ require .Nil (t , res )
416
+
417
+ err = tx .Global ().Set (ctx , "foo" , []byte ("bar" ))
418
+ require .NoError (t , err )
419
+
420
+ res , err = tx .Global ().Get (ctx , "foo" )
421
+ require .NoError (t , err )
422
+ require .Equal (t , []byte ("bar" ), res )
423
+
424
+ // Now we switch to the local store. We don't expect the Get
425
+ // call to error since it should just return a nil value for
426
+ // key that has not been set.
427
+ _ , err = tx .Local ().Get (ctx , "foo" )
428
+ require .NoError (t , err )
429
+
430
+ // For Set, we expect an error since the session does not exist.
431
+ err = tx .Local ().Set (ctx , "foo" , []byte ("bar" ))
432
+ require .ErrorIs (t , err , session .ErrUnknownGroup )
433
+
434
+ // We again don't expect the error for delete since we just
435
+ // expect it to return nil if the key is not found.
436
+ err = tx .Local ().Del (ctx , "foo" )
437
+ require .NoError (t , err )
438
+
439
+ return nil
440
+ })
441
+ require .NoError (t , err )
442
+
443
+ // Now, go and create a sessions in the session DB.
444
+ sess , err := sessions .NewSession (
445
+ ctx , "test" , session .TypeAutopilot , time .Unix (1000 , 0 ),
446
+ "something" ,
447
+ )
448
+ require .NoError (t , err )
449
+
450
+ // Get a kvstore namespaced by a session ID for a session that now
451
+ // does exist.
452
+ store = db .GetKVStores ("AutoFees" , sess .GroupID , "auto-fees" )
453
+
454
+ // Now, repeat the "Set" call for this session's kvstore to
455
+ // show that it no longer errors.
456
+ err = store .Update (ctx , func (ctx context.Context , tx KVStoreTx ) error {
457
+ // For Set, we expect an error since the session does not exist.
458
+ err = tx .Local ().Set (ctx , "foo" , []byte ("bar" ))
459
+ require .NoError (t , err )
460
+
461
+ res , err := tx .Local ().Get (ctx , "foo" )
462
+ require .NoError (t , err )
463
+ require .Equal (t , []byte ("bar" ), res )
464
+
465
+ return nil
466
+ })
467
+ require .NoError (t , err )
468
+ }
469
+
379
470
func intToSessionID (i uint32 ) session.ID {
380
471
var id session.ID
381
472
byteOrder .PutUint32 (id [:], i )
0 commit comments