From d6be549e17e135e355e0d7770c2788575dc853cd Mon Sep 17 00:00:00 2001 From: elbandi Date: Wed, 8 Nov 2023 00:56:57 +0100 Subject: [PATCH 1/3] loopdb: Fix PublicationDeadline This commit fixes the publication deadline based on the swaps invoice timestamp. --- loopdb/sqlite.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/loopdb/sqlite.go b/loopdb/sqlite.go index 1a744f6..63ac0de 100644 --- a/loopdb/sqlite.go +++ b/loopdb/sqlite.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" sqlite_migrate "github.com/golang-migrate/migrate/v4/database/sqlite" "github.com/lightninglabs/loop/loopdb/sqlc" + "github.com/lightningnetwork/lnd/zpay32" "github.com/stretchr/testify/require" _ "modernc.org/sqlite" // Register relevant drivers. @@ -213,7 +214,7 @@ func (db *BaseDB) ExecTx(ctx context.Context, txOptions TxOptions, func (b *BaseDB) FixFaultyTimestamps(ctx context.Context) error { // Manually fetch all the loop out swaps. rows, err := b.DB.QueryContext( - ctx, "SELECT swap_hash, publication_deadline FROM loopout_swaps", + ctx, "SELECT swap_hash, swap_invoice, publication_deadline FROM loopout_swaps", ) if err != nil { return err @@ -226,6 +227,7 @@ func (b *BaseDB) FixFaultyTimestamps(ctx context.Context) error { // the sqlite driver will fail on faulty timestamps. type LoopOutRow struct { Hash []byte `json:"swap_hash"` + SwapInvoice string `json:"swap_invoice"` PublicationDeadline string `json:"publication_deadline"` } @@ -234,7 +236,7 @@ func (b *BaseDB) FixFaultyTimestamps(ctx context.Context) error { for rows.Next() { var swap LoopOutRow err := rows.Scan( - &swap.Hash, &swap.PublicationDeadline, + &swap.Hash, &swap.SwapInvoice, &swap.PublicationDeadline, ) if err != nil { return err @@ -264,14 +266,15 @@ func (b *BaseDB) FixFaultyTimestamps(ctx context.Context) error { // Skip if the year is not in the future. thisYear := time.Now().Year() - if year <= thisYear { + if year > 2020 && year <= thisYear { continue } - fixedTime, err := fixTimeStamp(swap.PublicationDeadline) + payReq, err := zpay32.Decode(swap.SwapInvoice, b.network) if err != nil { return err } + fixedTime := payReq.Timestamp.Add(time.Minute * 30) // Update the faulty time to a valid time. _, err = tx.ExecContext( From 57fa22b0952fbe34b87a9d041515a347515fdd4d Mon Sep 17 00:00:00 2001 From: sputn1ck Date: Wed, 3 Jan 2024 11:00:58 +0100 Subject: [PATCH 2/3] loopdb: remove unused code --- loopdb/sql_test.go | 76 ---------------------------- loopdb/sqlite.go | 122 --------------------------------------------- 2 files changed, 198 deletions(-) diff --git a/loopdb/sql_test.go b/loopdb/sql_test.go index 870d150..6d3f8de 100644 --- a/loopdb/sql_test.go +++ b/loopdb/sql_test.go @@ -384,82 +384,6 @@ func TestIssue615(t *testing.T) { require.NoError(t, err) } -func TestTimeConversions(t *testing.T) { - tests := []struct { - timeString string - expectedTime time.Time - }{ - { - timeString: "2018-11-01 00:00:00 +0000 UTC", - expectedTime: time.Date(2018, 11, 1, 0, 0, 0, 0, time.UTC), - }, - { - timeString: "2018-11-01 00:00:01.10000 +0000 UTC", - expectedTime: time.Date(2018, 11, 1, 0, 0, 1, 100000000, time.UTC), - }, - { - timeString: "2053-12-29T02:40:44.269009408Z", - expectedTime: time.Date( - time.Now().Year(), 12, 29, 2, 40, 44, 269009408, time.UTC, - ), - }, - { - timeString: "55563-06-27 02:09:24 +0000 UTC", - expectedTime: time.Date( - time.Now().Year(), 6, 27, 2, 9, 24, 0, time.UTC, - ), - }, - { - timeString: "2172-03-11 10:01:11.849906176 +0000 UTC", - expectedTime: time.Date( - time.Now().Year(), 3, 11, 10, 1, 11, 849906176, time.UTC, - ), - }, - { - timeString: "2023-08-04 16:07:49 +0800 CST", - expectedTime: time.Date( - 2023, 8, 4, 8, 7, 49, 0, time.UTC, - ), - }, - { - timeString: "2023-08-04 16:07:49 -0700 MST", - expectedTime: time.Date( - 2023, 8, 4, 23, 7, 49, 0, time.UTC, - ), - }, - { - timeString: "2023-08-04T16:07:49+08:00", - expectedTime: time.Date( - 2023, 8, 4, 8, 7, 49, 0, time.UTC, - ), - }, - { - timeString: "2023-08-04T16:07:49+08:00", - expectedTime: time.Date( - 2023, 8, 4, 8, 7, 49, 0, time.UTC, - ), - }, - { - timeString: "2188-02-29 15:34:23.847906176 +0000 UTC", - expectedTime: time.Date( - 2023, 2, 28, 15, 34, 23, 847906176, time.UTC, - ), - }, - { - timeString: "2188-02-29T16:07:49+08:00", - expectedTime: time.Date( - 2023, 2, 28, 8, 7, 49, 0, time.UTC, - ), - }, - } - - for _, test := range tests { - time, err := fixTimeStamp(test.timeString) - require.NoError(t, err) - require.Equal(t, test.expectedTime, time) - } -} - const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" func randomString(length int) string { diff --git a/loopdb/sqlite.go b/loopdb/sqlite.go index 63ac0de..d489959 100644 --- a/loopdb/sqlite.go +++ b/loopdb/sqlite.go @@ -3,7 +3,6 @@ package loopdb import ( "context" "database/sql" - "errors" "fmt" "net/url" "path/filepath" @@ -325,92 +324,6 @@ func (r *SqliteTxOptions) ReadOnly() bool { return r.readOnly } -// fixTimeStamp tries to parse a timestamp string with both the -// parseSqliteTimeStamp and parsePostgresTimeStamp functions. -// If both fail, it returns an error. -func fixTimeStamp(dateTimeStr string) (time.Time, error) { - year, err := getTimeStampYear(dateTimeStr) - if err != nil { - return time.Time{}, err - } - - // If the year is in the future. It was a faulty timestamp. - thisYear := time.Now().Year() - if year > thisYear { - dateTimeStr = strings.Replace( - dateTimeStr, - fmt.Sprintf("%d", year), - fmt.Sprintf("%d", thisYear), - 1, - ) - } - - // If the year is a leap year and the date is 29th of February, we - // need to change it to 28th of February. Otherwise, the time.Parse - // function will fail, as a non-leap year cannot have 29th of February. - day, month, err := extractDayAndMonth(dateTimeStr) - if err != nil { - return time.Time{}, fmt.Errorf("unable to parse timestamp day "+ - "and month %v: %v", dateTimeStr, err) - } - - if !isLeapYear(thisYear) && - month == 2 && day == 29 { - - dateTimeStr = strings.Replace( - dateTimeStr, - fmt.Sprintf("%d-02-29", thisYear), - fmt.Sprintf("%d-02-28", thisYear), - 1, - ) - } - - parsedTime, err := parseLayouts(defaultLayouts(), dateTimeStr) - if err != nil { - return time.Time{}, fmt.Errorf("unable to parse timestamp %v: %v", - dateTimeStr, err) - } - - return parsedTime.UTC(), nil -} - -// parseLayouts parses time based on a list of provided layouts. -// If layouts is empty list or nil, the error with unknown layout will be returned. -func parseLayouts(layouts []string, dateTime string) (time.Time, error) { - for _, layout := range layouts { - parsedTime, err := time.Parse(layout, dateTime) - if err == nil { - return parsedTime, nil - } - } - - return time.Time{}, errors.New("unknown layout") -} - -// defaultLayouts returns a default list of ALL supported layouts. -// This function returns new copy of a slice. -func defaultLayouts() []string { - return []string{ - "2006-01-02 15:04:05.99999 -0700 MST", // Custom sqlite layout. - time.RFC3339Nano, - time.RFC3339, - time.RFC1123Z, - time.RFC1123, - time.RFC850, - time.RFC822Z, - time.RFC822, - time.Layout, - time.RubyDate, - time.UnixDate, - time.ANSIC, - time.StampNano, - time.StampMicro, - time.StampMilli, - time.Stamp, - time.Kitchen, - } -} - // getTimeStampYear returns the year of a timestamp string. func getTimeStampYear(dateTimeStr string) (int, error) { parts := strings.Split(dateTimeStr, "-") @@ -426,38 +339,3 @@ func getTimeStampYear(dateTimeStr string) (int, error) { return year, nil } - -// extractDayAndMonth extracts the day and month from a date string. -func extractDayAndMonth(dateStr string) (int, int, error) { - // Split the date string into parts using various delimiters. - parts := strings.FieldsFunc(dateStr, func(r rune) bool { - return r == '-' || r == ' ' || r == 'T' || r == ':' || r == '+' || r == 'Z' - }) - - if len(parts) < 3 { - return 0, 0, fmt.Errorf("Invalid date format: %s", dateStr) - } - - // Extract year, month, and day from the parts. - _, err := strconv.Atoi(parts[0]) - if err != nil { - return 0, 0, err - } - - month, err := strconv.Atoi(parts[1]) - if err != nil { - return 0, 0, err - } - - day, err := strconv.Atoi(parts[2]) - if err != nil { - return 0, 0, err - } - - return day, month, nil -} - -// isLeapYear returns true if the year is a leap year. -func isLeapYear(year int) bool { - return (year%4 == 0 && year%100 != 0) || (year%400 == 0) -} From d36c154151ec7b6944a07f4d081c9e2e1c4323c6 Mon Sep 17 00:00:00 2001 From: sputn1ck Date: Wed, 3 Jan 2024 11:22:35 +0100 Subject: [PATCH 3/3] loopdb: fix unit test --- loopdb/sql_test.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/loopdb/sql_test.go b/loopdb/sql_test.go index 6d3f8de..dce2b37 100644 --- a/loopdb/sql_test.go +++ b/loopdb/sql_test.go @@ -322,6 +322,15 @@ func TestSqliteTypeConversion(t *testing.T) { func TestIssue615(t *testing.T) { ctxb := context.Background() + // Create an invoice to get the timestamp from. + invoice := "lnbc5u1pje2dyusp5qs356crpns9u3we8hw7w9gntfz89zkcaxu6w6h6a" + + "pw6jlgc0cynqpp5y2xdzu4eqasuttxp3nrk72vqdzce3wead7nmf693uqpgx" + + "2hd533qdpcyfnx2etyyp3ks6trddjkuueqw3hkketwwv7kgvrd0py95d6vvv" + + "65z0fzxqzfvcqpjrzjqd82srutzjx82prr234anxdlwvs6peklcc92lp9aqs" + + "q296xnwmqd2rrf9gqqtwqqqqqqqqqqqqqqqqqq9q9qxpqysgq768236z7cx6" + + "gyy766wajrmpnpt6wavkf5nypwyj6r3dcxm89aggq2jm2kznaxvr0lrsqgv7" + + "592upfh5ruyrwzy5tethpzere78xfgwqp64jrpa" + // Create a new sqlite store for testing. sqlDB := NewTestDB(t) @@ -356,7 +365,7 @@ func TestIssue615(t *testing.T) { MaxPrepayRoutingFee: 40, PrepayInvoice: "prepayinvoice", DestAddr: destAddr, - SwapInvoice: "swapinvoice", + SwapInvoice: invoice, MaxSwapRoutingFee: 30, SweepConfTarget: 2, HtlcConfirmations: 2,