mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
Represent withdrawal txids as optional in the domain model and keep pending withdrawals visible through GetAllWithdrawals. Pending rows now surface nil and zero values in Go and empty and zero defaults over RPC, while malformed non-NULL txids still fail loudly. Also sync godoc's with how it actually behaves: returns pending withdraws in addition to finalized ones.
154 lines
3.9 KiB
Go
154 lines
3.9 KiB
Go
package withdraw
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightninglabs/loop/loopdb"
|
|
"github.com/lightninglabs/loop/loopdb/sqlc"
|
|
"github.com/lightninglabs/loop/staticaddr/deposit"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestSqlStore tests the basic functionality of the SQLStore.
|
|
func TestSqlStore(t *testing.T) {
|
|
ctxb := context.Background()
|
|
testDb := loopdb.NewTestDB(t)
|
|
defer testDb.Close()
|
|
|
|
depositStore := deposit.NewSqlStore(testDb.BaseDB)
|
|
store := NewSqlStore(loopdb.NewTypedStore[Querier](testDb), depositStore)
|
|
|
|
newID := func() deposit.ID {
|
|
did, err := deposit.GetRandomDepositID()
|
|
require.NoError(t, err)
|
|
|
|
return did
|
|
}
|
|
|
|
d1, d2 := &deposit.Deposit{
|
|
ID: newID(),
|
|
Value: btcutil.Amount(100_000),
|
|
TimeOutSweepPkScript: []byte{
|
|
0x00, 0x14, 0x1a, 0x2b, 0x3c, 0x41,
|
|
},
|
|
},
|
|
&deposit.Deposit{
|
|
ID: newID(),
|
|
Value: btcutil.Amount(200_000),
|
|
TimeOutSweepPkScript: []byte{
|
|
0x00, 0x14, 0x1a, 0x2b, 0x3c, 0x4d,
|
|
},
|
|
}
|
|
|
|
withdrawalTx := &wire.MsgTx{
|
|
Version: 2,
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: int64(d1.Value + d2.Value - 100),
|
|
PkScript: []byte{
|
|
0x00,
|
|
},
|
|
},
|
|
{
|
|
Value: int64(100),
|
|
PkScript: []byte{
|
|
0x01,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err := depositStore.CreateDeposit(ctxb, d1)
|
|
require.NoError(t, err)
|
|
err = depositStore.CreateDeposit(ctxb, d2)
|
|
require.NoError(t, err)
|
|
|
|
err = store.CreateWithdrawal(ctxb, []*deposit.Deposit{d1, d2})
|
|
require.NoError(t, err)
|
|
|
|
withdrawals, err := store.GetAllWithdrawals(ctxb)
|
|
require.NoError(t, err)
|
|
require.Len(t, withdrawals, 1)
|
|
require.NotEmpty(t, withdrawals[0].ID)
|
|
require.EqualValues(
|
|
t, d1.Value+d2.Value, withdrawals[0].TotalDepositAmount,
|
|
)
|
|
require.Len(t, withdrawals[0].Deposits, 2)
|
|
require.EqualValues(
|
|
t, d1.Value, withdrawals[0].Deposits[0].Value,
|
|
)
|
|
require.EqualValues(
|
|
t, d2.Value, withdrawals[0].Deposits[1].Value,
|
|
)
|
|
require.NotEmpty(t, withdrawals[0].InitiationTime)
|
|
require.Nil(t, withdrawals[0].TxID)
|
|
require.Zero(t, withdrawals[0].WithdrawnAmount)
|
|
require.Zero(t, withdrawals[0].ChangeAmount)
|
|
require.Zero(t, withdrawals[0].ConfirmationHeight)
|
|
|
|
err = store.UpdateWithdrawal(
|
|
ctxb, []*deposit.Deposit{d1, d2}, withdrawalTx, 6, []byte{0x01},
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
withdrawals, err = store.GetAllWithdrawals(ctxb)
|
|
require.NoError(t, err)
|
|
require.Len(t, withdrawals, 1)
|
|
require.NotNil(t, withdrawals[0].TxID)
|
|
require.Equal(t, withdrawalTx.TxHash(), *withdrawals[0].TxID)
|
|
require.EqualValues(
|
|
t, d1.Value+d2.Value-100, withdrawals[0].WithdrawnAmount,
|
|
)
|
|
require.EqualValues(t, 100, withdrawals[0].ChangeAmount)
|
|
require.EqualValues(t, 6, withdrawals[0].ConfirmationHeight)
|
|
}
|
|
|
|
// TestGetAllWithdrawalsRejectsInvalidTxID verifies that a malformed persisted
|
|
// withdrawal txid is rejected, while pending withdrawals remain readable via
|
|
// NULL values.
|
|
func TestGetAllWithdrawalsRejectsInvalidTxID(t *testing.T) {
|
|
ctxb := context.Background()
|
|
testDb := loopdb.NewTestDB(t)
|
|
defer testDb.Close()
|
|
|
|
depositStore := deposit.NewSqlStore(testDb.BaseDB)
|
|
store := NewSqlStore(loopdb.NewTypedStore[Querier](testDb), depositStore)
|
|
|
|
depositID, err := deposit.GetRandomDepositID()
|
|
require.NoError(t, err)
|
|
|
|
d := &deposit.Deposit{
|
|
ID: depositID,
|
|
Value: btcutil.Amount(100_000),
|
|
TimeOutSweepPkScript: []byte{
|
|
0x00, 0x14, 0x1a, 0x2b, 0x3c, 0x41,
|
|
},
|
|
}
|
|
|
|
err = depositStore.CreateDeposit(ctxb, d)
|
|
require.NoError(t, err)
|
|
|
|
err = store.CreateWithdrawal(ctxb, []*deposit.Deposit{d})
|
|
require.NoError(t, err)
|
|
|
|
withdrawalID, err := testDb.Queries.GetWithdrawalIDByDepositID(
|
|
ctxb, d.ID[:],
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
err = testDb.Queries.UpdateWithdrawal(ctxb, sqlc.UpdateWithdrawalParams{
|
|
WithdrawalID: withdrawalID,
|
|
WithdrawalTxID: sql.NullString{
|
|
String: "abcd",
|
|
Valid: true,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = store.GetAllWithdrawals(ctxb)
|
|
require.ErrorContains(t, err, "invalid withdrawal txid")
|
|
}
|