diff --git a/loopdb/store.go b/loopdb/store.go index e075495..f9644e8 100644 --- a/loopdb/store.go +++ b/loopdb/store.go @@ -276,36 +276,54 @@ func (s *boltSwapStore) FetchLoopInSwaps() ([]*LoopIn, error) { return swaps, nil } -// createLoop creates a swap in the store. It requires that the contract is -// already serialized to be able to use this function for both in and out swaps. -func (s *boltSwapStore) createLoop(bucketKey []byte, hash lntypes.Hash, - contractBytes []byte) error { +// createLoopBucket creates the bucket for a particular swap. +func createLoopBucket(tx *bbolt.Tx, swapTypeKey []byte, hash lntypes.Hash) ( + *bbolt.Bucket, error) { + + // First, we'll grab the root bucket that houses all of our + // swaps of this type. + swapTypeBucket, err := tx.CreateBucketIfNotExists(swapTypeKey) + if err != nil { + return nil, err + } + + // If the swap already exists, then we'll exit as we don't want + // to override a swap. + if swapTypeBucket.Get(hash[:]) != nil { + return nil, fmt.Errorf("swap %v already exists", hash) + } + + // From the swap type bucket, we'll make a new sub swap bucket using the + // swap hash to store the individual swap. + return swapTypeBucket.CreateBucket(hash[:]) +} + +// CreateLoopOut adds an initiated swap to the store. +// +// NOTE: Part of the loopdb.SwapStore interface. +func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash, + swap *LoopOutContract) error { + + // If the hash doesn't match the pre-image, then this is an invalid + // swap so we'll bail out early. + if hash != swap.Preimage.Hash() { + return errors.New("hash and preimage do not match") + } // Otherwise, we'll create a new swap within the database. return s.db.Update(func(tx *bbolt.Tx) error { - // First, we'll grab the root bucket that houses all of our - // main swaps. - rootBucket, err := tx.CreateBucketIfNotExists( - bucketKey, - ) + // Create the swap bucket. + swapBucket, err := createLoopBucket(tx, loopOutBucketKey, hash) if err != nil { return err } - // If the swap already exists, then we'll exit as we don't want - // to override a swap. - if rootBucket.Get(hash[:]) != nil { - return fmt.Errorf("swap %v already exists", hash) - } - - // From the root bucket, we'll make a new sub swap bucket using - // the swap hash. - swapBucket, err := rootBucket.CreateBucket(hash[:]) + // With the swap bucket created, we'll store the swap itself. + contractBytes, err := serializeLoopOutContract(swap) if err != nil { return err } - // With the swap bucket created, we'll store the swap itself. err = swapBucket.Put(contractKey, contractBytes) if err != nil { return err @@ -318,26 +336,6 @@ func (s *boltSwapStore) createLoop(bucketKey []byte, hash lntypes.Hash, }) } -// CreateLoopOut adds an initiated swap to the store. -// -// NOTE: Part of the loopdb.SwapStore interface. -func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash, - swap *LoopOutContract) error { - - // If the hash doesn't match the pre-image, then this is an invalid - // swap so we'll bail out early. - if hash != swap.Preimage.Hash() { - return errors.New("hash and preimage do not match") - } - - contractBytes, err := serializeLoopOutContract(swap) - if err != nil { - return err - } - - return s.createLoop(loopOutBucketKey, hash, contractBytes) -} - // CreateLoopIn adds an initiated swap to the store. // // NOTE: Part of the loopdb.SwapStore interface. @@ -350,12 +348,30 @@ func (s *boltSwapStore) CreateLoopIn(hash lntypes.Hash, return errors.New("hash and preimage do not match") } - contractBytes, err := serializeLoopInContract(swap) - if err != nil { - return err - } + // Otherwise, we'll create a new swap within the database. + return s.db.Update(func(tx *bbolt.Tx) error { + // Create the swap bucket. + swapBucket, err := createLoopBucket(tx, loopInBucketKey, hash) + if err != nil { + return err + } + + // With the swap bucket created, we'll store the swap itself. + contractBytes, err := serializeLoopInContract(swap) + if err != nil { + return err + } + + err = swapBucket.Put(contractKey, contractBytes) + if err != nil { + return err + } - return s.createLoop(loopInBucketKey, hash, contractBytes) + // Finally, we'll create an empty updates bucket for this swap + // to track any future updates to the swap itself. + _, err = swapBucket.CreateBucket(updatesBucketKey) + return err + }) } // updateLoop saves a new swap state transition to the store. It takes in a