99import time
1010import traceback
1111from functools import wraps
12+ from datetime import datetime
1213
1314from embit import bip32
1415from embit .descriptor import Descriptor as EmbitDescriptor
@@ -185,7 +186,7 @@ def _sync(self):
185186 if self .sock .is_socket_closed ():
186187 logger .info ("Not Syncing as socket is broken" )
187188 return
188- logger .info (f"Syncing ... { self . sock } " )
189+ logger .info (f"Syncing ..." )
189190 subscription_logging_counter = 0
190191 # subscribe to all scripts
191192 all_scripts = Script .query .all ()
@@ -196,16 +197,18 @@ def _sync(self):
196197 continue
197198 subscription_logging_counter += 1
198199 if subscription_logging_counter % 100 == 0 :
199- progress_percent = subscription_logging_counter / all_scripts_len * 100
200- self .progress_percent = int (progress_percent )
200+ self .progress_percent = int (
201+ subscription_logging_counter / all_scripts_len * 100
202+ )
201203 logger .info (
202- f"Now subscribed to { subscription_logging_counter } scripthashes ({ int ( progress_percent ) } %)"
204+ f"Now subscribed to { subscription_logging_counter } scripthashes ({ self . progress_percent } %)"
203205 )
204206
205207 res = self .sock .call ("blockchain.scripthash.subscribe" , [sc .scripthash ])
206208 if res != sc .state :
207209 self .sync_script (sc , res )
208210 self .progress_percent = 100
211+ logger .info (f"Finished Syncing { all_scripts_len } scripts" )
209212
210213 def sync (self , asyncc = True ):
211214 if asyncc :
@@ -219,13 +222,76 @@ def sync(self, asyncc=True):
219222 else :
220223 self ._sync ()
221224
225+ # ToDo: subcribe_scripts and sync is very similiar. One does it for all of the scripts in the DB,
226+ # the other one only for a specific descriptor. We should merge them!
227+ def subcribe_scripts (self , descriptor , asyncc = True ):
228+ """Takes a descriptor and syncs all the scripts into the DB
229+ creates a new thread doing that.
230+ """
231+ if asyncc :
232+ t = FlaskThread (
233+ target = self ._subcribe_scripts ,
234+ args = [
235+ descriptor .id ,
236+ ],
237+ )
238+ t .start ()
239+ else :
240+ self ._subcribe_scripts (descriptor .id )
241+
242+ def _subcribe_scripts (self , descriptor_id : int ) -> None :
243+ descriptor : Descriptor = Descriptor .query .filter (
244+ Descriptor .id == descriptor_id
245+ ).first ()
246+ logger .info (f"Starting sync/subscribe for { descriptor .descriptor [:30 ]} " )
247+ # subscribe to all scripts in a thread to speed up creation of the wallet
248+ sc : Script
249+ relevant_scripts_query = Script .query .filter_by (descriptor = descriptor )
250+ relevant_scripts = relevant_scripts_query .all ()
251+ relevant_scripts_count = relevant_scripts_query .count ()
252+
253+ count_scripts = 0
254+ count_syned_scripts = 0
255+ ts = datetime .now ()
256+ for sc in relevant_scripts :
257+ # subscribing
258+ res = self .sock .call ("blockchain.scripthash.subscribe" , [sc .scripthash ])
259+ count_scripts += 1
260+
261+ # syncing
262+ if res != sc .state :
263+ self .sync_script (sc , res )
264+ count_syned_scripts += 1
265+
266+ # logging and expose progress
267+ if count_scripts % 100 == 0 :
268+ logger .info (
269+ f"Now subscribed to { count_syned_scripts } of { relevant_scripts_count } scripthashes ({ self .progress_percent } %) (via importdescriptor))"
270+ )
271+ self .progress_percent = int (
272+ count_syned_scripts / relevant_scripts_count * 100
273+ )
274+
275+ self .progress_percent = 100
276+ ts_diff_s = int ((datetime .now () - ts ).total_seconds ())
277+ logger .info (
278+ f"Finished Subscribing and syncing for descriptor { descriptor .descriptor [:30 ]} in { ts_diff_s } "
279+ )
280+ logger .info (
281+ f"A total of { len (relevant_scripts )} scripts got subscribed where { count_syned_scripts } got synced"
282+ )
283+
222284 def sync_script (self , script , state = None ):
223285 # Normally every script has 1-2 transactions and 0-1 utxos,
224286 # so even if we delete everything and resync it's ok
225287 # except donation addresses that may have many txs...
226- logger .info (
288+ logger .debug (
227289 f"Script { script .scripthash [:7 ]} is not synced { script .state } != { state } "
228290 )
291+ if script .state != None :
292+ logger .info (
293+ f"Script { script .scripthash [:7 ]} has an update from state { script .state } to { state } "
294+ )
229295 script_pubkey = script .script_pubkey
230296 internal = script .descriptor .internal
231297 # get all transactions, utxos and update balances
@@ -1269,41 +1335,3 @@ def importdescriptor(
12691335 db .session .commit ()
12701336 self .subcribe_scripts (d )
12711337 return d
1272-
1273- def subcribe_scripts (self , descriptor , asyncc = True ):
1274- """Takes a descriptor and syncs all the scripts into the DB
1275- creates a new thread doing that.
1276- """
1277- if asyncc :
1278- t = FlaskThread (
1279- target = self ._subcribe_scripts ,
1280- args = [
1281- descriptor .id ,
1282- ],
1283- )
1284- t .start ()
1285- else :
1286- self ._subcribe_scripts (descriptor .id )
1287-
1288- def _subcribe_scripts (self , descriptor_id : Descriptor ) -> None :
1289-
1290- descriptor : Descriptor = Descriptor .query .filter (
1291- Descriptor .id == descriptor_id
1292- ).first ()
1293- # subscribe to all scripts in a thread to speed up creation of the wallet
1294- sc : Script
1295- relevant_scripts_query = Script .query .filter_by (descriptor = descriptor )
1296- relevant_scripts = relevant_scripts_query .all ()
1297- relevant_scripts_count = relevant_scripts_query .count ()
1298-
1299- count_syned_scripts = 0
1300- for sc in relevant_scripts :
1301- res = self .sock .call ("blockchain.scripthash.subscribe" , [sc .scripthash ])
1302- if res != sc .state :
1303- count_syned_scripts = count_syned_scripts + 1
1304- self .progress_percent = count_syned_scripts / count_syned_scripts * 100
1305- self .sync_script (sc , res )
1306- self .progress_percent = 100
1307- logger .info (
1308- f"subscribed to { len (relevant_scripts )} scripts for descriptor { descriptor .descriptor [:30 ]} ... where { count_syned_scripts } got synced"
1309- )
0 commit comments