@@ -51,6 +51,7 @@ import (
51
51
"github.com/lightningnetwork/lnd/rpcperms"
52
52
"github.com/lightningnetwork/lnd/signal"
53
53
"github.com/lightningnetwork/lnd/sqldb"
54
+ "github.com/lightningnetwork/lnd/sqldb/sqlc"
54
55
"github.com/lightningnetwork/lnd/sweep"
55
56
"github.com/lightningnetwork/lnd/walletunlocker"
56
57
"github.com/lightningnetwork/lnd/watchtower"
@@ -60,6 +61,16 @@ import (
60
61
"gopkg.in/macaroon-bakery.v2/bakery"
61
62
)
62
63
64
+ const (
65
+ // invoiceMigrationBatchSize is the number of invoices that will be
66
+ // migrated in a single batch.
67
+ invoiceMigrationBatchSize = 1000
68
+
69
+ // invoiceMigration is the version of the migration that will be used to
70
+ // migrate invoices from the kvdb to the sql database.
71
+ invoiceMigration = 7
72
+ )
73
+
63
74
// GrpcRegistrar is an interface that must be satisfied by an external subserver
64
75
// that wants to be able to register its own gRPC server onto lnd's main
65
76
// grpc.Server instance.
@@ -932,10 +943,10 @@ type DatabaseInstances struct {
932
943
// the btcwallet's loader.
933
944
WalletDB btcwallet.LoaderOption
934
945
935
- // NativeSQLStore is a pointer to a native SQL store that can be used
936
- // for native SQL queries for tables that already support it. This may
937
- // be nil if the use-native-sql flag was not set.
938
- NativeSQLStore * sqldb.BaseDB
946
+ // NativeSQLStore holds a reference to the native SQL store that can
947
+ // be used for native SQL queries for tables that already support it.
948
+ // This may be nil if the use-native-sql flag was not set.
949
+ NativeSQLStore sqldb.DB
939
950
}
940
951
941
952
// DefaultDatabaseBuilder is a type that builds the default database backends
@@ -1038,7 +1049,7 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
1038
1049
if err != nil {
1039
1050
cleanUp ()
1040
1051
1041
- err : = fmt .Errorf ("unable to open graph DB: %w" , err )
1052
+ err = fmt .Errorf ("unable to open graph DB: %w" , err )
1042
1053
d .logger .Error (err )
1043
1054
1044
1055
return nil , nil , err
@@ -1072,51 +1083,69 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
1072
1083
case err != nil :
1073
1084
cleanUp ()
1074
1085
1075
- err : = fmt .Errorf ("unable to open graph DB: %w" , err )
1086
+ err = fmt .Errorf ("unable to open graph DB: %w" , err )
1076
1087
d .logger .Error (err )
1077
1088
return nil , nil , err
1078
1089
}
1079
1090
1080
- // Instantiate a native SQL invoice store if the flag is set.
1091
+ // Instantiate a native SQL store if the flag is set.
1081
1092
if d .cfg .DB .UseNativeSQL {
1082
- // KV invoice db resides in the same database as the channel
1083
- // state DB. Let's query the database to see if we have any
1084
- // invoices there. If we do, we won't allow the user to start
1085
- // lnd with native SQL enabled, as we don't currently migrate
1086
- // the invoices to the new database schema.
1087
- invoiceSlice , err := dbs .ChanStateDB .QueryInvoices (
1088
- ctx , invoices.InvoiceQuery {
1089
- NumMaxInvoices : 1 ,
1090
- },
1091
- )
1092
- if err != nil {
1093
- cleanUp ()
1094
- d .logger .Errorf ("Unable to query KV invoice DB: %v" ,
1095
- err )
1093
+ migrations := sqldb .GetMigrations ()
1094
+
1095
+ // If the user has not explicitly disabled the SQL invoice
1096
+ // migration, attach the custom migration function to invoice
1097
+ // migration (version 7). Even if this custom migration is
1098
+ // disabled, the regular native SQL store migrations will still
1099
+ // run. If the database version is already above this custom
1100
+ // migration's version (7), it will be skipped permanently,
1101
+ // regardless of the flag.
1102
+ if ! d .cfg .DB .SkipSQLInvoiceMigration {
1103
+ migrationFn := func (tx * sqlc.Queries ) error {
1104
+ return invoices .MigrateInvoicesToSQL (
1105
+ ctx , dbs .ChanStateDB .Backend ,
1106
+ dbs .ChanStateDB , tx ,
1107
+ invoiceMigrationBatchSize ,
1108
+ )
1109
+ }
1096
1110
1097
- return nil , nil , err
1111
+ // Make sure we attach the custom migration function to
1112
+ // the correct migration version.
1113
+ for i := 0 ; i < len (migrations ); i ++ {
1114
+ if migrations [i ].Version != invoiceMigration {
1115
+ continue
1116
+ }
1117
+
1118
+ migrations [i ].MigrationFn = migrationFn
1119
+ }
1098
1120
}
1099
1121
1100
- if len (invoiceSlice .Invoices ) > 0 {
1122
+ // We need to apply all migrations to the native SQL store
1123
+ // before we can use it.
1124
+ err = dbs .NativeSQLStore .ApplyAllMigrations (ctx , migrations )
1125
+ if err != nil {
1101
1126
cleanUp ()
1102
- err := fmt .Errorf ("found invoices in the KV invoice " +
1103
- "DB, migration to native SQL is not yet " +
1104
- "supported" )
1127
+ err = fmt .Errorf ("faild to run migrations for the " +
1128
+ "native SQL store: %w" , err )
1105
1129
d .logger .Error (err )
1106
1130
1107
1131
return nil , nil , err
1108
1132
}
1109
1133
1134
+ // With the DB ready and migrations applied, we can now create
1135
+ // the base DB and transaction executor for the native SQL
1136
+ // invoice store.
1137
+ baseDB := dbs .NativeSQLStore .GetBaseDB ()
1110
1138
executor := sqldb .NewTransactionExecutor (
1111
- dbs .NativeSQLStore ,
1112
- func (tx * sql.Tx ) invoices.SQLInvoiceQueries {
1113
- return dbs .NativeSQLStore .WithTx (tx )
1139
+ baseDB , func (tx * sql.Tx ) invoices.SQLInvoiceQueries {
1140
+ return baseDB .WithTx (tx )
1114
1141
},
1115
1142
)
1116
1143
1117
- dbs . InvoiceDB = invoices .NewSQLStore (
1144
+ sqlInvoiceDB : = invoices .NewSQLStore (
1118
1145
executor , clock .NewDefaultClock (),
1119
1146
)
1147
+
1148
+ dbs .InvoiceDB = sqlInvoiceDB
1120
1149
} else {
1121
1150
dbs .InvoiceDB = dbs .ChanStateDB
1122
1151
}
@@ -1129,7 +1158,7 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
1129
1158
if err != nil {
1130
1159
cleanUp ()
1131
1160
1132
- err : = fmt .Errorf ("unable to open %s database: %w" ,
1161
+ err = fmt .Errorf ("unable to open %s database: %w" ,
1133
1162
lncfg .NSTowerClientDB , err )
1134
1163
d .logger .Error (err )
1135
1164
return nil , nil , err
@@ -1144,7 +1173,7 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
1144
1173
if err != nil {
1145
1174
cleanUp ()
1146
1175
1147
- err : = fmt .Errorf ("unable to open %s database: %w" ,
1176
+ err = fmt .Errorf ("unable to open %s database: %w" ,
1148
1177
lncfg .NSTowerServerDB , err )
1149
1178
d .logger .Error (err )
1150
1179
return nil , nil , err
0 commit comments