Browse Source

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
The MMGen Project 1 year ago
parent
commit
4c431500

+ 1 - 0
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

+ 1 - 1
mmgen/data/version

@@ -1 +1 @@
-14.1.dev21
+14.1.dev22

+ 8 - 1
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')

+ 22 - 2
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()

+ 4 - 3
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')

+ 3 - 1
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):