@@ -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+ // CreateSession is called.
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
@@ -275,6 +276,46 @@ func (db *BoltStore) CreateSession(session *Session) error {
275276
276277 return putSession (sessionBucket , session )
277278 })
279+ if err != nil {
280+ return nil , err
281+ }
282+
283+ return session , nil
284+ }
285+
286+ // CreateSession moves the session with the given ID from the Reserved state to
287+ // the Created state.
288+ //
289+ // NOTE: this is part of the Store interface.
290+ func (db * BoltStore ) CreateSession (id ID ) (* Session , error ) {
291+ var session * Session
292+ err := db .Update (func (tx * bbolt.Tx ) error {
293+ sessionBucket , err := getBucket (tx , sessionBucketKey )
294+ if err != nil {
295+ return err
296+ }
297+
298+ session , err = getSessionByID (sessionBucket , id )
299+ if err != nil {
300+ return err
301+ }
302+
303+ // The session MUST be in the Reserved state.
304+ if session .State != StateReserved {
305+ return fmt .Errorf ("session must be in the Reserved " +
306+ "state for it to move to the Created state" )
307+ }
308+
309+ // Move the session to the CreatedState.
310+ session .State = StateCreated
311+
312+ return putSession (sessionBucket , session )
313+ })
314+ if err != nil {
315+ return nil , err
316+ }
317+
318+ return session , nil
278319}
279320
280321// UpdateSessionRemotePubKey can be used to add the given remote pub key
@@ -565,53 +606,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
565606 return session , nil
566607}
567608
568- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
609+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
569610// key and session ID pair. Care must be taken to ensure that no other thread
570611// calls this before the returned ID and key pair from this method are either
571612// used or discarded.
572- //
573- // NOTE: this is part of the Store interface.
574- func (db * BoltStore ) GetUnusedIDAndKeyPair () (ID , * btcec.PrivateKey , error ) {
575- var (
576- id ID
577- privKey * btcec.PrivateKey
578- )
579- err := db .Update (func (tx * bbolt.Tx ) error {
580- sessionBucket , err := getBucket (tx , sessionBucketKey )
581- if err != nil {
582- return err
583- }
584-
585- idIndexBkt := sessionBucket .Bucket (idIndexKey )
586- if idIndexBkt == nil {
587- return ErrDBInitErr
588- }
613+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
614+ error ) {
589615
590- // Spin until we find a key with an ID that does not collide
591- // with any of our existing IDs.
592- for {
593- // Generate a new private key and ID pair.
594- privKey , id , err = NewSessionPrivKeyAndID ()
595- if err != nil {
596- return err
597- }
616+ idIndexBkt := bucket .Bucket (idIndexKey )
617+ if idIndexBkt == nil {
618+ return ID {}, nil , ErrDBInitErr
619+ }
598620
599- // Check that no such ID exits in our id-to-key index.
600- idBkt := idIndexBkt .Bucket (id [:])
601- if idBkt != nil {
602- continue
603- }
621+ // Spin until we find a key with an ID that does not collide with any of
622+ // our existing IDs.
623+ for {
624+ // Generate a new private key and ID pair.
625+ privKey , id , err := NewSessionPrivKeyAndID ()
626+ if err != nil {
627+ return ID {}, nil , err
628+ }
604629
605- break
630+ // Check that no such ID exits in our id-to-key index.
631+ idBkt := idIndexBkt .Bucket (id [:])
632+ if idBkt != nil {
633+ continue
606634 }
607635
608- return nil
609- })
610- if err != nil {
611- return id , nil , err
636+ return id , privKey , nil
612637 }
613-
614- return id , privKey , nil
615638}
616639
617640// GetGroupID will return the group ID for the given session ID.
0 commit comments