From 4c431500aabe47ae2ef83df86d88da9af34f7c4e Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 11 Mar 2024 10:28:40 +0000 Subject: [PATCH] mmgen-xmrwallet: new --priority option Increase the chances of your transaction being included in a block during periods of TX pool congestion. Supported values: 1 - low 2 - normal 3 - high 4 - highest If option is omitted, default priority (0) is used --- mmgen/cfg.py | 1 + mmgen/data/version | 2 +- mmgen/main_xmrwallet.py | 9 ++++++++- mmgen/xmrwallet.py | 24 ++++++++++++++++++++++-- test/cmdtest_py_d/ct_xmr_autosign.py | 7 ++++--- test/cmdtest_py_d/ct_xmrwallet.py | 4 +++- 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/mmgen/cfg.py b/mmgen/cfg.py index e2db18a1..1938d11e 100755 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -196,6 +196,7 @@ class Config(Lockable): # Monero: monero_wallet_rpc_user = 'monero' monero_wallet_rpc_password = '' + priority = 0 # test suite: bogus_send = False diff --git a/mmgen/data/version b/mmgen/data/version index 81aa9436..247246e0 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -14.1.dev21 +14.1.dev22 diff --git a/mmgen/main_xmrwallet.py b/mmgen/main_xmrwallet.py index ebf78d87..a6aeff42 100755 --- a/mmgen/main_xmrwallet.py +++ b/mmgen/main_xmrwallet.py @@ -23,11 +23,12 @@ mmgen-xmrwallet: Perform various Monero wallet and transacting operations for import asyncio from .cfg import gc,Config -from .util import die +from .util import die,fmt_dict from .xmrwallet import ( MoneroWalletOps, xmrwallet_uarg_info, xmrwallet_uargs, + tx_priorities ) opts_data = { @@ -60,6 +61,11 @@ opts_data = { When this option is in effect, filename argu- ments must be omitted, as files are located automatically. +-f, --priority=N Specify an integer priority ‘N’ for inclusion + of a transaction in the blockchain (higher + number means higher fee). Valid parameters: + {tp}. If option + is omitted, the default priority will be used -m, --autosign-mountpoint=P Specify the autosign mountpoint (defaults to ‘/mnt/mmgen_autosign’, implies --autosign) -b, --rescan-blockchain Rescan the blockchain if wallet fails to sync @@ -94,6 +100,7 @@ opts_data = { R=xmrwallet_uarg_info['tx_relay_daemon'].annot, cfg=cfg, gc=gc, + tp=fmt_dict(tx_priorities,fmt='equal_compact') ), 'notes': lambda help_mod,s: s.format( xmrwallet_help = help_mod('xmrwallet') diff --git a/mmgen/xmrwallet.py b/mmgen/xmrwallet.py index 7316c1e1..032c57eb 100755 --- a/mmgen/xmrwallet.py +++ b/mmgen/xmrwallet.py @@ -25,7 +25,7 @@ from collections import namedtuple from pathlib import Path from .objmethods import MMGenObject,HiliteStr,InitErrors -from .obj import CoinTxID +from .obj import CoinTxID,Int from .color import red,yellow,green,blue,cyan,pink,orange,purple,gray from .util import ( msg, @@ -44,6 +44,7 @@ from .util import ( make_chksum_N, capfirst, list_gen, + fmt_dict ) from .fileutil import get_data_from_file from .seed import SeedID @@ -95,6 +96,13 @@ def fmt_amt(amt): def hl_amt(amt): return str(amt) +tx_priorities = { + 1: 'low', + 2: 'normal', + 3: 'high', + 4: 'highest' +} + class XMRWalletAddrSpec(HiliteStr,InitErrors,MMGenObject): color = 'cyan' width = 0 @@ -223,6 +231,7 @@ class MoneroMMGenTX: 'dest_address', 'txid', 'amount', + 'priority', 'fee', 'blob', 'metadata', @@ -266,6 +275,7 @@ class MoneroMMGenTX: [' From: Wallet {j}, account {k}'], [' To: Wallet {x}, account {y}, address {z}', d.dest], [' Amount: {m} XMR'], + [' Priority: {F}', d.priority], [' Fee: {n} XMR'], [' Dest: {o}'], [' Payment ID: {P}', pmt_id], @@ -285,6 +295,7 @@ class MoneroMMGenTX: j = d.source.wallet.hl(), k = red(f'#{d.source.account}'), m = d.amount.hl(), + F = (Int(d.priority).hl() + f' [{tx_priorities[d.priority]}]') if d.priority else None, n = d.fee.hl(), o = d.dest_address.hl(), P = pink(pmt_id.hex()) if pmt_id else None, @@ -359,6 +370,7 @@ class MoneroMMGenTX: dest_address = CoinAddr(proto,d.dest_address), txid = CoinTxID(d.txid), amount = proto.coin_amt(d.amount,from_unit='atomic'), + priority = self.cfg.priority if self.name in ('NewSigned','NewUnsigned') else d.priority, fee = proto.coin_amt(d.fee,from_unit='atomic'), blob = d.blob, metadata = d.metadata, @@ -434,6 +446,7 @@ class MoneroMMGenTX: dest_address = CoinAddr(proto,d.dest_address), txid = CoinTxID(d.txid), amount = proto.coin_amt(d.amount), + priority = d.priority, fee = proto.coin_amt(d.fee), blob = d.blob, metadata = d.metadata, @@ -1102,6 +1115,7 @@ class MoneroWalletOps: 'amount': amt.to_unit('atomic'), 'address': addr }], + priority = self.cfg.priority or None, do_not_relay = True, get_tx_hex = True, get_tx_metadata = True @@ -1127,6 +1141,7 @@ class MoneroWalletOps: 'sweep_all', address = addr, account_index = account, + priority = self.cfg.priority or None, do_not_relay = True, get_tx_hex = True, get_tx_metadata = True @@ -1512,12 +1527,17 @@ class MoneroWalletOps: class sweep(spec): spec_id = 'sweep_spec' spec_key = ( (1,'source'), (3,'dest') ) - opts = ('no_relay','tx_relay_daemon','watch_only') + opts = ('no_relay','tx_relay_daemon','watch_only','priority') def check_uopts(self): if self.cfg.tx_relay_daemon and (self.cfg.no_relay or self.cfg.autosign): die(1,'--tx-relay-daemon makes no sense in this context!') + if self.cfg.priority and self.cfg.priority not in list(tx_priorities): + die(1, '{}: invalid parameter for --priority (valid params: {})'.format( + self.cfg.priority, + fmt_dict(tx_priorities, fmt='square_compact'))) + def init_tx_relay_daemon(self): m = self.parse_tx_relay_opt() diff --git a/test/cmdtest_py_d/ct_xmr_autosign.py b/test/cmdtest_py_d/ct_xmr_autosign.py index ed099e63..9d8bc1f6 100755 --- a/test/cmdtest_py_d/ct_xmr_autosign.py +++ b/test/cmdtest_py_d/ct_xmr_autosign.py @@ -243,20 +243,21 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def restore_wallets(self): return self.create_watchonly_wallets() - def _create_transfer_tx(self,amt): + def _create_transfer_tx(self, amt, add_opts=[]): self.insert_device_online() t = self.do_op( 'transfer', 'alice', f'1:0:{self.burn_addr},{amt}', no_relay = True, - do_ret = True) + do_ret = True, + add_opts = add_opts) t.read() # required! self.remove_device_online() return t def create_transfer_tx1(self): - return self._create_transfer_tx('0.124') + return self._create_transfer_tx('0.124', add_opts=['--priority=2']) def create_transfer_tx2(self): return self._create_transfer_tx('0.257') diff --git a/test/cmdtest_py_d/ct_xmrwallet.py b/test/cmdtest_py_d/ct_xmrwallet.py index 1b413431..ebbe3322 100755 --- a/test/cmdtest_py_d/ct_xmrwallet.py +++ b/test/cmdtest_py_d/ct_xmrwallet.py @@ -528,6 +528,7 @@ class CmdTestXMRWallet(CmdTestBase): no_relay = False, return_amt = False, reuse_acct = False, + add_opts = [], add_desc = None, do_ret = False): @@ -545,6 +546,7 @@ class CmdTestXMRWallet(CmdTestBase): 'mmgen-xmrwallet', self.extra_opts + cmd_opts + + add_opts + (self.autosign_opts if data.autosign else []) + [op] + ([] if data.autosign else [data.kafile]) @@ -578,7 +580,7 @@ class CmdTestXMRWallet(CmdTestBase): return t if do_ret else amt if return_amt else t.ok() def sweep_to_address_proxy(self): - self.do_op('sweep','alice','1:0',self.tx_relay_daemon_proxy_parm) + self.do_op('sweep', 'alice', '1:0', self.tx_relay_daemon_proxy_parm, add_opts=['--priority=3']) return self.mine_chk('alice',1,0,lambda x: x.ub > 1,'unlocked balance > 1') def sweep_to_account(self):