mmgen-xmrwallet: new resubmit operation
This commit is contained in:
parent
a94d354b85
commit
3b7a238259
6 changed files with 82 additions and 19 deletions
|
|
@ -1 +1 @@
|
|||
April 2023
|
||||
May 2023
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
13.3.dev50
|
||||
13.3.dev51
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ sweep - sweep funds in specified wallet:account to new address in same
|
|||
relay - relay a transaction from a transaction file created using ‘sweep’
|
||||
or ‘transfer’ with the --no-relay option
|
||||
submit - submit an autosigned transaction to a wallet and the network
|
||||
resubmit - resubmit most recently submitted autosigned transaction (other
|
||||
actions are required: see Exporting Outputs below)
|
||||
txview - display detailed information about a transaction file or files
|
||||
txlist - same as above, but display terse information in tabular format
|
||||
dump - produce JSON dumps of wallet metadata (accounts, addresses and
|
||||
|
|
@ -326,18 +328,20 @@ differences that apply to autosigning:
|
|||
Exporting Outputs
|
||||
|
||||
Exporting outputs from a watch-only wallet is generally required in only
|
||||
two cases:
|
||||
three cases:
|
||||
|
||||
a) at the start of each signing session (after ‘mmgen-autosign setup’); and
|
||||
a) at the start of each signing session (after ‘mmgen-autosign setup’);
|
||||
b) after the wallet has received funds from an outside source or another
|
||||
wallet.
|
||||
wallet; and
|
||||
c) after performing a ‘resubmit’ operation.
|
||||
|
||||
You might also need to do it, however, if an offline wallet is unable to sign
|
||||
a transaction due to missing outputs.
|
||||
|
||||
Export outputs from a wallet as follows:
|
||||
Export outputs from a wallet as follows (note that the --rescan-blockchain
|
||||
option is required only after a ‘resubmit’ – otherwise it should be omitted):
|
||||
|
||||
$ mmgen-xmrwallet --autosign export-outputs <wallet index>
|
||||
$ mmgen-xmrwallet --autosign --rescan-blockchain export-outputs <wallet index>
|
||||
|
||||
At the start of a new signing session, you must export outputs from ALL
|
||||
wallets you intend to transact with. This is necessary because the offline
|
||||
|
|
@ -349,6 +353,11 @@ into the corresponding signing wallet(s) (and optionally redo any failed
|
|||
transaction signing operation). The signing wallet(s) will also create
|
||||
signed key images.
|
||||
|
||||
Following a ‘resubmit’, you must then import the signed key images into your
|
||||
online wallet as follows:
|
||||
|
||||
$ mmgen-xmrwallet --autosign import-key-images
|
||||
|
||||
|
||||
Replacing Existing Hot Wallets with Watch-Only Wallets
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ opts_data = {
|
|||
'[opts] sweep [xmr_keyaddrfile] SWEEP_SPEC',
|
||||
'[opts] submit [TX_file]',
|
||||
'[opts] relay <TX_file>',
|
||||
'[opts] resubmit',
|
||||
'[opts] txview | txlist [TX_file] ...',
|
||||
'[opts] export-outputs [wallets]',
|
||||
'[opts] import-key-images [wallets]',
|
||||
|
|
@ -112,7 +113,7 @@ if cmd_args and cfg.autosign and (
|
|||
MoneroWalletOps.kafile_arg_ops
|
||||
+ ('export-outputs','import-key-images','txview','txlist')
|
||||
)
|
||||
or len(cmd_args) == 1 and cmd_args[0] == 'submit'
|
||||
or len(cmd_args) == 1 and cmd_args[0] in ('submit','resubmit')
|
||||
):
|
||||
cmd_args.insert(1,None)
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ wallets = spec = None
|
|||
if op.replace('-','_') not in MoneroWalletOps.ops:
|
||||
die(1,f'{op!r}: unrecognized operation')
|
||||
|
||||
if op in ('relay','submit'):
|
||||
if op in ('relay','submit','resubmit'):
|
||||
if len(cmd_args) != 0:
|
||||
cfg._opts.usage()
|
||||
elif op in ('txview','txlist'):
|
||||
|
|
|
|||
|
|
@ -446,6 +446,7 @@ class MoneroMMGenTX:
|
|||
class Submitted(ColdSigned):
|
||||
desc = 'submitted transaction'
|
||||
ext = 'subtx'
|
||||
silent_load = True
|
||||
|
||||
class View(Completed):
|
||||
silent_load = True
|
||||
|
|
@ -606,6 +607,7 @@ class MoneroWalletOps:
|
|||
'label',
|
||||
'sign',
|
||||
'submit',
|
||||
'resubmit',
|
||||
'dump',
|
||||
'restore',
|
||||
'export_outputs',
|
||||
|
|
@ -1266,6 +1268,10 @@ class MoneroWalletOps:
|
|||
opts = ('rescan_blockchain',)
|
||||
test_monerod = True
|
||||
|
||||
def check_uopts(self):
|
||||
if self.cfg.rescan_blockchain and self.cfg.watch_only:
|
||||
die(1,f'Operation {self.name!r} does not support --rescan-blockchain with watch-only wallets')
|
||||
|
||||
def __init__(self,cfg,uarg_tuple):
|
||||
|
||||
super().__init__(cfg,uarg_tuple)
|
||||
|
|
@ -1748,6 +1754,25 @@ class MoneroWalletOps:
|
|||
ask_overwrite = not self.cfg.autosign )
|
||||
return new_tx
|
||||
|
||||
class resubmit(submit):
|
||||
action = 'resubmitting transaction with'
|
||||
|
||||
def check_uopts(self):
|
||||
if not self.cfg.autosign:
|
||||
die(1,f'--autosign is required for this operation')
|
||||
|
||||
def get_tx(self):
|
||||
asi = get_autosign_obj(self.cfg,'xmr')
|
||||
files = [f for f in asi.xmr_tx_dir.iterdir() if f.name.endswith('.'+MoneroMMGenTX.Submitted.ext)]
|
||||
txs = sorted(
|
||||
(MoneroMMGenTX.Submitted( self.cfg, Path(fn) ) for fn in files),
|
||||
key = lambda x: getattr(x.data,'submit_time',None) or x.data.create_time
|
||||
)
|
||||
if txs:
|
||||
return txs[-1]
|
||||
else:
|
||||
self.die_no_tx( 'submitted', 0, asi.xmr_tx_dir )
|
||||
|
||||
class dump(wallet):
|
||||
|
||||
async def process_wallet(self,d,fn,last):
|
||||
|
|
@ -1764,10 +1789,17 @@ class MoneroWalletOps:
|
|||
class export_outputs(wallet):
|
||||
action = 'exporting outputs from'
|
||||
stem = 'process'
|
||||
opts = ('rescan_blockchain',)
|
||||
|
||||
async def process_wallet(self,d,fn,last):
|
||||
h = self.rpc(self,d)
|
||||
h.open_wallet('source')
|
||||
|
||||
if self.cfg.rescan_blockchain:
|
||||
gmsg_r(f'\n Rescanning blockchain...')
|
||||
self.c.call('rescan_blockchain')
|
||||
gmsg('done')
|
||||
|
||||
self.head_msg(d.idx,h.fn)
|
||||
for ftype in ('Unsigned','Signed'):
|
||||
old_fn = getattr(MoneroWalletOutputsFile,ftype).find_fn_from_wallet_fn(
|
||||
|
|
@ -1803,7 +1835,7 @@ class MoneroWalletOps:
|
|||
idata = res['num_imported']
|
||||
bmsg('\n {} output{} imported'.format( idata, suf(idata) ))
|
||||
data = m.data._asdict()
|
||||
data.update(self.c.call('export_key_images')) # for testing: all = True
|
||||
data.update(self.c.call('export_key_images', all=True))
|
||||
m = MoneroWalletOutputsFile.SignedNew(
|
||||
parent = self,
|
||||
wallet_fn = m.get_wallet_fn(fn),
|
||||
|
|
|
|||
|
|
@ -66,18 +66,23 @@ class TestSuiteXMRAutosign(TestSuiteXMRWallet,TestSuiteAutosignBase):
|
|||
('create_transfer_tx1', 'creating a transfer TX'),
|
||||
('sign_transfer_tx1', 'signing the transfer TX'),
|
||||
('submit_transfer_tx1', 'submitting the transfer TX'),
|
||||
('resubmit_transfer_tx1', 'resubmitting the transfer TX'),
|
||||
('export_outputs1', 'exporting outputs from Alice’s watch-only wallet #1'),
|
||||
('export_key_images1', 'exporting signed key images from Alice’s offline wallets'),
|
||||
('import_key_images1', 'importing signed key images into Alice’s online wallets'),
|
||||
('sync_chkbal1', 'syncing Alice’s wallet #1'),
|
||||
('create_transfer_tx2', 'creating a transfer TX (for relaying via proxy)'),
|
||||
('sign_transfer_tx2', 'signing the transfer TX (for relaying via proxy)'),
|
||||
('submit_transfer_tx2', 'submitting the transfer TX (relaying via proxy)'),
|
||||
('sync_chkbal1', 'syncing Alice’s wallets and checking balance'),
|
||||
('sync_chkbal2', 'syncing Alice’s wallets and checking balance'),
|
||||
('dump_wallets', 'dumping Alice’s wallets'),
|
||||
('delete_wallets', 'deleting Alice’s wallets'),
|
||||
('restore_wallets', 'creating online (watch-only) wallets for Alice'),
|
||||
('delete_dump_files', 'deleting Alice’s dump files'),
|
||||
('export_outputs', 'exporting outputs from Alice’s watch-only wallets'),
|
||||
('export_key_images', 'exporting signed key images from Alice’s offline wallets'),
|
||||
('import_key_images', 'importing signed key images into Alice’s online wallets'),
|
||||
('sync_chkbal2', 'syncing Alice’s wallets and checking balance'),
|
||||
('export_outputs2', 'exporting outputs from Alice’s watch-only wallets'),
|
||||
('export_key_images2', 'exporting signed key images from Alice’s offline wallets'),
|
||||
('import_key_images2', 'importing signed key images into Alice’s online wallets'),
|
||||
('sync_chkbal3', 'syncing Alice’s wallets and checking balance'),
|
||||
('txlist', 'listing Alice’s submitted transactions'),
|
||||
('check_tx_dirs', 'cleaning and checking signable file directories'),
|
||||
)
|
||||
|
|
@ -247,10 +252,14 @@ class TestSuiteXMRAutosign(TestSuiteXMRWallet,TestSuiteAutosignBase):
|
|||
bal_chk_func = bal_chk_func )
|
||||
|
||||
def sync_chkbal1(self):
|
||||
return self._sync_chkbal( lambda n,b,ub: b == ub and 1 < b < 1.12 )
|
||||
# 1.234567891234 - 0.124 = 1.110567891234 (minus fees)
|
||||
|
||||
def sync_chkbal2(self):
|
||||
return self._sync_chkbal( lambda n,b,ub: b == ub and 0.8 < b < 0.86 )
|
||||
# 1.234567891234 - 0.124 - 0.257 = 0.853567891234 (minus fees)
|
||||
|
||||
sync_chkbal2 = sync_chkbal1
|
||||
sync_chkbal3 = sync_chkbal2
|
||||
|
||||
def _mine_chk(self,desc):
|
||||
bal_type = {'locked':'b','unlocked':'ub'}[desc]
|
||||
|
|
@ -262,6 +271,9 @@ class TestSuiteXMRAutosign(TestSuiteXMRWallet,TestSuiteAutosignBase):
|
|||
def submit_transfer_tx1(self):
|
||||
return self._submit_transfer_tx( ext='sigtx' )
|
||||
|
||||
def resubmit_transfer_tx1(self):
|
||||
return self._submit_transfer_tx( relay_parm=self.tx_relay_daemon_proxy_parm, op='resubmit', check_bal=False )
|
||||
|
||||
def submit_transfer_tx2(self):
|
||||
return self._submit_transfer_tx( relay_parm=self.tx_relay_daemon_parm )
|
||||
|
||||
|
|
@ -288,14 +300,20 @@ class TestSuiteXMRAutosign(TestSuiteXMRWallet,TestSuiteAutosignBase):
|
|||
wallet_arg = wallet_arg,
|
||||
add_opts = add_opts )
|
||||
|
||||
def export_outputs(self):
|
||||
def export_outputs1(self):
|
||||
return self._export_outputs('1',['--rescan-blockchain'])
|
||||
|
||||
def export_outputs2(self):
|
||||
return self._export_outputs('1-2')
|
||||
|
||||
def _export_key_images(self,tx_count):
|
||||
self.tx_count = tx_count
|
||||
return self.do_sign(['--full-summary'],tx_name='Monero wallet outputs file')
|
||||
|
||||
def export_key_images(self):
|
||||
def export_key_images1(self):
|
||||
return self._export_key_images(1)
|
||||
|
||||
def export_key_images2(self):
|
||||
return self._export_key_images(2)
|
||||
|
||||
def _import_key_images(self,wallet_arg):
|
||||
|
|
@ -304,7 +322,10 @@ class TestSuiteXMRAutosign(TestSuiteXMRWallet,TestSuiteAutosignBase):
|
|||
desc = 'importing key images',
|
||||
wallet_arg = wallet_arg )
|
||||
|
||||
def import_key_images(self):
|
||||
def import_key_images1(self):
|
||||
return self._import_key_images(None)
|
||||
|
||||
def import_key_images2(self):
|
||||
return self._import_key_images(None)
|
||||
|
||||
def create_fake_tx_files(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue