Skip to content

Commit 6717d9d

Browse files
committed
session+lnrpc: add StateReserved and delete these on start up
1 parent 68ae704 commit 6717d9d

File tree

11 files changed

+210
-33
lines changed

11 files changed

+210
-33
lines changed

app/src/types/generated/lit-sessions_pb.d.ts

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/types/generated/lit-sessions_pb.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

litrpc/lit-autopilot.swagger.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,8 @@
662662
"STATE_CREATED",
663663
"STATE_IN_USE",
664664
"STATE_REVOKED",
665-
"STATE_EXPIRED"
665+
"STATE_EXPIRED",
666+
"STATE_RESERVED"
666667
],
667668
"default": "STATE_CREATED"
668669
},

litrpc/lit-sessions.pb.go

Lines changed: 33 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

litrpc/lit-sessions.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ enum SessionState {
9797
STATE_IN_USE = 1;
9898
STATE_REVOKED = 2;
9999
STATE_EXPIRED = 3;
100+
STATE_RESERVED = 4;
100101
}
101102

102103
message AddSessionResponse {

litrpc/lit-sessions.swagger.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@
521521
"STATE_CREATED",
522522
"STATE_IN_USE",
523523
"STATE_REVOKED",
524-
"STATE_EXPIRED"
524+
"STATE_EXPIRED",
525+
"STATE_RESERVED"
525526
],
526527
"default": "STATE_CREATED"
527528
},

proto/lit-sessions.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ enum SessionState {
9797
STATE_IN_USE = 1;
9898
STATE_REVOKED = 2;
9999
STATE_EXPIRED = 3;
100+
STATE_RESERVED = 4;
100101
}
101102

