From e4ee3effdfaccb1a4748ebd04c45179c2d8baf7e Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Tue, 26 Jul 2022 14:05:24 +0000 Subject: [PATCH] relocate scantxoutset code to `base_proto.bitcoin.misc` --- mmgen/base_proto/bitcoin/misc.py | 62 ++++++++++++++++++++++++++++++ mmgen/base_proto/bitcoin/tw/ctl.py | 35 ++--------------- 2 files changed, 65 insertions(+), 32 deletions(-) create mode 100755 mmgen/base_proto/bitcoin/misc.py diff --git a/mmgen/base_proto/bitcoin/misc.py b/mmgen/base_proto/bitcoin/misc.py new file mode 100755 index 00000000..39e89dbf --- /dev/null +++ b/mmgen/base_proto/bitcoin/misc.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# +# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet +# Copyright (C)2013-2022 The MMGen Project +# Licensed under the GNU General Public License, Version 3: +# https://www.gnu.org/licenses +# Public project repositories: +# https://github.com/mmgen/mmgen +# https://gitlab.com/mmgen/mmgen + +""" +base_proto.bitcoin.misc: miscellaneous functions for Bitcoin base protocol +""" + +from ...globalvars import g +from ...util import msg,msg_r + +async def scantxoutset(rpc,descriptor_list): + + import asyncio + + async def do_scan(): + return await rpc.call( + 'scantxoutset', + 'start', + descriptor_list, + timeout = 720 ) # call may take several minutes to complete + + async def do_status(): + + CR = '\n' if g.test_suite else '\r' + sleep_secs = 0.1 if g.test_suite else 2 + m = f'{CR}Scanning UTXO set: ' + msg_r(m + '0% completed ') + + while True: + await asyncio.sleep(sleep_secs) + res = await rpc.call('scantxoutset','status') + if res: + msg_r(m + f'{res["progress"]}% completed ') + if task1.done(): + msg(m + '100% completed') + return + + res = await rpc.call('scantxoutset','status') + if res and res.get('progress'): + msg_r('Aborting scan in progress...') + await rpc.call('scantxoutset','abort') + await asyncio.sleep(1) + msg('done') + + if rpc.backend.name == 'aiohttp': + task1 = asyncio.create_task( do_scan() ) + task2 = asyncio.create_task( do_status() ) + ret = await task1 + await task2 + else: + msg_r(f'Scanning UTXO set, this could take several minutes...') + ret = await do_scan() + msg('done') + + return ret diff --git a/mmgen/base_proto/bitcoin/tw/ctl.py b/mmgen/base_proto/bitcoin/tw/ctl.py index e6db771b..e1fe72ca 100755 --- a/mmgen/base_proto/bitcoin/tw/ctl.py +++ b/mmgen/base_proto/bitcoin/tw/ctl.py @@ -99,38 +99,8 @@ class BitcoinTrackingWallet(TrackingWallet): @write_mode async def rescan_addresses(self,coin_addrs): - import asyncio - - async def do_scan(): - return await self.rpc.call( - 'scantxoutset', - 'start', - [f'addr({a})' for a in coin_addrs], - timeout = 720 ) # call may take several minutes to complete - - async def do_status(): - m = f'{CR}Scanning UTXO set: ' - msg_r(m) - while True: - await asyncio.sleep(2) - res = await self.rpc.call('scantxoutset','status') - if res: - msg_r(m + f'{res["progress"]}% completed ') - if task1.done(): - msg('') - return - - CR = '\r' - - if self.rpc.backend.name == 'aiohttp': - task1 = asyncio.create_task( do_scan() ) - task2 = asyncio.create_task( do_status() ) - res = await task1 - await task2 - else: - msg_r(f'Scanning UTXO set, this could take several minutes...') - res = await do_scan() - msg('done') + from ..misc import scantxoutset + res = await scantxoutset( self.rpc, [f'addr({addr})' for addr in coin_addrs] ) if not res['success']: msg('UTXO scanning failed or was interrupted') @@ -143,6 +113,7 @@ class BitcoinTrackingWallet(TrackingWallet): len(blocks), suf(blocks) )) vmsg(f'Blocks to rescan: {fmt_list(blocks,fmt="bare")}') + CR = '\n' if g.test_suite else '\r' for n,block in enumerate(blocks): msg_r(f'{CR}Rescanning block: {block} ({n+1}/{len(blocks)})') # httplib seems to require fresh connection here, so specify timeout