From 26edd218899f2f7a9a59aedcd7a0ccd4882a350c Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Thu, 19 May 2022 03:07:10 +0800 Subject: [PATCH] loopdb: add new bucket to save liquidity params This commit adds a new bucket to save liquidity parameters. We've skipped the serialization and deserialization implementations here and leave them to be handled by the liquidity package. --- loopdb/interface.go | 14 ++++++++++++ loopdb/store.go | 52 ++++++++++++++++++++++++++++++++++++++++++++ loopdb/store_test.go | 28 ++++++++++++++++++++++++ store_mock_test.go | 16 ++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/loopdb/interface.go b/loopdb/interface.go index 86dd853..41172da 100644 --- a/loopdb/interface.go +++ b/loopdb/interface.go @@ -33,6 +33,20 @@ type SwapStore interface { UpdateLoopIn(hash lntypes.Hash, time time.Time, state SwapStateData) error + // PutLiquidityParams writes the serialized `manager.Parameters` bytes + // into the bucket. + // + // 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 + + // 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) + // Close closes the underlying database. Close() error } diff --git a/loopdb/store.go b/loopdb/store.go index 420a00c..67fdcd6 100644 --- a/loopdb/store.go +++ b/loopdb/store.go @@ -94,6 +94,14 @@ var ( // value: uint32 confirmation value confirmationsKey = []byte("confirmations") + // liquidtyBucket is a root bucket used to save liquidity manager + // related info. + liquidityBucket = []byte("liquidity") + + // liquidtyParamsKey specifies the key used to store the liquidity + // parameters. + liquidtyParamsKey = []byte("params") + byteOrder = binary.BigEndian keyLength = 33 @@ -190,6 +198,12 @@ func NewBoltSwapStore(dbPath string, chainParams *chaincfg.Params) ( return err } + // Create liquidity manager's bucket. + _, err = tx.CreateBucketIfNotExists(liquidityBucket) + if err != nil { + return err + } + return nil }) if err != nil { @@ -712,3 +726,41 @@ func (s *boltSwapStore) UpdateLoopIn(hash lntypes.Hash, time time.Time, func (s *boltSwapStore) Close() error { return s.db.Close() } + +// PutLiquidityParams writes the serialized `manager.Parameters` bytes into the +// bucket. +// +// 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 { + return s.db.Update(func(tx *bbolt.Tx) error { + // Read the root bucket. + rootBucket := tx.Bucket(liquidityBucket) + if rootBucket == nil { + return errors.New("liquidity bucket does not exist") + } + return rootBucket.Put(liquidtyParamsKey, params) + }) +} + +// 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. +func (s *boltSwapStore) FetchLiquidityParams() ([]byte, error) { + var params []byte + + err := s.db.View(func(tx *bbolt.Tx) error { + // Read the root bucket. + rootBucket := tx.Bucket(liquidityBucket) + if rootBucket == nil { + return errors.New("liquidity bucket does not exist") + } + + params = rootBucket.Get(liquidtyParamsKey) + return nil + }) + + return params, err +} diff --git a/loopdb/store_test.go b/loopdb/store_test.go index 3f7e11b..ea349d6 100644 --- a/loopdb/store_test.go +++ b/loopdb/store_test.go @@ -471,3 +471,31 @@ func TestLegacyOutgoingChannel(t *testing.T) { t.Fatal("invalid outgoing channel") } } + +// TestLiquidityParams checks that reading and writing to liquidty bucket are +// as expected. +func TestLiquidityParams(t *testing.T) { + tempDirName, err := ioutil.TempDir("", "clientstore") + require.NoError(t, err, "failed to db") + defer os.RemoveAll(tempDirName) + + 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() + 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) + require.NoError(t, err, "failed to put params") + + // Now fetch the db again should return the above saved bytes. + paramsRead, err := store.FetchLiquidityParams() + require.NoError(t, err, "failed to fetch params") + require.Equal(t, params, paramsRead, "unexpected return value") +} diff --git a/store_mock_test.go b/store_mock_test.go index 77f36c3..a366fcd 100644 --- a/store_mock_test.go +++ b/store_mock_test.go @@ -171,6 +171,22 @@ func (s *storeMock) UpdateLoopIn(hash lntypes.Hash, time time.Time, return nil } +// PutLiquidityParams writes the serialized `manager.Parameters` bytes into the +// bucket. +// +// NOTE: Part of the loopdb.SwapStore interface. +func (s *storeMock) PutLiquidityParams(params []byte) error { + return nil +} + +// FetchLiquidityParams reads the serialized `manager.Parameters` bytes from +// the bucket. +// +// NOTE: Part of the loopdb.SwapStore interface. +func (s *storeMock) FetchLiquidityParams() ([]byte, error) { + return nil, nil +} + func (s *storeMock) Close() error { return nil }