@@ -182,41 +182,39 @@ 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.
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.
189188//
190189// 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- }
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 ) {
203194
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.
206- //
207- // NOTE: this is part of the Store interface.
208- func (db * BoltStore ) CreateSession (session * Session ) error {
209- sessionKey := getSessionKey (session )
210-
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+
213+ sessionKey := getSessionKey (session )
214+
217215 if len (sessionBucket .Get (sessionKey )) != 0 {
218- return fmt .Errorf ("session with local public " +
219- "key(%x) already exists" ,
216+ return fmt .Errorf ("session with local public key(%x) " +
217+ "already exists" ,
220218 session .LocalPublicKey .SerializeCompressed ())
221219 }
222220
@@ -275,6 +273,46 @@ func (db *BoltStore) CreateSession(session *Session) error {
275273
276274 return putSession (sessionBucket , session )
277275 })
276+ if err != nil {
277+ return nil , err
278+ }
279+
280+ return session , nil
281+ }
282+
283+ // CreateSession moves the session with the given ID from the Reserved state to
284+ // the Created state.
285+ //
286+ // NOTE: this is part of the Store interface.
287+ func (db * BoltStore ) CreateSession (id ID ) (* Session , error ) {
288+ var session * Session
289+ err := db .Update (func (tx * bbolt.Tx ) error {
290+ sessionBucket , err := getBucket (tx , sessionBucketKey )
291+ if err != nil {
292+ return err
293+ }
294+
295+ session , err = getSessionByID (sessionBucket , id )
296+ if err != nil {
297+ return err
298+ }
299+
300+ // The session MUST be in the Reserved state.
301+ if session .State != StateReserved {
302+ return fmt .Errorf ("session must be in the Reserved " +
303+ "state for it to move to the Created state" )
304+ }
305+
306+ // Move the session to the CreatedState.
307+ session .State = StateCreated
308+
309+ return putSession (sessionBucket , session )
310+ })
311+ if err != nil {
312+ return nil , err
313+ }
314+
315+ return session , nil
278316}
279317
280318// UpdateSessionRemotePubKey can be used to add the given remote pub key
@@ -565,53 +603,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
565603 return session , nil
566604}
567605
568- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
606+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
569607// key and session ID pair. Care must be taken to ensure that no other thread
570608// calls this before the returned ID and key pair from this method are either
571609// 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- }
610+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
611+ error ) {
589612
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- }
613+ idIndexBkt := bucket .Bucket (idIndexKey )
614+ if idIndexBkt == nil {
615+ return ID {}, nil , ErrDBInitErr
616+ }
598617
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- }
618+ // Spin until we find a key with an ID that does not collide with any of
619+ // our existing IDs.
620+ for {
621+ // Generate a new private key and ID pair.
622+ privKey , id , err := NewSessionPrivKeyAndID ()
623+ if err != nil {
624+ return ID {}, nil , err
625+ }
604626
605- break
627+ // Check that no such ID exits in our id-to-key index.
628+ idBkt := idIndexBkt .Bucket (id [:])
629+ if idBkt != nil {
630+ continue
606631 }
607632
608- return nil
609- })
610- if err != nil {
611- return id , nil , err
633+ return id , privKey , nil
612634 }
613-
614- return id , privKey , nil
615635}
616636
617637// GetGroupID will return the group ID for the given session ID.
0 commit comments