-
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
ba1c6fb
cd2b552
4f4f5c9
74bd006
5987960
d42abea
b0ead35
0078293
7a4dd7f
29a2ce7
27293cf
812a052
e5b6d81
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 |
---|---|---|
|
@@ -136,7 +136,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 | ||
|
@@ -205,6 +205,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
+208
to
+210
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. |
||
|
||
// If you change this please also update .github/pull_request_template.md, | ||
// docs/INSTALL.md and GO_IMAGE in lnrpc/gen_protos_docker.sh. | ||
go 1.22.6 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
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/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 { | ||
var db *sqldb.BaseDB | ||
if sqlite { | ||
db = sqldb.NewTestSqliteDB(t).BaseDB | ||
} else { | ||
db = sqldb.NewTestPostgresDB(t, pgFixture).BaseDB | ||
} | ||
|
||
executor := sqldb.NewTransactionExecutor( | ||
db, func(tx *sql.Tx) invpkg.SQLInvoiceQueries { | ||
return db.WithTx(tx) | ||
}, | ||
) | ||
|
||
testClock := clock.NewTestClock(time.Unix(1, 0)) | ||
|
||
return invpkg.NewSQLStore(executor, testClock) | ||
} | ||
|
||
migrationTest := func(t *testing.T, store1 *channeldb.DB, sqlite bool) { | ||
store2 := makeSQLDB(t, sqlite) | ||
ctxb := context.Background() | ||
|
||
const batchSize = 11 | ||
err := invpkg.MigrateInvoicesToSQL( | ||
ctxb, store1.Backend, store1, store2, batchSize, | ||
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. call |
||
) | ||
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. | ||
NumMaxInvoices: 9999, | ||
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. do we know how much the db had initially would be an important information here. |
||
} | ||
result1, err := store1.QueryInvoices(ctxb, query) | ||
require.NoError(t, err) | ||
numInvoices := len(result1.Invoices) | ||
|
||
result2, err := store2.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]) | ||
|
||
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, err := channeldb.Open(test.dbPath) | ||
require.NoError(t, err) | ||
|
||
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.
Nit: define defaults for migration batching