102103
message AddSessionResponse {

session/interface.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ const (
5151
// StateExpired is the state of a session that has passed its expiry
5252
// date.
5353
StateExpired State = 3
54+
55+
// StateReserved is a temporary initial state of a session. On start-up,
56+
// any sessions in this state should be cleaned up.
57+
//
58+
// NOTE: this isn't used yet.
59+
StateReserved State = 4
5460
)
5561

5662
// MacaroonRecipe defines the permissions and caveats that should be used
@@ -215,5 +221,9 @@ type Store interface {
215221
CheckSessionGroupPredicate(groupID ID,
216222
fn func(s *Session) bool) (bool, error)
217223

224+
// DeleteReservedSessions deletes all sessions that are in the
225+
// StateReserved state.
226+
DeleteReservedSessions() error
227+
218228
IDToGroupIndex
219229
}

session/kvdb_store.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,99 @@ func (db *BoltStore) listSessions(filterFn func(s *Session) bool) ([]*Session,
444444
return sessions, nil
445445
}
446446

447+
// DeleteReservedSessions deletes all sessions that are in the StateReserved
448+
// state.
449+
//
450+
// NOTE: this is part of the Store interface.
451+
func (db *BoltStore) DeleteReservedSessions() error {
452+
return db.Update(func(tx *bbolt.Tx) error {
453+
sessionBucket, err := getBucket(tx, sessionBucketKey)
454+
if err != nil {
455+
return err
456+
}
457+
458+
return sessionBucket.ForEach(func(k, v []byte) error {
459+
// We'll also get buckets here, skip those (identified
460+
// by nil value).
461+
if v == nil {
462+
return nil
463+
}
464+
465+
session, err := DeserializeSession(bytes.NewReader(v))
466+
if err != nil {
467+
return err
468+
}
469+
470+
if session.State != StateReserved {
471+
return nil
472+
}
473+
474+
err = sessionBucket.Delete(k)
475+
if err != nil {
476+
return err
477+
}
478+
479+
idIndexBkt := sessionBucket.Bucket(idIndexKey)
480+
if idIndexBkt == nil {
481+
return ErrDBInitErr
482+
}
483+
484+
// Delete the entire session ID bucket.
485+
err = idIndexBkt.DeleteBucket(session.ID[:])
486+
if err != nil {
487+
return err
488+
}
489+
490+
groupIdIndexBkt := sessionBucket.Bucket(groupIDIndexKey)
491+
if groupIdIndexBkt == nil {
492+
return ErrDBInitErr
493+
}
494+
495+
groupBkt := groupIdIndexBkt.Bucket(session.GroupID[:])
496+
if groupBkt == nil {
497+
return ErrDBInitErr
498+
}
499+
500+
sessionIDsBkt := groupBkt.Bucket(sessionIDKey)
501+
if sessionIDsBkt == nil {
502+
return ErrDBInitErr
503+
}
504+
505+
var (
506+
seqKey []byte
507+
numSessions int
508+
)
509+
err = sessionIDsBkt.ForEach(func(k, v []byte) error {
510+
numSessions++
511+
512+
if !bytes.Equal(v, session.ID[:]) {
513+
return nil
514+
}
515+
516+
seqKey = k
517+
518+
return nil
519+
})
520+
if err != nil {
521+
return err
522+
}
523+
524+
if numSessions == 0 {
525+
return fmt.Errorf("no sessions found for "+
526+
"group ID %x", session.GroupID)
527+
}
528+
529+
if numSessions == 1 {
530+
// Delete the whole group bucket.
531+
return groupBkt.DeleteBucket(sessionIDKey)
532+
}
533+
534+
// Else, delete just the session ID entry.
535+
return sessionIDsBkt.Delete(seqKey)
536+
})
537+
})
538+
}
539+
447540
// RevokeSession updates the state of the session with the given local
448541
// public key to be revoked.
449542
//

session/store_test.go

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,58 @@ func TestBasicSessionStore(t *testing.T) {
142142
require.NoError(t, err)
143143
require.Empty(t, sessions)
144144

145-
sessions, err = db.ListSessionsByState(StateInUse)
145+
sessions, err = db.ListSessionsByState(StateReserved)
146146
require.NoError(t, err)
147147
require.Empty(t, sessions)
148+
149+
// Demonstrate deletion of a reserved session.
150+
//
151+
// Calling DeleteReservedSessions should have no effect yet since none
152+
// of the sessions are reserved.
153+
require.NoError(t, db.DeleteReservedSessions())
154+
155+
sessions, err = db.ListSessionsByState(StateReserved)
156+
require.NoError(t, err)
157+
require.Empty(t, sessions)
158+
159+
// Add a session and put it in the StateReserved state. We'll also
160+
// link it to session 1.
161+
s5 := newSession(
162+
t, db, clock, "session 5", withState(StateReserved),
163+
withLinkedGroupID(&session1.GroupID),
164+
)
165+
require.NoError(t, db.CreateSession(s5))
166+
167+
sessions, err = db.ListSessionsByState(StateReserved)
168+
require.NoError(t, err)
169+
require.Equal(t, 1, len(sessions))
170+
assertEqualSessions(t, s5, sessions[0])
171+
172+
// Show that the group ID/session ID index has also been populated with
173+
// this session.
174+
groupID, err := db.GetGroupID(s5.ID)
175+
require.NoError(t, err)
176+
require.Equal(t, s1.ID, groupID)
177+
178+
sessIDs, err := db.GetSessionIDs(s5.GroupID)
179+
require.NoError(t, err)
180+
require.ElementsMatch(t, []ID{s5.ID, s1.ID}, sessIDs)
181+
182+
// Now delete the reserved session and show that it is no longer in the
183+
// database and no longer in the group ID/session ID index.
184+
require.NoError(t, db.DeleteReservedSessions())
185+
186+
sessions, err = db.ListSessionsByState(StateReserved)
187+
require.NoError(t, err)
188+
require.Empty(t, sessions)
189+
190+
_, err = db.GetGroupID(s5.ID)
191+
require.ErrorContains(t, err, "no index entry")
192+
193+
// Only session 1 should remain in this group.
194+
sessIDs, err = db.GetSessionIDs(s5.GroupID)
195+
require.NoError(t, err)
196+
require.ElementsMatch(t, []ID{s1.ID}, sessIDs)
148197
}
149198

150199
// TestLinkingSessions tests that session linking works as expected.
@@ -359,6 +408,12 @@ func withType(t Type) testSessionModifier {
359408
}
360409
}
361410

411+
func withState(state State) testSessionModifier {
412+
return func(s *Session) {
413+
s.State = state
414+
}
415+
}
416+
362417
func newSession(t *testing.T, db Store, clock clock.Clock, label string,
363418
mods ...testSessionModifier) *Session {
364419

0 commit comments

Comments
 (0)