-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
invoices: migrate KV invoices to native SQL for users of KV SQL backends #8831
base: master
Are you sure you want to change the base?
Changes from all commits
0a33e33
4ea8100
962b9de
5c92bf7
075a6be
ddfb93a
7fba3ab
1b02a4c
c3f1494
799d07e
160c3e6
e203dfc
da14052
228e623
b32fe45
93017aa
18091a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,7 +138,7 @@ require ( | |
github.com/opencontainers/image-spec v1.0.2 // indirect | ||
github.com/opencontainers/runc v1.1.12 // indirect | ||
github.com/ory/dockertest/v3 v3.10.0 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 | ||
github.com/prometheus/client_model v0.2.0 // indirect | ||
github.com/prometheus/common v0.26.0 // indirect | ||
github.com/prometheus/procfs v0.6.0 // indirect | ||
|
@@ -207,6 +207,10 @@ replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 | |
// allows us to specify that as an option. | ||
replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display | ||
|
||
// Temporary replace until https://github.com/lightningnetwork/lnd/pull/8831 is | ||
// merged. | ||
replace github.com/lightningnetwork/lnd/sqldb => ./sqldb | ||
Comment on lines
+210
to
+212
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like this commit should be dropped. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this is still needed as we modify the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is close to merge - should we not split this up into 2 PRs? 1) that updates sqldb and 2) that points to that one? so that we dont merge with this replacement. or is the plan just to do an immediate follow up removing the replace? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both works imo, I'm happy to split it up once we get all approves :) |
||
|
||
// If you change this please also update docs/INSTALL.md and GO_VERSION in | ||
// Makefile (then run `make lint` to see where else it needs to be updated as | ||
// well). | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package invoices_test | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"testing" | ||
"time" | ||
|
||
"github.com/lightningnetwork/lnd/channeldb" | ||
"github.com/lightningnetwork/lnd/clock" | ||
invpkg "github.com/lightningnetwork/lnd/invoices" | ||
"github.com/lightningnetwork/lnd/sqldb" | ||
"github.com/lightningnetwork/lnd/sqldb/sqlc" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// TestMigrationWithChannelDB tests the migration of invoices from a bolt backed | ||
// channel.db to a SQL database. Note that this test does not attempt to be a | ||
// complete migration test for all invoice types but rather is added as a tool | ||
// for developers and users to debug invoice migration issues with an actual | ||
// channel.db file. | ||
func TestMigrationWithChannelDB(t *testing.T) { | ||
// First create a shared Postgres instance so we don't spawn a new | ||
// docker container for each test. | ||
pgFixture := sqldb.NewTestPgFixture( | ||
t, sqldb.DefaultPostgresFixtureLifetime, | ||
) | ||
t.Cleanup(func() { | ||
pgFixture.TearDown(t) | ||
}) | ||
|
||
makeSQLDB := func(t *testing.T, sqlite bool) (*invpkg.SQLStore, | ||
*sqldb.TransactionExecutor[*sqlc.Queries]) { | ||
|
||
var db *sqldb.BaseDB | ||
if sqlite { | ||
db = sqldb.NewTestSqliteDB(t).BaseDB | ||
} else { | ||
db = sqldb.NewTestPostgresDB(t, pgFixture).BaseDB | ||
} | ||
|
||
invoiceExecutor := sqldb.NewTransactionExecutor( | ||
db, func(tx *sql.Tx) invpkg.SQLInvoiceQueries { | ||
return db.WithTx(tx) | ||
}, | ||
ellemouton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
genericExecutor := sqldb.NewTransactionExecutor( | ||
db, func(tx *sql.Tx) *sqlc.Queries { | ||
return db.WithTx(tx) | ||
}, | ||
) | ||
|
||
testClock := clock.NewTestClock(time.Unix(1, 0)) | ||
|
||
return invpkg.NewSQLStore(invoiceExecutor, testClock), | ||
genericExecutor | ||
} | ||
|
||
migrationTest := func(t *testing.T, kvStore *channeldb.DB, | ||
sqlite bool) { | ||
|
||
sqlInvoiceStore, sqlStore := makeSQLDB(t, sqlite) | ||
ctxb := context.Background() | ||
|
||
const batchSize = 11 | ||
ellemouton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var opts sqldb.MigrationTxOptions | ||
err := sqlStore.ExecTx( | ||
ctxb, &opts, func(tx *sqlc.Queries) error { | ||
return invpkg.MigrateInvoicesToSQL( | ||
ctxb, kvStore.Backend, kvStore, tx, | ||
batchSize, | ||
) | ||
}, func() {}, | ||
) | ||
require.NoError(t, err) | ||
|
||
// MigrateInvoices will check if the inserted invoice equals to | ||
// the migrated one, but as a sanity check, we'll also fetch the | ||
// invoices from the store and compare them to the original | ||
// invoices. | ||
query := invpkg.InvoiceQuery{ | ||
IndexOffset: 0, | ||
// As a sanity check, fetch more invoices than we have | ||
// to ensure that we did not add any extra invoices. | ||
// Note that we don't really have a way to know the | ||
// exact number of invoices in the bolt db without first | ||
// iterating over all of them, but for test purposes | ||
// constant should be enough. | ||
NumMaxInvoices: 9999, | ||
ziggie1984 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
result1, err := kvStore.QueryInvoices(ctxb, query) | ||
require.NoError(t, err) | ||
numInvoices := len(result1.Invoices) | ||
|
||
result2, err := sqlInvoiceStore.QueryInvoices(ctxb, query) | ||
require.NoError(t, err) | ||
require.Equal(t, numInvoices, len(result2.Invoices)) | ||
|
||
// Simply zero out the add index so we don't fail on that when | ||
// comparing. | ||
for i := 0; i < numInvoices; i++ { | ||
result1.Invoices[i].AddIndex = 0 | ||
result2.Invoices[i].AddIndex = 0 | ||
|
||
// We need to override the timezone of the invoices as | ||
// the provided DB vs the test runners local time zone | ||
// might be different. | ||
invpkg.OverrideInvoiceTimeZone(&result1.Invoices[i]) | ||
invpkg.OverrideInvoiceTimeZone(&result2.Invoices[i]) | ||
|
||
require.Equal( | ||
t, result1.Invoices[i], result2.Invoices[i], | ||
) | ||
} | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
dbPath string | ||
}{ | ||
{ | ||
"empty", | ||
t.TempDir(), | ||
}, | ||
{ | ||
"testdata", | ||
"testdata", | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
test := test | ||
t.Run(test.name, func(t *testing.T) { | ||
store := channeldb.OpenForTesting(t, test.dbPath) | ||
|
||
t.Run("Postgres", func(t *testing.T) { | ||
migrationTest(t, store, false) | ||
}) | ||
|
||
t.Run("SQLite", func(t *testing.T) { | ||
migrationTest(t, store, true) | ||
}) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dont we still want this check for anyone who has set
d.cfg.DB.SkipSQLInvoiceMigration=true
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and to protect against users who had a bbolt invoice store before?