From b8157ef9010e6a2503c40e4c97127ec80e0e8e29 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 6 May 2026 15:02:09 +0200 Subject: [PATCH] staticaddr/deposit: restore owning address parameters Join each selected deposit with its persisted static-address row during loop-in recovery. Hydrate legacy rows as needed so restored swaps retain the scripts and key locators required for signing. --- cmd/loop/staticaddr_test.go | 7 +- loopdb/sqlc/queries/static_address_loopin.sql | 9 + loopdb/sqlc/static_address_loopin.sql.go | 25 +++ staticaddr/deposit/manager.go | 95 ++++++++- staticaddr/deposit/manager_reconcile_test.go | 29 ++- staticaddr/deposit/manager_test.go | 193 ++++++++++++++---- staticaddr/loopin/manager.go | 29 ++- staticaddr/loopin/manager_test.go | 15 +- staticaddr/loopin/sql_store.go | 10 + 9 files changed, 348 insertions(+), 64 deletions(-) diff --git a/cmd/loop/staticaddr_test.go b/cmd/loop/staticaddr_test.go index 2cc88ad6..2f7bcfb8 100644 --- a/cmd/loop/staticaddr_test.go +++ b/cmd/loop/staticaddr_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/loop/looprpc" + "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightninglabs/loop/staticaddr/deposit" "github.com/lightninglabs/loop/staticaddr/loopin" "github.com/stretchr/testify/require" @@ -196,6 +197,9 @@ func TestWarningDepositSelectionMatchesLoopInSelection(t *testing.T) { OutPoint: outpoint, Value: btcutil.Amount(fixture.value), ConfirmationHeight: fixture.confirmationHeight, + AddressParams: &address.Parameters{ + Expiry: csvExpiry, + }, }) } @@ -204,8 +208,7 @@ func TestWarningDepositSelectionMatchesLoopInSelection(t *testing.T) { ) loopInSelected, err := loopin.SelectDeposits( - btcutil.Amount(targetAmount), loopInDeposits, csvExpiry, - blockHeight, + btcutil.Amount(targetAmount), loopInDeposits, blockHeight, ) require.NoError(t, err) diff --git a/loopdb/sqlc/queries/static_address_loopin.sql b/loopdb/sqlc/queries/static_address_loopin.sql index b4fca5d4..4a88c518 100644 --- a/loopdb/sqlc/queries/static_address_loopin.sql +++ b/loopdb/sqlc/queries/static_address_loopin.sql @@ -147,10 +147,19 @@ WHERE -- name: DepositsForSwapHash :many SELECT d.*, + sa.client_pubkey client_pubkey, + sa.server_pubkey server_pubkey, + sa.expiry expiry, + sa.client_key_family client_key_family, + sa.client_key_index client_key_index, + sa.pkscript pkscript, + sa.protocol_version protocol_version, + sa.initiation_height initiation_height, u.update_state, u.update_timestamp FROM deposits d + LEFT JOIN static_addresses sa ON sa.id = d.static_address_id LEFT JOIN deposit_updates u ON u.id = ( SELECT id diff --git a/loopdb/sqlc/static_address_loopin.sql.go b/loopdb/sqlc/static_address_loopin.sql.go index f6c896ce..8cb2aef6 100644 --- a/loopdb/sqlc/static_address_loopin.sql.go +++ b/loopdb/sqlc/static_address_loopin.sql.go @@ -46,10 +46,19 @@ func (q *Queries) DepositIDsForSwapHash(ctx context.Context, swapHash []byte) ([ const depositsForSwapHash = `-- name: DepositsForSwapHash :many SELECT d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash, d.static_address_id, + sa.client_pubkey client_pubkey, + sa.server_pubkey server_pubkey, + sa.expiry expiry, + sa.client_key_family client_key_family, + sa.client_key_index client_key_index, + sa.pkscript pkscript, + sa.protocol_version protocol_version, + sa.initiation_height initiation_height, u.update_state, u.update_timestamp FROM deposits d + LEFT JOIN static_addresses sa ON sa.id = d.static_address_id LEFT JOIN deposit_updates u ON u.id = ( SELECT id @@ -74,6 +83,14 @@ type DepositsForSwapHashRow struct { FinalizedWithdrawalTx sql.NullString SwapHash []byte StaticAddressID sql.NullInt32 + ClientPubkey []byte + ServerPubkey []byte + Expiry sql.NullInt32 + ClientKeyFamily sql.NullInt32 + ClientKeyIndex sql.NullInt32 + Pkscript []byte + ProtocolVersion sql.NullInt32 + InitiationHeight sql.NullInt32 UpdateState sql.NullString UpdateTimestamp sql.NullTime } @@ -99,6 +116,14 @@ func (q *Queries) DepositsForSwapHash(ctx context.Context, swapHash []byte) ([]D &i.FinalizedWithdrawalTx, &i.SwapHash, &i.StaticAddressID, + &i.ClientPubkey, + &i.ServerPubkey, + &i.Expiry, + &i.ClientKeyFamily, + &i.ClientKeyIndex, + &i.Pkscript, + &i.ProtocolVersion, + &i.InitiationHeight, &i.UpdateState, &i.UpdateTimestamp, ); err != nil { diff --git a/staticaddr/deposit/manager.go b/staticaddr/deposit/manager.go index 4d4b1df4..6fcfea28 100644 --- a/staticaddr/deposit/manager.go +++ b/staticaddr/deposit/manager.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -69,8 +70,8 @@ type Manager struct { // mu guards access to the activeDeposits map. mu sync.Mutex - // reconcileMu serializes deposit reconciliation so new deposits are - // discovered and retained exactly once per outpoint. + // reconcileMu serializes startup recovery and deposit reconciliation so + // new deposits are discovered and retained exactly once per outpoint. reconcileMu sync.Mutex // activeDeposits contains all the active static address outputs. @@ -213,6 +214,9 @@ func (m *Manager) notifyActiveDeposits(ctx context.Context, // recoverDeposits recovers static address parameters, previous deposits and // state machines from the database and starts the deposit notifier. func (m *Manager) recoverDeposits(ctx context.Context) error { + m.reconcileMu.Lock() + defer m.reconcileMu.Unlock() + log.Infof("Recovering static address parameters and deposits...") // Recover deposits. @@ -222,6 +226,11 @@ func (m *Manager) recoverDeposits(ctx context.Context) error { } for i, d := range deposits { + err = m.hydrateLegacyDepositAddressParams(ctx, d) + if err != nil { + return err + } + m.deposits[d.OutPoint] = deposits[i] // If the current deposit is final it wasn't active when we @@ -258,6 +267,66 @@ func (m *Manager) recoverDeposits(ctx context.Context) error { return nil } +// hydrateLegacyDepositAddressParams fills in address parameters for deposits +// that predate the durable deposit-to-static-address link. Those deposits all +// belonged to the legacy/root static address, so the legacy address manager +// lookup preserves the behavior that existed before multi-address support. +func (m *Manager) hydrateLegacyDepositAddressParams(ctx context.Context, + deposits ...*Deposit) error { + + needsHydration := false + for _, d := range deposits { + if d != nil && d.AddressParams == nil { + needsHydration = true + break + } + } + if !needsHydration { + return nil + } + + if m.cfg == nil || m.cfg.AddressManager == nil { + return nil + } + + var legacyParams *address.Parameters + for _, d := range deposits { + if d == nil || d.AddressParams != nil { + continue + } + + if legacyParams == nil { + params, err := m.cfg.AddressManager. + GetStaticAddressParameters(ctx) + if err != nil { + return fmt.Errorf("unable to load legacy "+ + "static address parameters for deposit %v: %w", + d.OutPoint, err) + } + if params == nil { + return fmt.Errorf("missing legacy static address "+ + "parameters for deposit %v", d.OutPoint) + } + + if params.ID <= 0 { + params.ID, err = m.cfg.AddressManager. + GetStaticAddressID(ctx, params.PkScript) + if err != nil { + return fmt.Errorf("unable to load legacy "+ + "static address ID for deposit %v: %w", + d.OutPoint, err) + } + } + + legacyParams = params + } + + d.AddressParams = legacyParams + } + + return nil +} + // pollDeposits periodically polls for new deposits to our static address. This // complements the block-driven reconciliation in the main event loop: while new // blocks trigger reconcileDeposits to promptly detect confirmations, the ticker @@ -805,7 +874,17 @@ func (m *Manager) removeActiveDeposit(outpoint wire.OutPoint) { // GetAllDeposits returns all known deposits from the database. func (m *Manager) GetAllDeposits(ctx context.Context) ([]*Deposit, error) { - return m.cfg.Store.AllDeposits(ctx) + deposits, err := m.cfg.Store.AllDeposits(ctx) + if err != nil { + return nil, err + } + + err = m.hydrateLegacyDepositAddressParams(ctx, deposits...) + if err != nil { + return nil, err + } + + return deposits, nil } // GetVisibleDeposits returns deposits that should be exposed through normal @@ -820,6 +899,11 @@ func (m *Manager) GetVisibleDeposits(ctx context.Context) ([]*Deposit, error) { return nil, err } + err = m.hydrateLegacyDepositAddressParams(ctx, deposits...) + if err != nil { + return nil, err + } + m.mu.Lock() defer m.mu.Unlock() @@ -896,6 +980,11 @@ func (m *Manager) DepositsForOutpoints(ctx context.Context, return nil, err } + err = m.hydrateLegacyDepositAddressParams(ctx, deposit) + if err != nil { + return nil, err + } + deposits = append(deposits, deposit) } diff --git a/staticaddr/deposit/manager_reconcile_test.go b/staticaddr/deposit/manager_reconcile_test.go index 15b2f0a6..288295a7 100644 --- a/staticaddr/deposit/manager_reconcile_test.go +++ b/staticaddr/deposit/manager_reconcile_test.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightninglabs/loop/staticaddr/script" "github.com/lightninglabs/loop/staticaddr/version" "github.com/lightninglabs/loop/test" @@ -41,8 +42,15 @@ func TestReconcileDepositsSerialized(t *testing.T) { "ListUnspent", mock.Anything, int32(0), int32(MaxConfs), ).Return([]*lnwallet.Utxo{utxo}, nil) mockAddressManager.On( - "GetStaticAddressParameters", mock.Anything, - ).Return((*script.Parameters)(nil), errors.New("fsm init failed")) + "GetParameters", mock.Anything, + ).Return(&address.Parameters{ + ID: 1, + ClientPubkey: defaultServerPubkey, + ServerPubkey: defaultServerPubkey, + Expiry: defaultExpiry, + PkScript: utxo.PkScript, + ProtocolVersion: 999, + }) mockStore := new(mockStore) var createCalls atomic.Int32 @@ -137,8 +145,15 @@ func TestReconcileConfirmedDepositUsesCurrentHeight(t *testing.T) { "ListUnspent", mock.Anything, int32(0), int32(MaxConfs), ).Return([]*lnwallet.Utxo{utxo}, nil) mockAddressManager.On( - "GetStaticAddressParameters", mock.Anything, - ).Return((*script.Parameters)(nil), errors.New("fsm init failed")) + "GetParameters", mock.Anything, + ).Return(&address.Parameters{ + ID: 1, + ClientPubkey: defaultServerPubkey, + ServerPubkey: defaultServerPubkey, + Expiry: defaultExpiry, + PkScript: utxo.PkScript, + ProtocolVersion: 999, + }) mockStore := new(mockStore) mockStore.On( @@ -471,6 +486,12 @@ func TestReconcileDepositsReactivatesReappearedDeposit(t *testing.T) { OutPoint: outpoint, Value: btcutil.Amount(100_000), ConfirmationHeight: 77, + AddressParams: &address.Parameters{ + ClientPubkey: defaultServerPubkey, + ServerPubkey: defaultServerPubkey, + Expiry: defaultExpiry, + ProtocolVersion: version.ProtocolVersion_V0, + }, } deposit.SetState(Deposited) diff --git a/staticaddr/deposit/manager_test.go b/staticaddr/deposit/manager_test.go index cb9a8f54..1c642357 100644 --- a/staticaddr/deposit/manager_test.go +++ b/staticaddr/deposit/manager_test.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightninglabs/loop/staticaddr/script" "github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swapserverrpc" @@ -524,6 +525,96 @@ func TestManagerSkipsExpiryNotificationOnReconcileFailure(t *testing.T) { } } +func TestRecoverDepositsKeepsSpentWithdrawing(t *testing.T) { + ctx := context.Background() + + id, err := GetRandomDepositID() + require.NoError(t, err) + + storedDeposit := &Deposit{ + ID: id, + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{2}, + Index: 2, + }, + state: Withdrawing, + Value: btcutil.Amount(100000), + ConfirmationHeight: 42, + } + + testContext := newManagerTestContextWithStoredDeposits( + t, []*Deposit{storedDeposit}, nil, + ) + + err = testContext.manager.recoverDeposits(ctx) + require.NoError(t, err) + + deposits, err := testContext.manager.GetActiveDepositsInState(Withdrawing) + require.NoError(t, err) + require.Len(t, deposits, 1) + require.Equal(t, storedDeposit.OutPoint, deposits[0].OutPoint) +} + +func TestRecoverDepositsHydratesLegacyAddressParams(t *testing.T) { + ctx := context.Background() + + id, err := GetRandomDepositID() + require.NoError(t, err) + + storedDeposit := &Deposit{ + ID: id, + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{3}, + Index: 3, + }, + state: Deposited, + Value: btcutil.Amount(100000), + ConfirmationHeight: 42, + TimeOutSweepPkScript: []byte{0x42, 0x21, 0x69}, + } + + testContext := newManagerTestContextWithStoredDeposits( + t, []*Deposit{storedDeposit}, nil, + ) + + storedDeposit.AddressParams = nil + + err = testContext.manager.recoverDeposits(ctx) + require.NoError(t, err) + require.NotNil(t, storedDeposit.AddressParams) + require.NotZero(t, storedDeposit.AddressParams.ID) +} + +func TestGetAllDepositsHydratesLegacyAddressParams(t *testing.T) { + ctx := context.Background() + + id, err := GetRandomDepositID() + require.NoError(t, err) + + storedDeposit := &Deposit{ + ID: id, + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{4}, + Index: 4, + }, + state: Withdrawn, + Value: btcutil.Amount(100000), + ConfirmationHeight: 42, + } + + testContext := newManagerTestContextWithStoredDeposits( + t, []*Deposit{storedDeposit}, nil, + ) + + storedDeposit.AddressParams = nil + + deposits, err := testContext.manager.GetAllDeposits(ctx) + require.NoError(t, err) + require.Len(t, deposits, 1) + require.NotNil(t, deposits[0].AddressParams) + require.NotZero(t, deposits[0].AddressParams.ID) +} + // ManagerTestContext is a helper struct that contains all the necessary // components to test the reservation manager. type ManagerTestContext struct { @@ -540,6 +631,39 @@ type ManagerTestContext struct { // newManagerTestContext creates a new test context for the reservation manager. func newManagerTestContext(t *testing.T) *ManagerTestContext { + ID, err := GetRandomDepositID() + require.NoError(t, err) + + utxo := &lnwallet.Utxo{ + AddressType: lnwallet.TaprootPubkey, + Value: btcutil.Amount(100000), + Confirmations: int64(defaultDepositConfirmations), + PkScript: []byte("pkscript"), + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{}, + Index: 0xffffffff, + }, + } + + storedDeposits := []*Deposit{ + { + ID: ID, + state: Deposited, + OutPoint: utxo.OutPoint, + Value: utxo.Value, + ConfirmationHeight: 3, + TimeOutSweepPkScript: []byte{0x42, 0x21, 0x69}, + }, + } + + return newManagerTestContextWithStoredDeposits( + t, storedDeposits, []*lnwallet.Utxo{utxo}, + ) +} + +func newManagerTestContextWithStoredDeposits(t *testing.T, + storedDeposits []*Deposit, utxos []*lnwallet.Utxo) *ManagerTestContext { + mockLnd := test.NewMockLnd() lndContext := test.NewContext(t, mockLnd) @@ -552,29 +676,6 @@ func newManagerTestContext(t *testing.T) *ManagerTestContext { blockChan := make(chan int32) blockErrChan := make(chan error) - ID, err := GetRandomDepositID() - utxo := &lnwallet.Utxo{ - AddressType: lnwallet.TaprootPubkey, - Value: btcutil.Amount(100000), - Confirmations: int64(defaultDepositConfirmations), - PkScript: []byte("pkscript"), - OutPoint: wire.OutPoint{ - Hash: chainhash.Hash{}, - Index: 0xffffffff, - }, - } - require.NoError(t, err) - storedDeposits := []*Deposit{ - { - ID: ID, - state: Deposited, - OutPoint: utxo.OutPoint, - Value: utxo.Value, - ConfirmationHeight: 3, - TimeOutSweepPkScript: []byte{0x42, 0x21, 0x69}, - }, - } - mockStore.On( "AllDeposits", mock.Anything, ).Return(storedDeposits, nil) @@ -583,17 +684,29 @@ func newManagerTestContext(t *testing.T) *ManagerTestContext { "UpdateDeposit", mock.Anything, mock.Anything, ).Return(nil) + staticAddress, addrParams := generateStaticAddress( + context.Background(), mockLnd, lndContext.T, + ) + for _, storedDeposit := range storedDeposits { + if storedDeposit.AddressParams == nil { + storedDeposit.AddressParams = addrParams + } + } + var manager *Manager + mockAddressManager.On( "GetStaticAddressParameters", mock.Anything, - ).Return(&script.Parameters{ - Expiry: defaultExpiry, - }, nil) + ).Return(addrParams, nil) mockAddressManager.On( "ListUnspent", mock.Anything, mock.Anything, mock.Anything, ).Return(func() []*lnwallet.Utxo { - currentUtxo := *utxo + if len(utxos) != 1 { + return utxos + } + + currentUtxo := *utxos[0] currentHeight := manager.currentHeight.Load() if currentHeight < defaultDepositConfirmations { currentUtxo.Confirmations = 0 @@ -638,9 +751,6 @@ func newManagerTestContext(t *testing.T) *ManagerTestContext { blockErrChan: blockErrChan, } - staticAddress := generateStaticAddress( - context.Background(), testContext, - ) mockAddressManager.On( "GetStaticAddress", mock.Anything, ).Return(staticAddress, nil) @@ -648,19 +758,30 @@ func newManagerTestContext(t *testing.T) *ManagerTestContext { return testContext } -func generateStaticAddress(ctx context.Context, - t *ManagerTestContext) *script.StaticAddress { +func generateStaticAddress(ctx context.Context, mockLnd *test.LndMockServices, + t *testing.T) (*script.StaticAddress, *address.Parameters) { - keyDescriptor, err := t.mockLnd.WalletKit.DeriveNextKey( + keyDescriptor, err := mockLnd.WalletKit.DeriveNextKey( ctx, swap.StaticAddressKeyFamily, ) - require.NoError(t.context.T, err) + require.NoError(t, err) staticAddress, err := script.NewStaticAddress( input.MuSig2Version100RC2, int64(defaultExpiry), keyDescriptor.PubKey, defaultServerPubkey, ) - require.NoError(t.context.T, err) + require.NoError(t, err) - return staticAddress + pkScript, err := staticAddress.StaticAddressScript() + require.NoError(t, err) + + return staticAddress, &address.Parameters{ + ID: 1, + ClientPubkey: keyDescriptor.PubKey, + ServerPubkey: defaultServerPubkey, + Expiry: defaultExpiry, + PkScript: pkScript, + KeyLocator: keyDescriptor.KeyLocator, + ProtocolVersion: 0, + } } diff --git a/staticaddr/loopin/manager.go b/staticaddr/loopin/manager.go index 2f1e0e77..226b8900 100644 --- a/staticaddr/loopin/manager.go +++ b/staticaddr/loopin/manager.go @@ -678,19 +678,8 @@ func (m *Manager) initiateLoopIn(ctx context.Context, "deposits: %w", err) } - // TODO(hieblmi): add params to deposit for multi-address - // support. - params, err := m.cfg.AddressManager.GetStaticAddressParameters( - ctx, - ) - if err != nil { - return nil, fmt.Errorf("unable to retrieve static "+ - "address parameters: %w", err) - } - selectedDeposits, err = SelectDeposits( - req.SelectedAmount, allDeposits, params.Expiry, - m.currentHeight.Load(), + req.SelectedAmount, allDeposits, m.currentHeight.Load(), ) if err != nil { return nil, fmt.Errorf("unable to select deposits: %w", @@ -870,15 +859,21 @@ func (m *Manager) activeDepositsForLoopIn(loopIn *StaticAddressLoopIn) ( // leaving a dust change. It returns an error if the sum of deposits minus dust // is less than the requested amount. func SelectDeposits(targetAmount btcutil.Amount, - unfilteredDeposits []*deposit.Deposit, csvExpiry uint32, - blockHeight uint32) ([]*deposit.Deposit, error) { + unfilteredDeposits []*deposit.Deposit, blockHeight uint32) ( + []*deposit.Deposit, error) { // Filter out deposits that are too close to expiry to be swapped. var deposits []*deposit.Deposit for _, d := range unfilteredDeposits { confirmationHeight := d.GetConfirmationHeight() + if d.AddressParams == nil { + return nil, fmt.Errorf("missing static address parameters "+ + "for deposit %s", d.OutPoint.String()) + } + if !IsSwappable( - uint32(confirmationHeight), blockHeight, csvExpiry, + uint32(confirmationHeight), blockHeight, + d.AddressParams.Expiry, ) { log.Debugf("Skipping deposit %s as it expires before "+ @@ -905,11 +900,11 @@ func SelectDeposits(targetAmount btcutil.Amount, if deposits[i].Value == deposits[j].Value { iExp := blocksUntilDepositExpiry( uint32(iConfirmationHeight), blockHeight, - csvExpiry, + deposits[i].AddressParams.Expiry, ) jExp := blocksUntilDepositExpiry( uint32(jConfirmationHeight), blockHeight, - csvExpiry, + deposits[j].AddressParams.Expiry, ) return iExp < jExp diff --git a/staticaddr/loopin/manager_test.go b/staticaddr/loopin/manager_test.go index 9fa8587c..67f744f6 100644 --- a/staticaddr/loopin/manager_test.go +++ b/staticaddr/loopin/manager_test.go @@ -14,6 +14,7 @@ import ( "github.com/lightninglabs/loop" "github.com/lightninglabs/loop/fsm" "github.com/lightninglabs/loop/labels" + "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightninglabs/loop/staticaddr/deposit" "github.com/lightninglabs/loop/staticaddr/script" "github.com/lightninglabs/loop/swap" @@ -193,9 +194,11 @@ func TestSelectDeposits(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + setTestDepositParams(tc.deposits, tc.csvExpiry) + setTestDepositParams(tc.expected, tc.csvExpiry) + selectedDeposits, err := SelectDeposits( - tc.targetValue, tc.deposits, tc.csvExpiry, - tc.blockHeight, + tc.targetValue, tc.deposits, tc.blockHeight, ) if tc.expectedErr == "" { require.NoError(t, err) @@ -417,6 +420,14 @@ func TestGetAllSwapsPreservesStoreDeposits(t *testing.T) { require.Equal(t, []*deposit.Deposit{currentDeposit}, swaps[0].Deposits) } +func setTestDepositParams(deposits []*deposit.Deposit, expiry uint32) { + for _, d := range deposits { + d.AddressParams = &address.Parameters{ + Expiry: expiry, + } + } +} + // TestIsSwappableUnconfirmed checks that an unconfirmed deposit is considered // swappable because its CSV timeout has not started yet. func TestIsSwappableUnconfirmed(t *testing.T) { diff --git a/staticaddr/loopin/sql_store.go b/staticaddr/loopin/sql_store.go index d5f71271..cd102850 100644 --- a/staticaddr/loopin/sql_store.go +++ b/staticaddr/loopin/sql_store.go @@ -610,6 +610,16 @@ func toStaticAddressLoopIn(_ context.Context, network *chaincfg.Params, TimeoutSweepPkScript: d.TimeoutSweepPkScript, ExpirySweepTxid: d.ExpirySweepTxid, FinalizedWithdrawalTx: d.FinalizedWithdrawalTx, + SwapHash: d.SwapHash, + StaticAddressID: d.StaticAddressID, + ClientPubkey: d.ClientPubkey, + ServerPubkey: d.ServerPubkey, + Expiry: d.Expiry, + ClientKeyFamily: d.ClientKeyFamily, + ClientKeyIndex: d.ClientKeyIndex, + Pkscript: d.Pkscript, + ProtocolVersion: d.ProtocolVersion, + InitiationHeight: d.InitiationHeight, } sqlcDepositUpdate := sqlc.DepositUpdate{