@@ -182,41 +182,42 @@ func getSessionKey(session *Session) []byte {
182182 return session .LocalPublicKey .SerializeCompressed ()
183183}
184184
185- // NewSession creates a new session with the given user-defined parameters.
186- //
187- // NOTE: currently this purely a constructor of the Session type and does not
188- // make any database calls. This will be changed in a future commit.
189- //
190- // NOTE: this is part of the Store interface.
191- func (db * BoltStore ) NewSession (id ID , localPrivKey * btcec.PrivateKey ,
192- label string , typ Type , expiry time.Time , serverAddr string ,
193- devServer bool , perms []bakery.Op , caveats []macaroon.Caveat ,
194- featureConfig FeaturesConfig , privacy bool , linkedGroupID * ID ,
195- flags PrivacyFlags ) (* Session , error ) {
196-
197- return buildSession (
198- id , localPrivKey , label , typ , db .clock .Now (), expiry ,
199- serverAddr , devServer , perms , caveats , featureConfig , privacy ,
200- linkedGroupID , flags ,
201- )
202- }
203-
204- // CreateSession adds a new session to the store. If a session with the same
205- // local public key already exists an error is returned.
185+ // NewSession creates and persists a new session with the given user-defined
186+ // parameters. The initial state of the session will be Reserved until
187+ // ShiftState is called with StateCreated.
206188//
207189// NOTE: this is part of the Store interface.
208- func (db * BoltStore ) CreateSession (session * Session ) error {
209- sessionKey := getSessionKey (session )
190+ func (db * BoltStore ) NewSession (label string , typ Type , expiry time.Time ,
191+ serverAddr string , devServer bool , perms []bakery.Op ,
192+ caveats []macaroon.Caveat , featureConfig FeaturesConfig , privacy bool ,
193+ linkedGroupID * ID , flags PrivacyFlags ) (* Session , error ) {
210194
211- return db .Update (func (tx * bbolt.Tx ) error {
195+ var session * Session
196+ err := db .Update (func (tx * bbolt.Tx ) error {
212197 sessionBucket , err := getBucket (tx , sessionBucketKey )
213198 if err != nil {
214199 return err
215200 }
216201
202+ id , localPrivKey , err := getUnusedIDAndKeyPair (sessionBucket )
203+ if err != nil {
204+ return err
205+ }
206+
207+ session , err = buildSession (
208+ id , localPrivKey , label , typ , db .clock .Now (), expiry ,
209+ serverAddr , devServer , perms , caveats , featureConfig ,
210+ privacy , linkedGroupID , flags ,
211+ )
212+ if err != nil {
213+ return err
214+ }
215+
216+ sessionKey := getSessionKey (session )
217+
217218 if len (sessionBucket .Get (sessionKey )) != 0 {
218- return fmt .Errorf ("session with local public " +
219- "key(%x) already exists" ,
219+ return fmt .Errorf ("session with local public key(%x) " +
220+ "already exists" ,
220221 session .LocalPublicKey .SerializeCompressed ())
221222 }
222223
@@ -248,9 +249,7 @@ func (db *BoltStore) CreateSession(session *Session) error {
248249 }
249250
250251 // Ensure that the session is no longer active.
251- if sess .State == StateCreated ||
252- sess .State == StateInUse {
253-
252+ if ! sess .State .Terminal () {
254253 return fmt .Errorf ("session (id=%x) " +
255254 "in group %x is still active" ,
256255 sess .ID , sess .GroupID )
@@ -275,6 +274,11 @@ func (db *BoltStore) CreateSession(session *Session) error {
275274
276275 return putSession (sessionBucket , session )
277276 })
277+ if err != nil {
278+ return nil , err
279+ }
280+
281+ return session , nil
278282}
279283
280284// UpdateSessionRemotePubKey can be used to add the given remote pub key
@@ -577,53 +581,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
577581 return session , nil
578582}
579583
580- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
584+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
581585// key and session ID pair. Care must be taken to ensure that no other thread
582586// calls this before the returned ID and key pair from this method are either
583587// used or discarded.
584- //
585- // NOTE: this is part of the Store interface.
586- func (db * BoltStore ) GetUnusedIDAndKeyPair () (ID , * btcec.PrivateKey , error ) {
587- var (
588- id ID
589- privKey * btcec.PrivateKey
590- )
591- err := db .Update (func (tx * bbolt.Tx ) error {
592- sessionBucket , err := getBucket (tx , sessionBucketKey )
593- if err != nil {
594- return err
595- }
596-
597- idIndexBkt := sessionBucket .Bucket (idIndexKey )
598- if idIndexBkt == nil {
599- return ErrDBInitErr
600- }
588+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
589+ error ) {
601590
602- // Spin until we find a key with an ID that does not collide
603- // with any of our existing IDs.
604- for {
605- // Generate a new private key and ID pair.
606- privKey , id , err = NewSessionPrivKeyAndID ()
607- if err != nil {
608- return err
609- }
591+ idIndexBkt := bucket .Bucket (idIndexKey )
592+ if idIndexBkt == nil {
593+ return ID {}, nil , ErrDBInitErr
594+ }
610595
611- // Check that no such ID exits in our id-to-key index.
612- idBkt := idIndexBkt .Bucket (id [:])
613- if idBkt != nil {
614- continue
615- }
596+ // Spin until we find a key with an ID that does not collide with any of
597+ // our existing IDs.
598+ for {
599+ // Generate a new private key and ID pair.
600+ privKey , id , err := NewSessionPrivKeyAndID ()
601+ if err != nil {
602+ return ID {}, nil , err
603+ }
616604
617- break
605+ // Check that no such ID exits in our id-to-key index.
606+ idBkt := idIndexBkt .Bucket (id [:])
607+ if idBkt != nil {
608+ continue
618609 }
619610
620- return nil
621- })
622- if err != nil {
623- return id , nil , err
611+ return id , privKey , nil
624612 }
625-
626- return id , privKey , nil
627613}
628614
629615// GetGroupID will return the group ID for the given session ID.
@@ -691,65 +677,6 @@ func (db *BoltStore) GetSessionIDs(groupID ID) ([]ID, error) {
691677 return sessionIDs , nil
692678}
693679
694- // CheckSessionGroupPredicate iterates over all the sessions in a group and
695- // checks if each one passes the given predicate function. True is returned if
696- // each session passes.
697- //
698- // NOTE: this is part of the Store interface.
699- func (db * BoltStore ) CheckSessionGroupPredicate (groupID ID ,
700- fn func (s * Session ) bool ) (bool , error ) {
701-
702- var (
703- pass bool
704- errFailedPred = errors .New ("session failed predicate" )
705- )
706- err := db .View (func (tx * bbolt.Tx ) error {
707- sessionBkt , err := getBucket (tx , sessionBucketKey )
708- if err != nil {
709- return err
710- }
711-
712- sessionIDs , err := getSessionIDs (sessionBkt , groupID )
713- if err != nil {
714- return err
715- }
716-
717- // Iterate over all the sessions.
718- for _ , id := range sessionIDs {
719- key , err := getKeyForID (sessionBkt , id )
720- if err != nil {
721- return err
722- }
723-
724- v := sessionBkt .Get (key )
725- if len (v ) == 0 {
726- return ErrSessionNotFound
727- }
728-
729- session , err := DeserializeSession (bytes .NewReader (v ))
730- if err != nil {
731- return err
732- }
733-
734- if ! fn (session ) {
735- return errFailedPred
736- }
737- }
738-
739- pass = true
740-
741- return nil
742- })
743- if errors .Is (err , errFailedPred ) {
744- return pass , nil
745- }
746- if err != nil {
747- return pass , err
748- }
749-
750- return pass , nil
751- }
752-
753680// getSessionIDs returns all the session IDs associated with the given group ID.
754681func getSessionIDs (sessionBkt * bbolt.Bucket , groupID ID ) ([]ID , error ) {
755682 var sessionIDs []ID
0 commit comments