@@ -5,8 +5,10 @@ import (
55 "context"
66 "fmt"
77 "testing"
8+ "time"
89
910 "github.com/lightninglabs/lightning-terminal/session"
11+ "github.com/lightningnetwork/lnd/clock"
1012 "github.com/stretchr/testify/require"
1113)
1214
@@ -83,15 +85,21 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
8385 featureName = "auto-fees"
8486 }
8587
86- store := NewTestDB (t )
88+ sessions := session .NewTestDB (t , clock .NewDefaultClock ())
89+ store := NewTestDBWithSessions (t , sessions )
8790 db := NewDB (store )
8891 require .NoError (t , db .Start (ctx ))
8992
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" ,
9297 )
98+ require .NoError (t , err )
99+
100+ kvstores := db .GetKVStores ("test-rule" , sess .GroupID , featureName )
93101
94- err : = kvstores .Update (ctx , func (ctx context.Context ,
102+ err = kvstores .Update (ctx , func (ctx context.Context ,
95103 tx KVStoreTx ) error {
96104
97105 // Set an item in the temp store.
@@ -137,7 +145,7 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
137145 require .NoError (t , db .Stop ())
138146 })
139147
140- kvstores = db .GetKVStores ("test-rule" , [ 4 ] byte { 1 , 1 , 1 , 1 } , featureName )
148+ kvstores = db .GetKVStores ("test-rule" , sess . GroupID , featureName )
141149
142150 // The temp store should no longer have the stored value but the perm
143151 // store should .
@@ -164,23 +172,31 @@ func testTempAndPermStores(t *testing.T, featureSpecificStore bool) {
164172func TestKVStoreNameSpaces (t * testing.T ) {
165173 t .Parallel ()
166174 ctx := context .Background ()
167- db := NewTestDB (t )
168175
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 ), "" ,
172182 )
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 )
173189
174190 // 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" )
177193
178194 // The third DB is for the same rule but a different group. It is
179195 // 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" )
181197
182198 // 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 ,
184200 tx KVStoreTx ) error {
185201
186202 return tx .Global ().Set (
@@ -311,9 +327,9 @@ func TestKVStoreNameSpaces(t *testing.T) {
311327 // Test that the group space is shared by the first two dbs but not
312328 // the third. To do this, we re-init the DB's but leave the feature
313329 // 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 , "" )
317333
318334 err = rulesDB1 .Update (ctx , func (ctx context.Context ,
319335 tx KVStoreTx ) error {
@@ -376,6 +392,81 @@ func TestKVStoreNameSpaces(t *testing.T) {
376392 require .True (t , bytes .Equal (v , []byte ("thing 3" )))
377393}
378394
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+
379470func intToSessionID (i uint32 ) session.ID {
380471 var id session.ID
381472 byteOrder .PutUint32 (id [:], i )
0 commit comments