multi: use context in loopdb call

This commit adds a context to our loopdb interface, which we should use
in the sqlite migration.
This commit is contained in:
sputn1ck 2023-05-16 17:40:52 +02:00
parent 319a519309
commit becc8a38d8
No known key found for this signature in database
GPG key ID: 671103D881A5F0E4
15 changed files with 161 additions and 120 deletions

View file

@ -1,6 +1,7 @@
package loopdb
import (
"context"
"time"
"github.com/lightningnetwork/lnd/lntypes"
@ -10,30 +11,32 @@ import (
// houses information for all pending completed/failed swaps.
type SwapStore interface {
// FetchLoopOutSwaps returns all swaps currently in the store.
FetchLoopOutSwaps() ([]*LoopOut, error)
FetchLoopOutSwaps(ctx context.Context) ([]*LoopOut, error)
// FetchLoopOutSwap returns the loop out swap with the given hash.
FetchLoopOutSwap(hash lntypes.Hash) (*LoopOut, error)
FetchLoopOutSwap(ctx context.Context, hash lntypes.Hash) (*LoopOut, error)
// CreateLoopOut adds an initiated swap to the store.
CreateLoopOut(hash lntypes.Hash, swap *LoopOutContract) error
CreateLoopOut(ctx context.Context, hash lntypes.Hash,
swap *LoopOutContract) error
// UpdateLoopOut stores a new event for a target loop out swap. This
// appends to the event log for a particular swap as it goes through
// the various stages in its lifetime.
UpdateLoopOut(hash lntypes.Hash, time time.Time,
UpdateLoopOut(ctx context.Context, hash lntypes.Hash, time time.Time,
state SwapStateData) error
// FetchLoopInSwaps returns all swaps currently in the store.
FetchLoopInSwaps() ([]*LoopIn, error)
FetchLoopInSwaps(ctx context.Context) ([]*LoopIn, error)
// CreateLoopIn adds an initiated swap to the store.
CreateLoopIn(hash lntypes.Hash, swap *LoopInContract) error
CreateLoopIn(ctx context.Context, hash lntypes.Hash,
swap *LoopInContract) error
// UpdateLoopIn stores a new event for a target loop in swap. This
// appends to the event log for a particular swap as it goes through
// the various stages in its lifetime.
UpdateLoopIn(hash lntypes.Hash, time time.Time,
UpdateLoopIn(ctx context.Context, hash lntypes.Hash, time time.Time,
state SwapStateData) error
// PutLiquidityParams writes the serialized `manager.Parameters` bytes
@ -41,14 +44,14 @@ type SwapStore interface {
//
// NOTE: it's the caller's responsibility to encode the param. Atm,
// it's encoding using the proto package's `Marshal` method.
PutLiquidityParams(params []byte) error
PutLiquidityParams(ctx context.Context, params []byte) error
// FetchLiquidityParams reads the serialized `manager.Parameters` bytes
// from the bucket.
//
// NOTE: it's the caller's responsibility to decode the param. Atm,
// it's decoding using the proto package's `Unmarshal` method.
FetchLiquidityParams() ([]byte, error)
FetchLiquidityParams(ctx context.Context) ([]byte, error)
// Close closes the underlying database.
Close() error

View file

@ -1,6 +1,7 @@
package loopdb
import (
"context"
"io/ioutil"
"os"
"path/filepath"
@ -44,6 +45,8 @@ func TestMigrationUpdates(t *testing.T) {
},
}
ctxb := context.Background()
// Restore a legacy database.
tempDirName, err := ioutil.TempDir("", "clientstore")
require.NoError(t, err)
@ -69,7 +72,7 @@ func TestMigrationUpdates(t *testing.T) {
// Fetch the legacy loop out swap and assert that the updates are still
// there.
outSwaps, err := store.FetchLoopOutSwaps()
outSwaps, err := store.FetchLoopOutSwaps(ctxb)
require.NoError(t, err)
outSwap := outSwaps[0]
@ -78,7 +81,7 @@ func TestMigrationUpdates(t *testing.T) {
// Fetch the legacy loop in swap and assert that the updates are still
// there.
inSwaps, err := store.FetchLoopInSwaps()
inSwaps, err := store.FetchLoopInSwaps(ctxb)
require.NoError(t, err)
inSwap := inSwaps[0]

View file

@ -2,6 +2,7 @@ package loopdb
import (
"bytes"
"context"
"encoding/binary"
"errors"
"fmt"
@ -346,7 +347,9 @@ func unmarshalHtlcKeys(swapBucket *bbolt.Bucket, contract *SwapContract) error {
// FetchLoopOutSwaps returns all loop out swaps currently in the store.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) FetchLoopOutSwaps() ([]*LoopOut, error) {
func (s *boltSwapStore) FetchLoopOutSwaps(ctx context.Context) ([]*LoopOut,
error) {
var swaps []*LoopOut
err := s.db.View(func(tx *bbolt.Tx) error {
@ -385,7 +388,9 @@ func (s *boltSwapStore) FetchLoopOutSwaps() ([]*LoopOut, error) {
// FetchLoopOutSwap returns the loop out swap with the given hash.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) FetchLoopOutSwap(hash lntypes.Hash) (*LoopOut, error) {
func (s *boltSwapStore) FetchLoopOutSwap(ctx context.Context,
hash lntypes.Hash) (*LoopOut, error) {
var swap *LoopOut
err := s.db.View(func(tx *bbolt.Tx) error {
@ -414,7 +419,9 @@ func (s *boltSwapStore) FetchLoopOutSwap(hash lntypes.Hash) (*LoopOut, error) {
// FetchLoopInSwaps returns all loop in swaps currently in the store.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) FetchLoopInSwaps() ([]*LoopIn, error) {
func (s *boltSwapStore) FetchLoopInSwaps(ctx context.Context) ([]*LoopIn,
error) {
var swaps []*LoopIn
err := s.db.View(func(tx *bbolt.Tx) error {
@ -475,7 +482,7 @@ func createLoopBucket(tx *bbolt.Tx, swapTypeKey []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,
func (s *boltSwapStore) CreateLoopOut(ctx context.Context, hash lntypes.Hash,
swap *LoopOutContract) error {
// If the hash doesn't match the pre-image, then this is an invalid
@ -561,7 +568,7 @@ func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash,
// CreateLoopIn adds an initiated swap to the store.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) CreateLoopIn(hash lntypes.Hash,
func (s *boltSwapStore) CreateLoopIn(ctx context.Context, hash lntypes.Hash,
swap *LoopInContract) error {
// If the hash doesn't match the pre-image, then this is an invalid
@ -678,8 +685,8 @@ func (s *boltSwapStore) updateLoop(bucketKey []byte, hash lntypes.Hash,
// a particular swap as it goes through the various stages in its lifetime.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) UpdateLoopOut(hash lntypes.Hash, time time.Time,
state SwapStateData) error {
func (s *boltSwapStore) UpdateLoopOut(ctx context.Context,
hash lntypes.Hash, time time.Time, state SwapStateData) error {
return s.updateLoop(loopOutBucketKey, hash, time, state)
}
@ -688,8 +695,8 @@ func (s *boltSwapStore) UpdateLoopOut(hash lntypes.Hash, time time.Time,
// a particular swap as it goes through the various stages in its lifetime.
//
// NOTE: Part of the loopdb.SwapStore interface.
func (s *boltSwapStore) UpdateLoopIn(hash lntypes.Hash, time time.Time,
state SwapStateData) error {
func (s *boltSwapStore) UpdateLoopIn(ctx context.Context, hash lntypes.Hash,
time time.Time, state SwapStateData) error {
return s.updateLoop(loopInBucketKey, hash, time, state)
}
@ -706,7 +713,9 @@ func (s *boltSwapStore) Close() error {
//
// NOTE: it's the caller's responsibility to encode the param. Atm, it's
// encoding using the proto package's `Marshal` method.
func (s *boltSwapStore) PutLiquidityParams(params []byte) error {
func (s *boltSwapStore) PutLiquidityParams(ctx context.Context,
params []byte) error {
return s.db.Update(func(tx *bbolt.Tx) error {
// Read the root bucket.
rootBucket := tx.Bucket(liquidityBucket)
@ -722,7 +731,9 @@ func (s *boltSwapStore) PutLiquidityParams(params []byte) error {
//
// NOTE: it's the caller's responsibility to decode the param. Atm, it's
// decoding using the proto package's `Unmarshal` method.
func (s *boltSwapStore) FetchLiquidityParams() ([]byte, error) {
func (s *boltSwapStore) FetchLiquidityParams(ctx context.Context) ([]byte,
error) {
var params []byte
err := s.db.View(func(tx *bbolt.Tx) error {

View file

@ -1,6 +1,7 @@
package loopdb
import (
"context"
"crypto/sha256"
"io/ioutil"
"os"
@ -121,8 +122,10 @@ func testLoopOutStore(t *testing.T, pendingSwap *LoopOutContract) {
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
require.NoError(t, err)
ctxb := context.Background()
// First, verify that an empty database has no active swaps.
swaps, err := store.FetchLoopOutSwaps()
swaps, err := store.FetchLoopOutSwaps(ctxb)
require.NoError(t, err)
require.Empty(t, swaps)
@ -134,12 +137,12 @@ func testLoopOutStore(t *testing.T, pendingSwap *LoopOutContract) {
checkSwap := func(expectedState SwapState) {
t.Helper()
swaps, err := store.FetchLoopOutSwaps()
swaps, err := store.FetchLoopOutSwaps(ctxb)
require.NoError(t, err)
require.Len(t, swaps, 1)
swap, err := store.FetchLoopOutSwap(hash)
swap, err := store.FetchLoopOutSwap(ctxb, hash)
require.NoError(t, err)
require.Equal(t, hash, swap.Hash)
@ -158,20 +161,20 @@ func testLoopOutStore(t *testing.T, pendingSwap *LoopOutContract) {
// If we create a new swap, then it should show up as being initialized
// right after.
err = store.CreateLoopOut(hash, pendingSwap)
err = store.CreateLoopOut(ctxb, hash, pendingSwap)
require.NoError(t, err)
checkSwap(StateInitiated)
// Trying to make the same swap again should result in an error.
err = store.CreateLoopOut(hash, pendingSwap)
err = store.CreateLoopOut(ctxb, hash, pendingSwap)
require.Error(t, err)
checkSwap(StateInitiated)
// Next, we'll update to the next state of the pre-image being
// revealed. The state should be reflected here again.
err = store.UpdateLoopOut(
hash, testTime,
ctxb, hash, testTime,
SwapStateData{
State: StatePreimageRevealed,
HtlcTxHash: &chainhash.Hash{1, 6, 2},
@ -184,7 +187,7 @@ func testLoopOutStore(t *testing.T, pendingSwap *LoopOutContract) {
// Next, we'll update to the final state to ensure that the state is
// properly updated.
err = store.UpdateLoopOut(
hash, testTime,
ctxb, hash, testTime,
SwapStateData{
State: StateFailInsufficientValue,
},
@ -260,8 +263,10 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
require.NoError(t, err)
ctxb := context.Background()
// First, verify that an empty database has no active swaps.
swaps, err := store.FetchLoopInSwaps()
swaps, err := store.FetchLoopInSwaps(ctxb)
require.NoError(t, err)
require.Empty(t, swaps)
@ -272,7 +277,7 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
checkSwap := func(expectedState SwapState) {
t.Helper()
swaps, err := store.FetchLoopInSwaps()
swaps, err := store.FetchLoopInSwaps(ctxb)
require.NoError(t, err)
require.Len(t, swaps, 1)
@ -285,13 +290,13 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
// If we create a new swap, then it should show up as being initialized
// right after.
err = store.CreateLoopIn(hash, &pendingSwap)
err = store.CreateLoopIn(ctxb, hash, &pendingSwap)
require.NoError(t, err)
checkSwap(StateInitiated)
// Trying to make the same swap again should result in an error.
err = store.CreateLoopIn(hash, &pendingSwap)
err = store.CreateLoopIn(ctxb, hash, &pendingSwap)
require.Error(t, err)
checkSwap(StateInitiated)
@ -299,7 +304,7 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
// Next, we'll update to the next state of the pre-image being
// revealed. The state should be reflected here again.
err = store.UpdateLoopIn(
hash, testTime,
ctxb, hash, testTime,
SwapStateData{
State: StatePreimageRevealed,
},
@ -311,7 +316,7 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
// Next, we'll update to the final state to ensure that the state is
// properly updated.
err = store.UpdateLoopIn(
hash, testTime,
ctxb, hash, testTime,
SwapStateData{
State: StateFailInsufficientValue,
},
@ -407,6 +412,8 @@ func TestLegacyOutgoingChannel(t *testing.T) {
legacyOutgoingChannel = Hex("0000000000000005")
)
ctxb := context.Background()
legacyDb := map[string]interface{}{
"loop-in": map[string]interface{}{},
"metadata": map[string]interface{}{
@ -449,7 +456,7 @@ func TestLegacyOutgoingChannel(t *testing.T) {
t.Fatal(err)
}
swaps, err := store.FetchLoopOutSwaps()
swaps, err := store.FetchLoopOutSwaps(ctxb)
if err != nil {
t.Fatal(err)
}
@ -467,23 +474,25 @@ func TestLiquidityParams(t *testing.T) {
require.NoError(t, err, "failed to db")
defer os.RemoveAll(tempDirName)
ctxb := context.Background()
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
require.NoError(t, err, "failed to create store")
// Test when there's no params saved before, an empty bytes is
// returned.
params, err := store.FetchLiquidityParams()
params, err := store.FetchLiquidityParams(ctxb)
require.NoError(t, err, "failed to fetch params")
require.Empty(t, params, "expect empty bytes")
params = []byte("test")
// Test we can save the params.
err = store.PutLiquidityParams(params)
err = store.PutLiquidityParams(ctxb, params)
require.NoError(t, err, "failed to put params")
// Now fetch the db again should return the above saved bytes.
paramsRead, err := store.FetchLiquidityParams()
paramsRead, err := store.FetchLiquidityParams(ctxb)
require.NoError(t, err, "failed to fetch params")
require.Equal(t, params, paramsRead, "unexpected return value")
}