mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
session+lnrpc: add StateReserved and delete these on start up
This commit is contained in:
parent
68ae704229
commit
6717d9d54b
11 changed files with 210 additions and 33 deletions
1
app/src/types/generated/lit-sessions_pb.d.ts
generated
vendored
1
app/src/types/generated/lit-sessions_pb.d.ts
generated
vendored
|
|
@ -688,6 +688,7 @@ export interface SessionStateMap {
|
|||
STATE_IN_USE: 1;
|
||||
STATE_REVOKED: 2;
|
||||
STATE_EXPIRED: 3;
|
||||
STATE_RESERVED: 4;
|
||||
}
|
||||
|
||||
export const SessionState: SessionStateMap;
|
||||
|
|
|
|||
3
app/src/types/generated/lit-sessions_pb.js
generated
3
app/src/types/generated/lit-sessions_pb.js
generated
|
|
@ -5276,7 +5276,8 @@ proto.litrpc.SessionState = {
|
|||
STATE_CREATED: 0,
|
||||
STATE_IN_USE: 1,
|
||||
STATE_REVOKED: 2,
|
||||
STATE_EXPIRED: 3
|
||||
STATE_EXPIRED: 3,
|
||||
STATE_RESERVED: 4
|
||||
};
|
||||
|
||||
goog.object.extend(exports, proto.litrpc);
|
||||
|
|
|
|||
|
|
@ -662,7 +662,8 @@
|
|||
"STATE_CREATED",
|
||||
"STATE_IN_USE",
|
||||
"STATE_REVOKED",
|
||||
"STATE_EXPIRED"
|
||||
"STATE_EXPIRED",
|
||||
"STATE_RESERVED"
|
||||
],
|
||||
"default": "STATE_CREATED"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -81,10 +81,11 @@ func (SessionType) EnumDescriptor() ([]byte, []int) {
|
|||
type SessionState int32
|
||||
|
||||
const (
|
||||
SessionState_STATE_CREATED SessionState = 0
|
||||
SessionState_STATE_IN_USE SessionState = 1
|
||||
SessionState_STATE_REVOKED SessionState = 2
|
||||
SessionState_STATE_EXPIRED SessionState = 3
|
||||
SessionState_STATE_CREATED SessionState = 0
|
||||
SessionState_STATE_IN_USE SessionState = 1
|
||||
SessionState_STATE_REVOKED SessionState = 2
|
||||
SessionState_STATE_EXPIRED SessionState = 3
|
||||
SessionState_STATE_RESERVED SessionState = 4
|
||||
)
|
||||
|
||||
// Enum value maps for SessionState.
|
||||
|
|
@ -94,12 +95,14 @@ var (
|
|||
1: "STATE_IN_USE",
|
||||
2: "STATE_REVOKED",
|
||||
3: "STATE_EXPIRED",
|
||||
4: "STATE_RESERVED",
|
||||
}
|
||||
SessionState_value = map[string]int32{
|
||||
"STATE_CREATED": 0,
|
||||
"STATE_IN_USE": 1,
|
||||
"STATE_REVOKED": 2,
|
||||
"STATE_EXPIRED": 3,
|
||||
"STATE_CREATED": 0,
|
||||
"STATE_IN_USE": 1,
|
||||
"STATE_REVOKED": 2,
|
||||
"STATE_EXPIRED": 3,
|
||||
"STATE_RESERVED": 4,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -1897,31 +1900,32 @@ var file_lit_sessions_proto_rawDesc = []byte{
|
|||
0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x50, 0x49, 0x4c,
|
||||
0x4f, 0x54, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43,
|
||||
0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x05, 0x2a,
|
||||
0x59, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
|
||||
0x6d, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
|
||||
0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44,
|
||||
0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x55,
|
||||
0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45,
|
||||
0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45,
|
||||
0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x32, 0xe8, 0x01, 0x0a, 0x08, 0x53,
|
||||
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41,
|
||||
0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x6c,
|
||||
0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b,
|
||||
0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62,
|
||||
0x73, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54,
|
||||
0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x45, 0x44, 0x10, 0x04, 0x32, 0xe8,
|
||||
0x01, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x41,
|
||||
0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x74, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64,
|
||||
0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x49, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x12, 0x1b, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e,
|
||||
0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x52,
|
||||
0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6c,
|
||||
0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x74,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2d,
|
||||
0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ enum SessionState {
|
|||
STATE_IN_USE = 1;
|
||||
STATE_REVOKED = 2;
|
||||
STATE_EXPIRED = 3;
|
||||
STATE_RESERVED = 4;
|
||||
}
|
||||
|
||||
message AddSessionResponse {
|
||||
|
|
|
|||
|
|
@ -521,7 +521,8 @@
|
|||
"STATE_CREATED",
|
||||
"STATE_IN_USE",
|
||||
"STATE_REVOKED",
|
||||
"STATE_EXPIRED"
|
||||
"STATE_EXPIRED",
|
||||
"STATE_RESERVED"
|
||||
],
|
||||
"default": "STATE_CREATED"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ enum SessionState {
|
|||
STATE_IN_USE = 1;
|
||||
STATE_REVOKED = 2;
|
||||
STATE_EXPIRED = 3;
|
||||
STATE_RESERVED = 4;
|
||||
}
|
||||
|
||||
message AddSessionResponse {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ const (
|
|||
// StateExpired is the state of a session that has passed its expiry
|
||||
// date.
|
||||
StateExpired State = 3
|
||||
|
||||
// StateReserved is a temporary initial state of a session. On start-up,
|
||||
// any sessions in this state should be cleaned up.
|
||||
//
|
||||
// NOTE: this isn't used yet.
|
||||
StateReserved State = 4
|
||||
)
|
||||
|
||||
// MacaroonRecipe defines the permissions and caveats that should be used
|
||||
|
|
@ -215,5 +221,9 @@ type Store interface {
|
|||
CheckSessionGroupPredicate(groupID ID,
|
||||
fn func(s *Session) bool) (bool, error)
|
||||
|
||||
// DeleteReservedSessions deletes all sessions that are in the
|
||||
// StateReserved state.
|
||||
DeleteReservedSessions() error
|
||||
|
||||
IDToGroupIndex
|
||||
}
|
||||
|
|
|
|||
|
|
@ -444,6 +444,99 @@ func (db *BoltStore) listSessions(filterFn func(s *Session) bool) ([]*Session,
|
|||
return sessions, nil
|
||||
}
|
||||
|
||||
// DeleteReservedSessions deletes all sessions that are in the StateReserved
|
||||
// state.
|
||||
//
|
||||
// NOTE: this is part of the Store interface.
|
||||
func (db *BoltStore) DeleteReservedSessions() error {
|
||||
return db.Update(func(tx *bbolt.Tx) error {
|
||||
sessionBucket, err := getBucket(tx, sessionBucketKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sessionBucket.ForEach(func(k, v []byte) error {
|
||||
// We'll also get buckets here, skip those (identified
|
||||
// by nil value).
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
session, err := DeserializeSession(bytes.NewReader(v))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if session.State != StateReserved {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = sessionBucket.Delete(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
idIndexBkt := sessionBucket.Bucket(idIndexKey)
|
||||
if idIndexBkt == nil {
|
||||
return ErrDBInitErr
|
||||
}
|
||||
|
||||
// Delete the entire session ID bucket.
|
||||
err = idIndexBkt.DeleteBucket(session.ID[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
groupIdIndexBkt := sessionBucket.Bucket(groupIDIndexKey)
|
||||
if groupIdIndexBkt == nil {
|
||||
return ErrDBInitErr
|
||||
}
|
||||
|
||||
groupBkt := groupIdIndexBkt.Bucket(session.GroupID[:])
|
||||
if groupBkt == nil {
|
||||
return ErrDBInitErr
|
||||
}
|
||||
|
||||
sessionIDsBkt := groupBkt.Bucket(sessionIDKey)
|
||||
if sessionIDsBkt == nil {
|
||||
return ErrDBInitErr
|
||||
}
|
||||
|
||||
var (
|
||||
seqKey []byte
|
||||
numSessions int
|
||||
)
|
||||
err = sessionIDsBkt.ForEach(func(k, v []byte) error {
|
||||
numSessions++
|
||||
|
||||
if !bytes.Equal(v, session.ID[:]) {
|
||||
return nil
|
||||
}
|
||||
|
||||
seqKey = k
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if numSessions == 0 {
|
||||
return fmt.Errorf("no sessions found for "+
|
||||
"group ID %x", session.GroupID)
|
||||
}
|
||||
|
||||
if numSessions == 1 {
|
||||
// Delete the whole group bucket.
|
||||
return groupBkt.DeleteBucket(sessionIDKey)
|
||||
}
|
||||
|
||||
// Else, delete just the session ID entry.
|
||||
return sessionIDsBkt.Delete(seqKey)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// RevokeSession updates the state of the session with the given local
|
||||
// public key to be revoked.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -142,9 +142,58 @@ func TestBasicSessionStore(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Empty(t, sessions)
|
||||
|
||||
sessions, err = db.ListSessionsByState(StateInUse)
|
||||
sessions, err = db.ListSessionsByState(StateReserved)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, sessions)
|
||||
|
||||
// Demonstrate deletion of a reserved session.
|
||||
//
|
||||
// Calling DeleteReservedSessions should have no effect yet since none
|
||||
// of the sessions are reserved.
|
||||
require.NoError(t, db.DeleteReservedSessions())
|
||||
|
||||
sessions, err = db.ListSessionsByState(StateReserved)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, sessions)
|
||||
|
||||
// Add a session and put it in the StateReserved state. We'll also
|
||||
// link it to session 1.
|
||||
s5 := newSession(
|
||||
t, db, clock, "session 5", withState(StateReserved),
|
||||
withLinkedGroupID(&session1.GroupID),
|
||||
)
|
||||
require.NoError(t, db.CreateSession(s5))
|
||||
|
||||
sessions, err = db.ListSessionsByState(StateReserved)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(sessions))
|
||||
assertEqualSessions(t, s5, sessions[0])
|
||||
|
||||
// Show that the group ID/session ID index has also been populated with
|
||||
// this session.
|
||||
groupID, err := db.GetGroupID(s5.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, s1.ID, groupID)
|
||||
|
||||
sessIDs, err := db.GetSessionIDs(s5.GroupID)
|
||||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, []ID{s5.ID, s1.ID}, sessIDs)
|
||||
|
||||
// Now delete the reserved session and show that it is no longer in the
|
||||
// database and no longer in the group ID/session ID index.
|
||||
require.NoError(t, db.DeleteReservedSessions())
|
||||
|
||||
sessions, err = db.ListSessionsByState(StateReserved)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, sessions)
|
||||
|
||||
_, err = db.GetGroupID(s5.ID)
|
||||
require.ErrorContains(t, err, "no index entry")
|
||||
|
||||
// Only session 1 should remain in this group.
|
||||
sessIDs, err = db.GetSessionIDs(s5.GroupID)
|
||||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, []ID{s1.ID}, sessIDs)
|
||||
}
|
||||
|
||||
// TestLinkingSessions tests that session linking works as expected.
|
||||
|
|
@ -359,6 +408,12 @@ func withType(t Type) testSessionModifier {
|
|||
}
|
||||
}
|
||||
|
||||
func withState(state State) testSessionModifier {
|
||||
return func(s *Session) {
|
||||
s.State = state
|
||||
}
|
||||
}
|
||||
|
||||
func newSession(t *testing.T, db Store, clock clock.Clock, label string,
|
||||
mods ...testSessionModifier) *Session {
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,12 @@ func newSessionRPCServer(cfg *sessionRpcServerConfig) (*sessionRpcServer,
|
|||
// start all the components necessary for the sessionRpcServer to start serving
|
||||
// requests. This includes resuming all non-revoked sessions.
|
||||
func (s *sessionRpcServer) start(ctx context.Context) error {
|
||||
// Delete all sessions in the Reserved state.
|
||||
err := s.cfg.db.DeleteReservedSessions()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting reserved sessions: %v", err)
|
||||
}
|
||||
|
||||
// Start up all previously created sessions.
|
||||
sessions, err := s.cfg.db.ListSessionsByState(
|
||||
session.StateCreated,
|
||||
|
|
@ -1518,6 +1524,9 @@ func marshalRPCMacaroonRecipe(
|
|||
// marshalRPCState converts a session state to its RPC counterpart.
|
||||
func marshalRPCState(state session.State) (litrpc.SessionState, error) {
|
||||
switch state {
|
||||
case session.StateReserved:
|
||||
return litrpc.SessionState_STATE_RESERVED, nil
|
||||
|
||||
case session.StateCreated:
|
||||
return litrpc.SessionState_STATE_CREATED, nil
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue