electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit cefa4762ba904ef92d32b4c90005013dd7a7ac4a
parent bcdb72ae93f5e42b8c7f7d0eafb89a767a91f12f
Author: ThomasV <thomasv@electrum.org>
Date:   Tue, 10 Sep 2019 08:57:40 +0200

do not create multiple instances of SimpleConfig (fix #5629). Add config field to wallet

Diffstat:
Melectrum/commands.py | 10+++++-----
Melectrum/daemon.py | 10+++-------
Melectrum/gui/kivy/main_window.py | 4++--
Melectrum/gui/kivy/uix/dialogs/tx_dialog.py | 3+--
Melectrum/gui/kivy/uix/screens.py | 11+++++------
Melectrum/gui/qt/address_list.py | 2+-
Melectrum/gui/qt/main_window.py | 10+++++-----
Melectrum/gui/qt/request_list.py | 2+-
Melectrum/lnpeer.py | 4++--
Melectrum/tests/test_wallet_vertical.py | 80++++++++++++++++++++++++++++++++++++++++----------------------------------------
Melectrum/wallet.py | 65++++++++++++++++++++++++++++++++---------------------------------
11 files changed, 97 insertions(+), 104 deletions(-)

diff --git a/electrum/commands.py b/electrum/commands.py @@ -541,7 +541,7 @@ class Commands: fee_estimator = partial(SimpleConfig.estimate_fee_for_feerate, fee_per_kb) else: fee_estimator = fee - tx = wallet.make_unsigned_transaction(coins, final_outputs, self.config, fee_estimator, change_addr) + tx = wallet.make_unsigned_transaction(coins, final_outputs, fee_estimator, change_addr) if locktime is not None: tx.locktime = locktime if rbf is None: @@ -724,7 +724,7 @@ class Commands: @command('w') async def listrequests(self, pending=False, expired=False, paid=False, wallet=None): """List the payment requests you made.""" - out = wallet.get_sorted_requests(self.config) + out = wallet.get_sorted_requests() if pending: f = PR_UNPAID elif expired: @@ -762,7 +762,7 @@ class Commands: amount = satoshis(amount) expiration = int(expiration) if expiration else None req = wallet.make_payment_request(addr, amount, memo, expiration) - wallet.add_payment_request(req, self.config) + wallet.add_payment_request(req) out = wallet.get_request(addr) return self._format_request(out) @@ -787,13 +787,13 @@ class Commands: @command('w') async def rmrequest(self, address, wallet=None): """Remove a payment request""" - return wallet.remove_payment_request(address, self.config) + return wallet.remove_payment_request(address) @command('w') async def clearrequests(self, wallet=None): """Remove all payment requests""" for k in list(wallet.receive_requests.keys()): - wallet.remove_payment_request(k, self.config) + wallet.remove_payment_request(k) @command('n') async def notify(self, address: str, URL: str): diff --git a/electrum/daemon.py b/electrum/daemon.py @@ -430,20 +430,16 @@ class Daemon(Logger): return True async def run_cmdline(self, config_options): - config = SimpleConfig(config_options) - # FIXME this is ugly... - config.fee_estimates = self.network.config.fee_estimates.copy() - config.mempool_fees = self.network.config.mempool_fees.copy() - cmdname = config.get('cmd') + cmdname = config_options['cmd'] cmd = known_commands[cmdname] # arguments passed to function - args = map(lambda x: config.get(x), cmd.params) + args = [config_options.get(x) for x in cmd.params] # decode json arguments args = [json_decode(i) for i in args] # options kwargs = {} for x in cmd.options: - kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)) + kwargs[x] = config_options.get(x) if cmd.requires_wallet: kwargs['wallet_path'] = config_options.get('wallet_path') func = getattr(self.cmd_runner, cmd.name) diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py @@ -817,7 +817,7 @@ class ElectrumWindow(App): from electrum.transaction import TxOutput if run_hook('abort_send', self): return '' - inputs = self.wallet.get_spendable_coins(None, self.electrum_config) + inputs = self.wallet.get_spendable_coins(None) if not inputs: return '' addr = None @@ -827,7 +827,7 @@ class ElectrumWindow(App): addr = self.wallet.dummy_address() outputs = [TxOutput(TYPE_ADDRESS, addr, '!')] try: - tx = self.wallet.make_unsigned_transaction(inputs, outputs, self.electrum_config) + tx = self.wallet.make_unsigned_transaction(inputs, outputs) except NoDynamicFeeEstimates as e: Clock.schedule_once(lambda dt, bound_e=e: self.show_error(str(bound_e))) return '' diff --git a/electrum/gui/kivy/uix/dialogs/tx_dialog.py b/electrum/gui/kivy/uix/dialogs/tx_dialog.py @@ -223,8 +223,7 @@ class TxDialog(Factory.Popup): return try: new_tx = self.wallet.bump_fee(tx=self.tx, - new_fee_rate=new_fee_rate, - config=self.app.electrum_config) + new_fee_rate=new_fee_rate) except CannotBumpFee as e: self.app.show_error(str(e)) return diff --git a/electrum/gui/kivy/uix/screens.py b/electrum/gui/kivy/uix/screens.py @@ -360,10 +360,9 @@ class SendScreen(CScreen): def _do_send_onchain(self, amount, message, outputs, rbf): # make unsigned transaction - config = self.app.electrum_config - coins = self.app.wallet.get_spendable_coins(None, config) + coins = self.app.wallet.get_spendable_coins(None) try: - tx = self.app.wallet.make_unsigned_transaction(coins, outputs, config, None) + tx = self.app.wallet.make_unsigned_transaction(coins, outputs, None) except NotEnoughFunds: self.app.show_error(_("Not enough funds")) return @@ -467,7 +466,7 @@ class ReceiveScreen(CScreen): return self.screen.address = addr req = self.app.wallet.make_payment_request(addr, amount, message, self.expiry()) - self.app.wallet.add_payment_request(req, self.app.electrum_config) + self.app.wallet.add_payment_request(req) key = addr self.clear() self.update() @@ -497,7 +496,7 @@ class ReceiveScreen(CScreen): def update(self): if not self.loaded: return - _list = self.app.wallet.get_sorted_requests(self.app.electrum_config) + _list = self.app.wallet.get_sorted_requests() requests_container = self.screen.ids.requests_container requests_container.data = [self.get_card(item) for item in _list if item.get('status') != PR_PAID] @@ -512,7 +511,7 @@ class ReceiveScreen(CScreen): d.open() def clear_requests_dialog(self): - expired = [req for req in self.app.wallet.get_sorted_requests(self.app.electrum_config) if req['status'] == PR_EXPIRED] + expired = [req for req in self.app.wallet.get_sorted_requests() if req['status'] == PR_EXPIRED] if len(expired) == 0: return def callback(c): diff --git a/electrum/gui/qt/address_list.py b/electrum/gui/qt/address_list.py @@ -251,7 +251,7 @@ class AddressList(MyTreeView): else: menu.addAction(_("Unfreeze"), lambda: self.parent.set_frozen_state_of_addresses([addr], False)) - coins = self.wallet.get_spendable_coins(addrs, config=self.config) + coins = self.wallet.get_spendable_coins(addrs) if coins: menu.addAction(_("Spend from"), lambda: self.parent.spend_coins(coins)) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py @@ -1093,7 +1093,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): addr = self.wallet.create_new_address(False) req = self.wallet.make_payment_request(addr, amount, message, expiration) try: - self.wallet.add_payment_request(req, self.config) + self.wallet.add_payment_request(req) except Exception as e: self.logger.exception('Error adding payment request') self.show_error(_('Error adding payment request') + ':\n' + repr(e)) @@ -1455,7 +1455,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): is_sweep = bool(self.tx_external_keypairs) make_tx = lambda fee_est: \ self.wallet.make_unsigned_transaction( - coins, outputs, self.config, + coins, outputs, fixed_fee=fee_est, is_sweep=is_sweep) try: tx = make_tx(fee_estimator) @@ -1696,7 +1696,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): try: is_sweep = bool(self.tx_external_keypairs) tx = self.wallet.make_unsigned_transaction( - coins, outputs, self.config, fixed_fee=fee_estimator, + coins, outputs, fixed_fee=fee_estimator, is_sweep=is_sweep) except (NotEnoughFunds, NoDynamicFeeEstimates) as e: self.show_message(str(e)) @@ -2044,7 +2044,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): if self.pay_from: return self.pay_from else: - return self.wallet.get_spendable_coins(None, self.config) + return self.wallet.get_spendable_coins(None) def spend_coins(self, coins): self.set_pay_from(coins) @@ -3116,7 +3116,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): is_final = cb.isChecked() new_fee_rate = feerate_e.get_amount() try: - new_tx = self.wallet.bump_fee(tx=tx, new_fee_rate=new_fee_rate, config=self.config) + new_tx = self.wallet.bump_fee(tx=tx, new_fee_rate=new_fee_rate) except CannotBumpFee as e: self.show_error(str(e)) return diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py @@ -114,7 +114,7 @@ class RequestList(MyTreeView): self.parent.update_receive_address_styling() self.model().clear() self.update_headers(self.__class__.headers) - for req in self.wallet.get_sorted_requests(self.config): + for req in self.wallet.get_sorted_requests(): status = req.get('status') if status == PR_PAID: continue diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py @@ -490,7 +490,7 @@ class Peer(Logger): wallet = self.lnworker.wallet # dry run creating funding tx to see if we even have enough funds funding_tx_test = wallet.mktx([TxOutput(bitcoin.TYPE_ADDRESS, wallet.dummy_address(), funding_sat)], - password, self.lnworker.config, nonlocal_only=True) + password, nonlocal_only=True) await asyncio.wait_for(self.initialized.wait(), LN_P2P_NETWORK_TIMEOUT) feerate = self.lnworker.current_feerate_per_kw() local_config = self.make_local_config(funding_sat, push_msat, LOCAL) @@ -570,7 +570,7 @@ class Peer(Logger): redeem_script = funding_output_script(local_config, remote_config) funding_address = bitcoin.redeem_script_to_address('p2wsh', redeem_script) funding_output = TxOutput(bitcoin.TYPE_ADDRESS, funding_address, funding_sat) - funding_tx = wallet.mktx([funding_output], password, self.lnworker.config, nonlocal_only=True) + funding_tx = wallet.mktx([funding_output], password, nonlocal_only=True) funding_txid = funding_tx.txid() funding_index = funding_tx.outputs().index(funding_output) # remote commitment transaction diff --git a/electrum/tests/test_wallet_vertical.py b/electrum/tests/test_wallet_vertical.py @@ -572,7 +572,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet1 -> wallet2 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 250000)] - tx = wallet1.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet1.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) self.assertTrue(tx.is_complete()) self.assertTrue(tx.is_segwit()) @@ -592,7 +592,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet2 -> wallet1 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet1.get_receiving_address(), 100000)] - tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet2.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) self.assertTrue(tx.is_complete()) self.assertFalse(tx.is_segwit()) @@ -645,7 +645,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet1 -> wallet2 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 370000)] - tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet1a.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners self.assertFalse(tx.is_complete()) wallet1b.sign_transaction(tx, password=None) @@ -668,7 +668,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet2 -> wallet1 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 100000)] - tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet2.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) self.assertTrue(tx.is_complete()) self.assertFalse(tx.is_segwit()) @@ -736,7 +736,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet1 -> wallet2 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet2a.get_receiving_address(), 165000)] - tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet1a.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) txid = tx.txid() tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners self.assertEqual(txid, tx.txid()) @@ -762,7 +762,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet2 -> wallet1 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 100000)] - tx = wallet2a.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet2a.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) txid = tx.txid() tx = Transaction(tx.serialize()) # simulates moving partial txn between cosigners self.assertEqual(txid, tx.txid()) @@ -816,7 +816,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet1 -> wallet2 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 1000000)] - tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet1a.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) self.assertTrue(tx.is_complete()) self.assertFalse(tx.is_segwit()) @@ -836,7 +836,7 @@ class TestWalletSending(TestCaseForTestnet): # wallet2 -> wallet1 outputs = [TxOutput(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 300000)] - tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000, tx_version=1) + tx = wallet2.mktx(outputs=outputs, password=None, fee=5000, tx_version=1) self.assertTrue(tx.is_complete()) self.assertTrue(tx.is_segwit()) @@ -885,8 +885,8 @@ class TestWalletSending(TestCaseForTestnet): # create tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2500000)] - coins = wallet.get_spendable_coins(domain=None, config=self.config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=self.config, fixed_fee=5000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=5000) tx.set_rbf(True) tx.locktime = 1325501 tx.version = 1 @@ -911,7 +911,7 @@ class TestWalletSending(TestCaseForTestnet): self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance()) # bump tx - tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config) + tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0) tx.locktime = 1325501 tx.version = 1 if simulate_moving_txs: @@ -976,8 +976,8 @@ class TestWalletSending(TestCaseForTestnet): # create tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2500000)] - coins = wallet.get_spendable_coins(domain=None, config=self.config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=self.config, fixed_fee=5000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=5000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1002,7 +1002,7 @@ class TestWalletSending(TestCaseForTestnet): self.assertEqual((0, funding_output_value - 2500000 - 5000, 0), wallet.get_balance()) # bump tx - tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config) + tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0) tx.locktime = 1325500 tx.version = 1 if simulate_moving_txs: @@ -1032,8 +1032,8 @@ class TestWalletSending(TestCaseForTestnet): # create tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', '!')] - coins = wallet.get_spendable_coins(domain=None, config=self.config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=self.config, fixed_fee=5000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=5000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1058,7 +1058,7 @@ class TestWalletSending(TestCaseForTestnet): self.assertEqual((0, 0, 0), wallet.get_balance()) # bump tx - tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config) + tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0) tx.locktime = 1325500 tx.version = 1 if simulate_moving_txs: @@ -1089,8 +1089,8 @@ class TestWalletSending(TestCaseForTestnet): # create tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', '!')] - coins = wallet.get_spendable_coins(domain=None, config=self.config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=self.config, fixed_fee=5000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=5000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1123,7 +1123,7 @@ class TestWalletSending(TestCaseForTestnet): self.assertEqual((0, 5_000_000, 0), wallet.get_balance()) # bump tx - tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0, config=self.config) + tx = wallet.bump_fee(tx=Transaction(tx.serialize()), new_fee_rate=70.0) tx.locktime = 1325500 tx.version = 1 if simulate_moving_txs: @@ -1144,7 +1144,7 @@ class TestWalletSending(TestCaseForTestnet): def _rbf_batching(self, *, simulate_moving_txs): wallet = self.create_standard_wallet_from_seed('frost repair depend effort salon ring foam oak cancel receive save usage') - config = SimpleConfig({'electrum_path': self.electrum_path, 'batch_rbf': True}) + wallet.config.set_key('batch_rbf', True) # bootstrap wallet (incoming funding_tx1) funding_tx1 = Transaction('01000000000102acd6459dec7c3c51048eb112630da756f5d4cb4752b8d39aa325407ae0885cba020000001716001455c7f5e0631d8e6f5f05dddb9f676cec48845532fdffffffd146691ef6a207b682b13da5f2388b1f0d2a2022c8cfb8dc27b65434ec9ec8f701000000171600147b3be8a7ceaf15f57d7df2a3d216bc3c259e3225fdffffff02a9875b000000000017a914ea5a99f83e71d1c1dfc5d0370e9755567fe4a141878096980000000000160014d4ca56fcbad98fb4dcafdc573a75d6a6fffb09b702483045022100dde1ba0c9a2862a65791b8d91295a6603207fb79635935a67890506c214dd96d022046c6616642ef5971103c1db07ac014e63fa3b0e15c5729eacdd3e77fcb7d2086012103a72410f185401bb5b10aaa30989c272b554dc6d53bda6da85a76f662723421af024730440220033d0be8f74e782fbcec2b396647c7715d2356076b442423f23552b617062312022063c95cafdc6d52ccf55c8ee0f9ceb0f57afb41ea9076eb74fe633f59c50c6377012103b96a4954d834fbcfb2bbf8cf7de7dc2b28bc3d661c1557d1fd1db1bfc123a94abb391400') @@ -1155,8 +1155,8 @@ class TestWalletSending(TestCaseForTestnet): # create tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2_500_000)] - coins = wallet.get_spendable_coins(domain=None, config=config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=config, fixed_fee=5000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=5000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1191,8 +1191,8 @@ class TestWalletSending(TestCaseForTestnet): # create new tx (output should be batched with existing!) # no new input will be needed. just a new output, and change decreased. outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1qy6xmdj96v5dzt3j08hgc05yk3kltqsnmw4r6ry', 2_500_000)] - coins = wallet.get_spendable_coins(domain=None, config=config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=config, fixed_fee=20000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=20000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1219,8 +1219,8 @@ class TestWalletSending(TestCaseForTestnet): # create new tx (output should be batched with existing!) # new input will be needed! outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2NCVwbmEpvaXKHpXUGJfJr9iB5vtRN3vcut', 6_000_000)] - coins = wallet.get_spendable_coins(domain=None, config=config) - tx = wallet.make_unsigned_transaction(coins, outputs, config=config, fixed_fee=100_000) + coins = wallet.get_spendable_coins(domain=None) + tx = wallet.make_unsigned_transaction(coins, outputs, fixed_fee=100_000) tx.set_rbf(True) tx.locktime = 1325499 tx.version = 1 @@ -1337,7 +1337,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1qyw3c0rvn6kk2c688y3dygvckn57525y8qnxt3a', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1446655 tx.version = 1 @@ -1380,7 +1380,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1421,7 +1421,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325341 tx.version = 1 @@ -1463,7 +1463,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325341 tx.version = 1 @@ -1500,7 +1500,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1535,7 +1535,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1570,7 +1570,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1608,7 +1608,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1646,7 +1646,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1684,7 +1684,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, 'tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325340 tx.version = 1 @@ -1734,7 +1734,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2MuCQQHJNnrXzQzuqfUCfAwAjPqpyEHbgue', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325503 tx.version = 1 @@ -1792,7 +1792,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2N8CtJRwxb2GCaiWWdSHLZHHLoZy53CCyxf', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325504 tx.version = 1 @@ -1852,7 +1852,7 @@ class TestWalletOfflineSigning(TestCaseForTestnet): # create unsigned tx outputs = [TxOutput(bitcoin.TYPE_ADDRESS, '2MyoZVy8T1t94yLmyKu8DP1SmbWvnxbkwRA', 2500000)] - tx = wallet_online.mktx(outputs=outputs, password=None, config=self.config, fee=5000) + tx = wallet_online.mktx(outputs=outputs, password=None, fee=5000) tx.set_rbf(True) tx.locktime = 1325505 tx.version = 1 diff --git a/electrum/wallet.py b/electrum/wallet.py @@ -236,7 +236,8 @@ class Abstract_Wallet(AddressSynchronizer): self.contacts = Contacts(self.storage) self._coin_price_cache = {} - self.lnworker = LNWallet(self) if get_config().get('lightning') else None + self.config = get_config() + self.lnworker = LNWallet(self) if self.config.get('lightning') else None def stop_threads(self): super().stop_threads() @@ -408,10 +409,10 @@ class Abstract_Wallet(AddressSynchronizer): status = _('Unconfirmed') if fee is None: fee = self.db.get_tx_fee(tx_hash) - if fee and self.network and self.network.config.has_fee_mempool(): + if fee and self.network and self.config.has_fee_mempool(): size = tx.estimated_size() fee_per_byte = fee / size - exp_n = self.network.config.fee_to_depth(fee_per_byte) + exp_n = self.config.fee_to_depth(fee_per_byte) can_bump = is_mine and not tx.is_final() else: status = _('Local') @@ -447,8 +448,8 @@ class Abstract_Wallet(AddressSynchronizer): mempool_depth_bytes=exp_n, ) - def get_spendable_coins(self, domain, config, *, nonlocal_only=False): - confirmed_only = config.get('confirmed_only', False) + def get_spendable_coins(self, domain, *, nonlocal_only=False): + confirmed_only = self.config.get('confirmed_only', False) utxos = self.get_utxos(domain, excluded_addresses=self.frozen_addresses, mature_only=True, @@ -728,8 +729,8 @@ class Abstract_Wallet(AddressSynchronizer): fee_per_byte = fee / size extra.append(format_fee_satoshis(fee_per_byte) + ' sat/b') if fee is not None and height in (TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED) \ - and self.network and self.network.config.has_fee_mempool(): - exp_n = self.network.config.fee_to_depth(fee_per_byte) + and self.config.has_fee_mempool(): + exp_n = self.config.fee_to_depth(fee_per_byte) if exp_n: extra.append('%.2f MB'%(exp_n/1000000)) if height == TX_HEIGHT_LOCAL: @@ -810,7 +811,7 @@ class Abstract_Wallet(AddressSynchronizer): max_change = self.max_change_outputs if self.multiple_change else 1 return change_addrs[:max_change] - def make_unsigned_transaction(self, coins, outputs, config, fixed_fee=None, + def make_unsigned_transaction(self, coins, outputs, fixed_fee=None, change_addr=None, is_sweep=False): # check outputs i_max = None @@ -823,7 +824,7 @@ class Abstract_Wallet(AddressSynchronizer): raise Exception("More than one output set to spend max") i_max = i - if fixed_fee is None and config.fee_per_kb() is None: + if fixed_fee is None and self.config.fee_per_kb() is None: raise NoDynamicFeeEstimates() for item in coins: @@ -831,7 +832,7 @@ class Abstract_Wallet(AddressSynchronizer): # Fee estimator if fixed_fee is None: - fee_estimator = config.estimate_fee + fee_estimator = self.config.estimate_fee elif isinstance(fixed_fee, Number): fee_estimator = lambda size: fixed_fee elif callable(fixed_fee): @@ -841,10 +842,10 @@ class Abstract_Wallet(AddressSynchronizer): if i_max is None: # Let the coin chooser select the coins to spend - coin_chooser = coinchooser.get_coin_chooser(config) + coin_chooser = coinchooser.get_coin_chooser(self.config) # If there is an unconfirmed RBF tx, merge with it base_tx = self.get_unconfirmed_base_tx_for_batching() - if config.get('batch_rbf', False) and base_tx: + if self.config.get('batch_rbf', False) and base_tx: # make sure we don't try to spend change from the tx-to-be-replaced: coins = [c for c in coins if c['prevout_hash'] != base_tx.txid()] is_local = self.get_tx_height(base_tx.txid()).height == TX_HEIGHT_LOCAL @@ -894,10 +895,10 @@ class Abstract_Wallet(AddressSynchronizer): run_hook('make_unsigned_transaction', self, tx) return tx - def mktx(self, outputs, password, config, fee=None, change_addr=None, + def mktx(self, outputs, password, fee=None, change_addr=None, domain=None, rbf=False, nonlocal_only=False, *, tx_version=None): - coins = self.get_spendable_coins(domain, config, nonlocal_only=nonlocal_only) - tx = self.make_unsigned_transaction(coins, outputs, config, fee, change_addr) + coins = self.get_spendable_coins(domain, nonlocal_only=nonlocal_only) + tx = self.make_unsigned_transaction(coins, outputs, fee, change_addr) tx.set_rbf(rbf) if tx_version is not None: tx.version = tx_version @@ -988,7 +989,7 @@ class Abstract_Wallet(AddressSynchronizer): max_conf = max(max_conf, tx_age) return max_conf >= req_conf - def bump_fee(self, *, tx, new_fee_rate, config) -> Transaction: + def bump_fee(self, *, tx, new_fee_rate) -> Transaction: """Increase the miner fee of 'tx'. 'new_fee_rate' is the target min rate in sat/vbyte """ @@ -1007,7 +1008,7 @@ class Abstract_Wallet(AddressSynchronizer): # method 1: keep all inputs, keep all not is_mine outputs, # allow adding new inputs tx_new = self._bump_fee_through_coinchooser( - tx=tx, new_fee_rate=new_fee_rate, config=config) + tx=tx, new_fee_rate=new_fee_rate) method_used = 1 except CannotBumpFee: # method 2: keep all inputs, no new inputs are added, @@ -1028,7 +1029,7 @@ class Abstract_Wallet(AddressSynchronizer): tx_new.locktime = get_locktime_for_new_transaction(self.network) return tx_new - def _bump_fee_through_coinchooser(self, *, tx, new_fee_rate, config): + def _bump_fee_through_coinchooser(self, *, tx, new_fee_rate): tx = Transaction(tx.serialize()) tx.deserialize(force_full_parse=True) # need to parse inputs tx.remove_signatures() @@ -1053,12 +1054,12 @@ class Abstract_Wallet(AddressSynchronizer): else: fixed_outputs = old_outputs - coins = self.get_spendable_coins(None, config) + coins = self.get_spendable_coins(None) for item in coins: self.add_input_info(item) def fee_estimator(size): - return config.estimate_fee_for_feerate(fee_per_kb=new_fee_rate*1000, size=size) - coin_chooser = coinchooser.get_coin_chooser(config) + return self.config.estimate_fee_for_feerate(fee_per_kb=new_fee_rate*1000, size=size) + coin_chooser = coinchooser.get_coin_chooser(self.config) try: return coin_chooser.make_tx(coins, old_inputs, fixed_outputs, change_addrs, fee_estimator, self.dust_threshold()) @@ -1324,8 +1325,6 @@ class Abstract_Wallet(AddressSynchronizer): return status, conf def get_request(self, key): - from .simple_config import get_config - config = get_config() if key in self.receive_requests: req = self.get_payment_request(key) elif self.lnworker: @@ -1334,11 +1333,11 @@ class Abstract_Wallet(AddressSynchronizer): req = None if not req: return - if config.get('payserver_port'): - host = config.get('payserver_host', 'localhost') - port = config.get('payserver_port') - root = config.get('payserver_root', '/r') - use_ssl = bool(config.get('ssl_keyfile')) + if self.config.get('payserver_port'): + host = self.config.get('payserver_host', 'localhost') + port = self.config.get('payserver_port') + root = self.config.get('payserver_root', '/r') + use_ssl = bool(self.config.get('ssl_keyfile')) protocol = 'https' if use_ssl else 'http' base = '%s://%s:%d'%(protocol, host, port) req['view_url'] = base + root + '/pay?id=' + key @@ -1371,7 +1370,7 @@ class Abstract_Wallet(AddressSynchronizer): self.receive_requests[key] = req self.storage.put('payment_requests', self.receive_requests) - def add_payment_request(self, req, config): + def add_payment_request(self, req): addr = req['address'] if not bitcoin.is_address(addr): raise Exception(_('Invalid Bitcoin address.')) @@ -1388,7 +1387,7 @@ class Abstract_Wallet(AddressSynchronizer): def delete_request(self, key): """ lightning or on-chain """ if key in self.receive_requests: - self.remove_payment_request(key, {}) + self.remove_payment_request(key) elif self.lnworker: self.lnworker.delete_invoice(key) @@ -1400,14 +1399,14 @@ class Abstract_Wallet(AddressSynchronizer): elif self.lnworker: self.lnworker.delete_invoice(key) - def remove_payment_request(self, addr, config): + def remove_payment_request(self, addr): if addr not in self.receive_requests: return False self.receive_requests.pop(addr) self.storage.put('payment_requests', self.receive_requests) return True - def get_sorted_requests(self, config): + def get_sorted_requests(self): """ sorted by timestamp """ out = [self.get_request(x) for x in self.receive_requests.keys()] if self.lnworker: @@ -1692,7 +1691,7 @@ class Imported_Wallet(Simple_Wallet): self.unverified_tx.pop(tx_hash, None) self.db.remove_transaction(tx_hash) self.set_label(address, None) - self.remove_payment_request(address, {}) + self.remove_payment_request(address) self.set_frozen_state_of_addresses([address], False) pubkey = self.get_public_key(address) self.db.remove_imported_address(address)