staticaddr/loopin: preserve loop-in last update time

This commit is contained in:
Gustavo Stingelin 2026-07-08 23:35:40 -03:00
parent 4c03e46928
commit df7dfba12a
No known key found for this signature in database
GPG key ID: 15CBADFE29F2017B
2 changed files with 37 additions and 9 deletions

View file

@ -5,6 +5,7 @@ import (
"database/sql"
"errors"
"strings"
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
@ -23,6 +24,12 @@ import (
const OutpointSeparator = ";"
// sqlStoreUpdateTime returns the PostgreSQL-compatible timestamp precision used
// for persisted loop-in update metadata.
func sqlStoreUpdateTime(clock clock.Clock) time.Time {
return clock.Now().Truncate(time.Microsecond)
}
var (
// ErrInvalidOutpoint is returned when an outpoint contains the outpoint
// separator.
@ -288,13 +295,14 @@ func (s *SqlStore) CreateLoopIn(ctx context.Context,
Fast: loopIn.Fast,
}
updateTime := sqlStoreUpdateTime(s.clock)
updateArgs := sqlc.InsertStaticAddressMetaUpdateParams{
SwapHash: loopIn.SwapHash[:],
UpdateTimestamp: s.clock.Now(),
UpdateTimestamp: updateTime,
UpdateState: string(loopIn.GetState()),
}
return s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(),
err := s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(),
func(q Querier) error {
err := q.InsertSwap(ctx, swapArgs)
if err != nil {
@ -331,6 +339,13 @@ func (s *SqlStore) CreateLoopIn(ctx context.Context,
return q.InsertStaticAddressMetaUpdate(ctx, updateArgs)
},
)
if err != nil {
return err
}
loopIn.LastUpdateTime = updateTime
return nil
}
// UpdateLoopIn updates the loop-in in the database.
@ -351,13 +366,14 @@ func (s *SqlStore) UpdateLoopIn(ctx context.Context,
},
}
updateTime := sqlStoreUpdateTime(s.clock)
updateArgs := sqlc.InsertStaticAddressMetaUpdateParams{
SwapHash: loopIn.SwapHash[:],
UpdateState: string(loopIn.GetState()),
UpdateTimestamp: s.clock.Now(),
UpdateTimestamp: updateTime,
}
return s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(),
err := s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(),
func(q Querier) error {
err := q.UpdateStaticAddressLoopIn(ctx, updateParams)
if err != nil {
@ -367,6 +383,13 @@ func (s *SqlStore) UpdateLoopIn(ctx context.Context,
return q.InsertStaticAddressMetaUpdate(ctx, updateArgs)
},
)
if err != nil {
return err
}
loopIn.LastUpdateTime = updateTime
return nil
}
// RecordStaticAddressRiskDecision stores the server's confirmation-risk

View file

@ -252,7 +252,9 @@ func TestCreateLoopIn(t *testing.T) {
// Set up test context objects.
ctx := t.Context()
testDb := loopdb.NewTestDB(t)
testClock := clock.NewTestClock(time.Now())
createTime := time.Unix(1_717_171_717, 123_456_789).UTC()
expectedCreateTime := createTime.Truncate(time.Microsecond)
testClock := clock.NewTestClock(createTime)
defer testDb.Close()
depositStore := deposit.NewSqlStore(testDb.BaseDB)
@ -325,6 +327,7 @@ func TestCreateLoopIn(t *testing.T) {
err = swapStore.CreateLoopIn(ctx, &swapPending)
require.NoError(t, err)
require.Equal(t, expectedCreateTime, swapPending.LastUpdateTime)
depositIDs, err := swapStore.DepositIDsForSwapHash(
ctx, swapHashPending,
@ -349,6 +352,7 @@ func TestCreateLoopIn(t *testing.T) {
require.Equal(t, []string{d1.OutPoint.String(), d2.OutPoint.String()},
swap.DepositOutpoints)
require.Equal(t, SignHtlcTx, swap.GetState())
require.Equal(t, swapPending.LastUpdateTime, swap.LastUpdateTime)
require.Equal(
t, ConfirmationRiskDecisionNone,
swap.ConfirmationRiskDecision,
@ -445,14 +449,15 @@ func TestCreateLoopIn(t *testing.T) {
err = swapStore.UpdateLoopIn(ctx, &swapPending)
require.NoError(t, err)
require.Equal(
t, updateTime.Truncate(time.Microsecond),
swapPending.LastUpdateTime,
)
swap, err = swapStore.GetLoopInByHash(ctx, swapHashPending)
require.NoError(t, err)
require.Equal(t, Succeeded, swap.GetState())
require.WithinDuration(
t, updateTime.UTC(), swap.LastUpdateTime.UTC(),
time.Microsecond,
)
require.Equal(t, swapPending.LastUpdateTime, swap.LastUpdateTime)
}
// TestGetLoopInByHashOrdersDepositsBySnapshot ensures recovered deposits are