11package  accounts
22
33import  (
4+ 	"bytes" 
45	"context" 
56	"database/sql" 
67	"errors" 
@@ -11,6 +12,7 @@ import (
1112
1213	"github.com/davecgh/go-spew/spew" 
1314	"github.com/lightninglabs/lightning-terminal/db/sqlc" 
15+ 	"github.com/lightningnetwork/lnd/kvdb" 
1416	"github.com/pmezard/go-difflib/difflib" 
1517)
1618
2426// MigrateAccountStoreToSQL runs the migration of all accounts and indices from 
2527// the KV database to the SQL database. The migration is done in a single 
2628// transaction to ensure that all accounts are migrated or none at all. 
27- func  MigrateAccountStoreToSQL (ctx  context.Context , kvStore  * BoltStore ,
29+ func  MigrateAccountStoreToSQL (ctx  context.Context , kvStore  kvdb. Backend ,
2830	tx  SQLQueries ) error  {
2931
3032	log .Infof ("Starting migration of the KV accounts store to SQL" )
@@ -47,12 +49,12 @@ func MigrateAccountStoreToSQL(ctx context.Context, kvStore *BoltStore,
4749// migrateAccountsToSQL runs the migration of all accounts from the KV database 
4850// to the SQL database. The migration is done in a single transaction to ensure 
4951// that all accounts are migrated or none at all. 
50- func  migrateAccountsToSQL (ctx  context.Context , kvStore  * BoltStore ,
52+ func  migrateAccountsToSQL (ctx  context.Context , kvStore  kvdb. Backend ,
5153	tx  SQLQueries ) error  {
5254
5355	log .Infof ("Starting migration of accounts from KV to SQL" )
5456
55- 	kvAccounts , err  :=  kvStore . Accounts ( ctx )
57+ 	kvAccounts , err  :=  getBBoltAccounts ( kvStore )
5658	if  err  !=  nil  {
5759		return  err 
5860	}
@@ -104,6 +106,51 @@ func migrateAccountsToSQL(ctx context.Context, kvStore *BoltStore,
104106	return  nil 
105107}
106108
109+ // getBBoltAccounts is a helper function that fetches all accounts from the 
110+ // Bbolt store, by iterating directly over the buckets, without needing to 
111+ // use any public functions of the BoltStore struct. 
112+ func  getBBoltAccounts (db  kvdb.Backend ) ([]* OffChainBalanceAccount , error ) {
113+ 	var  accounts  []* OffChainBalanceAccount 
114+ 	err  :=  db .View (func (tx  kvdb.RTx ) error  {
115+ 		// This function will be called in the ForEach and receive 
116+ 		// the key and value of each account in the DB. The key, which 
117+ 		// is also the ID is not used because it is also marshaled into 
118+ 		// the value. 
119+ 		readFn  :=  func (k , v  []byte ) error  {
120+ 			// Skip the two special purpose keys. 
121+ 			if  bytes .Equal (k , lastAddIndexKey ) || 
122+ 				bytes .Equal (k , lastSettleIndexKey ) {
123+ 
124+ 				return  nil 
125+ 			}
126+ 
127+ 			// There should be no sub-buckets. 
128+ 			if  v  ==  nil  {
129+ 				return  fmt .Errorf ("invalid bucket structure" )
130+ 			}
131+ 
132+ 			account , err  :=  deserializeAccount (v )
133+ 			if  err  !=  nil  {
134+ 				return  err 
135+ 			}
136+ 
137+ 			accounts  =  append (accounts , account )
138+ 			return  nil 
139+ 		}
140+ 
141+ 		// We know the bucket should exist since it's created when 
142+ 		// the account storage is initialized. 
143+ 		return  tx .ReadBucket (accountBucketName ).ForEach (readFn )
144+ 	}, func () {
145+ 		accounts  =  nil 
146+ 	})
147+ 	if  err  !=  nil  {
148+ 		return  nil , err 
149+ 	}
150+ 
151+ 	return  accounts , nil 
152+ }
153+ 
107154// migrateSingleAccountToSQL runs the migration for a single account from the 
108155// KV database to the SQL database. 
109156func  migrateSingleAccountToSQL (ctx  context.Context ,
@@ -163,12 +210,12 @@ func migrateSingleAccountToSQL(ctx context.Context,
163210
164211// migrateAccountsIndicesToSQL runs the migration for the account indices from 
165212// the KV database to the SQL database. 
166- func  migrateAccountsIndicesToSQL (ctx  context.Context , kvStore  * BoltStore ,
213+ func  migrateAccountsIndicesToSQL (ctx  context.Context , kvStore  kvdb. Backend ,
167214	tx  SQLQueries ) error  {
168215
169216	log .Infof ("Starting migration of accounts indices from KV to SQL" )
170217
171- 	addIndex , settleIndex , err  :=  kvStore . LastIndexes ( ctx )
218+ 	addIndex , settleIndex , err  :=  getBBoltIndices ( kvStore )
172219	if  errors .Is (err , ErrNoInvoiceIndexKnown ) {
173220		log .Infof ("No indices found in KV store, skipping migration" )
174221		return  nil 
@@ -211,6 +258,40 @@ func migrateAccountsIndicesToSQL(ctx context.Context, kvStore *BoltStore,
211258	return  nil 
212259}
213260
261+ // getBBoltIndices is a helper function that fetches the índices from the 
262+ // Bbolt store, by iterating directly over the buckets, without needing to 
263+ // use any public functions of the BoltStore struct. 
264+ func  getBBoltIndices (db  kvdb.Backend ) (uint64 , uint64 , error ) {
265+ 	var  (
266+ 		addValue , settleValue  []byte 
267+ 	)
268+ 	err  :=  db .View (func (tx  kvdb.RTx ) error  {
269+ 		bucket  :=  tx .ReadBucket (accountBucketName )
270+ 		if  bucket  ==  nil  {
271+ 			return  ErrAccountBucketNotFound 
272+ 		}
273+ 
274+ 		addValue  =  bucket .Get (lastAddIndexKey )
275+ 		if  len (addValue ) ==  0  {
276+ 			return  ErrNoInvoiceIndexKnown 
277+ 		}
278+ 
279+ 		settleValue  =  bucket .Get (lastSettleIndexKey )
280+ 		if  len (settleValue ) ==  0  {
281+ 			return  ErrNoInvoiceIndexKnown 
282+ 		}
283+ 
284+ 		return  nil 
285+ 	}, func () {
286+ 		addValue , settleValue  =  nil , nil 
287+ 	})
288+ 	if  err  !=  nil  {
289+ 		return  0 , 0 , err 
290+ 	}
291+ 
292+ 	return  byteOrder .Uint64 (addValue ), byteOrder .Uint64 (settleValue ), nil 
293+ }
294+ 
214295// overrideAccountTimeZone overrides the time zone of the account to the local 
215296// time zone and chops off the nanosecond part for comparison. This is needed 
216297// because KV database stores times as-is which as an unwanted side effect would 
0 commit comments