@@ -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
@@ -558,53 +596,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
558596 return session , nil
559597}
560598
561- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
599+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
562600// key and session ID pair. Care must be taken to ensure that no other thread
563601// calls this before the returned ID and key pair from this method are either
564602// used or discarded.
565- //
566- // NOTE: this is part of the Store interface.
567- func (db * BoltStore ) GetUnusedIDAndKeyPair () (ID , * btcec.PrivateKey , error ) {
568- var (
569- id ID
570- privKey * btcec.PrivateKey
571- )
572- err := db .Update (func (tx * bbolt.Tx ) error {
573- sessionBucket , err := getBucket (tx , sessionBucketKey )
574- if err != nil {
575- return err
576- }
577-
578- idIndexBkt := sessionBucket .Bucket (idIndexKey )
579- if idIndexBkt == nil {
580- return ErrDBInitErr
581- }
603+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
604+ error ) {
582605
583- // Spin until we find a key with an ID that does not collide
584- // with any of our existing IDs.
585- for {
586- // Generate a new private key and ID pair.
587- privKey , id , err = NewSessionPrivKeyAndID ()
588- if err != nil {
589- return err
590- }
606+ idIndexBkt := bucket .Bucket (idIndexKey )
607+ if idIndexBkt == nil {
608+ return ID {}, nil , ErrDBInitErr
609+ }
591610
592- // Check that no such ID exits in our id-to-key index.
593- idBkt := idIndexBkt .Bucket (id [:])
594- if idBkt != nil {
595- continue
596- }
611+ // Spin until we find a key with an ID that does not collide with any of
612+ // our existing IDs.
613+ for {
614+ // Generate a new private key and ID pair.
615+ privKey , id , err := NewSessionPrivKeyAndID ()
616+ if err != nil {
617+ return ID {}, nil , err
618+ }
597619
598- break
620+ // Check that no such ID exits in our id-to-key index.
621+ idBkt := idIndexBkt .Bucket (id [:])
622+ if idBkt != nil {
623+ continue
599624 }
600625
601- return nil
602- })
603- if err != nil {
604- return id , nil , err
626+ return id , privKey , nil
605627 }
606-
607- return id , privKey , nil
608628}
609629
610630// GetGroupID will return the group ID for the given session ID.
0 commit comments