mmgen-txbump: support transaction selection
Transaction selection logic is the same as with `mmgen-txsend --status`, except
ranges are not supported.
Examples (assumes --autosign):
# Bump last sent transaction:
$ mmgen-txbump
# Same as above:
$ mmgen-txbump 0
# Bump next-to-last sent transaction:
$ mmgen-txbump 1
Testing/demo:
$ test/cmdtest.py -e -X alice_txbump6 autosign_automount
This commit is contained in:
parent
a6ad36fd73
commit
c4ec627153
4 changed files with 38 additions and 16 deletions
|
|
@ -334,13 +334,13 @@ class Signable:
|
|||
shred_file(self.cfg, fn, iterations=15)
|
||||
sys.exit(0)
|
||||
|
||||
async def get_last_sent(self, *, tx_range=None):
|
||||
async def get_last_sent(self, *, tx_range):
|
||||
return await self.get_last_created(
|
||||
# compat fallback - ‘sent_timestamp’ attr is missing in some old TX files:
|
||||
sort_key = lambda x: x.sent_timestamp or x.timestamp,
|
||||
tx_range = tx_range)
|
||||
|
||||
async def get_last_created(self, *, sort_key=lambda x: x.timestamp, tx_range=None):
|
||||
async def get_last_created(self, *, tx_range, sort_key=lambda x: x.timestamp):
|
||||
from .tx import CompletedTX
|
||||
fns = [f for f in self.dir.iterdir() if f.name.endswith(self.subext)]
|
||||
files = sorted(
|
||||
|
|
@ -348,9 +348,7 @@ class Signable:
|
|||
for txfile in fns],
|
||||
key = sort_key)
|
||||
if files:
|
||||
return (
|
||||
files[-1] if tx_range is None else
|
||||
files[len(files) - 1 - tx_range.last:len(files) - tx_range.first])
|
||||
return files[len(files) - 1 - tx_range.last:len(files) - tx_range.first]
|
||||
else:
|
||||
die(1, 'No sent automount transactions!')
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ mmgen-txbump: Create, and optionally send and sign, a replacement transaction on
|
|||
import sys
|
||||
|
||||
from .cfg import gc, Config
|
||||
from .util import msg, msg_r, die, async_run
|
||||
from .util import msg, msg_r, die, is_int, async_run
|
||||
from .color import green
|
||||
|
||||
opts_data = {
|
||||
|
|
@ -37,8 +37,8 @@ opts_data = {
|
|||
'usage2': (
|
||||
f'[opts] [{gc.proj_name} TX file] [seed source] ...',
|
||||
f'[opts] {{u_args}} [{gc.proj_name} TX file] [seed source] ...',
|
||||
'--autosign [opts]',
|
||||
'--autosign [opts] {u_args}',
|
||||
'--autosign [opts] [index]',
|
||||
'--autosign [opts] [index] {u_args}',
|
||||
),
|
||||
'options': """
|
||||
-- -h, --help Print this help message
|
||||
|
|
@ -96,8 +96,12 @@ opts_data = {
|
|||
""",
|
||||
'notes': """
|
||||
|
||||
With --autosign, the TX file argument is omitted, and the last submitted TX
|
||||
file on the removable device will be used.
|
||||
With --autosign, the TX file argument is omitted, and the last submitted
|
||||
transaction on the removable device will be used. Or, if the first non-option
|
||||
argument is a non-negative integer, it specifies an index into the list of
|
||||
submitted transactions, in reverse chronological order, and that transaction
|
||||
will be bumped. ‘0’ (the default) signifies the last sent transaction, ‘1’
|
||||
the next-to-last, and so on.
|
||||
|
||||
If no outputs are specified, the original outputs will be used for the
|
||||
replacement transaction, otherwise a new transaction will be created with the
|
||||
|
|
@ -151,6 +155,8 @@ seedfiles = pop_seedfiles(cfg, ignore_dfl_wallet=not cfg.send, empty_ok=not cfg.
|
|||
if cfg.autosign:
|
||||
if cfg.send:
|
||||
die(1, '--send cannot be used together with --autosign')
|
||||
from .tx.online import CreatedTXRange
|
||||
tx_range = CreatedTXRange(cfg._args.pop(0) if cfg._args and is_int(cfg._args[0]) else '0')
|
||||
else:
|
||||
tx_file = cfg._args.pop()
|
||||
from .fileutil import check_infile
|
||||
|
|
@ -174,7 +180,7 @@ async def main():
|
|||
'Only sent transactions can be bumped with --autosign. Instead of bumping\n'
|
||||
f'your {state} transaction, abort it with ‘mmgen-txsend --abort’ and create\n'
|
||||
'a new one.')
|
||||
orig_tx = await si.get_last_created()
|
||||
orig_tx = (await si.get_last_created(tx_range=tx_range))[0]
|
||||
sign_and_send = False
|
||||
else:
|
||||
orig_tx = await CompletedTX(cfg=cfg, filename=tx_file)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ class SentTXRange(MMGenRange):
|
|||
min_idx = 0
|
||||
max_idx = 1_000_000
|
||||
|
||||
class CreatedTXRange(SentTXRange):
|
||||
pass
|
||||
|
||||
class OnlineSigned(Signed):
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -70,14 +70,14 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
('alice_txsend_abort5', 'aborting the transaction again (error)'),
|
||||
('generate', 'mining a block'),
|
||||
('alice_txcreate4', 'creating a transaction'),
|
||||
('alice_txbump1', 'bumping the unsigned transaction (error)'),
|
||||
('alice_txbump1', 'bumping the unsigned transaction (error, idx=0)'),
|
||||
('alice_txbump2', 'bumping the unsent transaction (error)'),
|
||||
('alice_txsend2_dump_hex', 'dumping the transaction to hex'),
|
||||
('alice_txsend2_cli', 'sending the transaction via cli'),
|
||||
('alice_txsend2_mark_sent', 'marking the transaction sent'),
|
||||
('alice_txbump3', 'bumping the transaction'),
|
||||
('alice_txsend3', 'sending the bumped transaction'),
|
||||
('alice_txbump4', 'bumping the transaction (new outputs, fee too low)'),
|
||||
('alice_txbump4', 'bumping the transaction (new outputs, fee too low, idx=0)'),
|
||||
('alice_txbump_abort1', 'aborting the transaction'),
|
||||
('alice_txbump5', 'bumping the transaction (new outputs)'),
|
||||
('alice_txsend5', 'sending the bumped transaction'),
|
||||
|
|
@ -86,6 +86,7 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
('alice_txstatus7', 'getting transaction status (tx_range=1, replaced)'),
|
||||
('alice_txstatus8', 'getting transaction status (tx_range=3, 2 confirmations)'),
|
||||
('alice_txstatus9', 'getting transaction status (tx_range=0-3)'),
|
||||
('alice_txbump6', 'bumping the next-to-last sent transaction (idx=1)'),
|
||||
('generate', 'mining a block'),
|
||||
('alice_bal2', 'checking Alice’s balance'),
|
||||
('wait_loop_kill', 'stopping autosign wait loop'),
|
||||
|
|
@ -293,7 +294,14 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
self.remove_device_online()
|
||||
return t
|
||||
|
||||
def _alice_txbump(self, fee_opt=None, output_args=[], bad_tx_expect=None, low_fee_fix=None):
|
||||
def _alice_txbump(
|
||||
self,
|
||||
fee_opt = None,
|
||||
output_args = [],
|
||||
bad_tx_expect = None,
|
||||
low_fee_fix = None,
|
||||
orig_tx_expect = None,
|
||||
idx = None):
|
||||
if not self.proto.cap('rbf'):
|
||||
return 'skip'
|
||||
self.insert_device_online()
|
||||
|
|
@ -301,6 +309,7 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
'mmgen-txbump',
|
||||
['--alice', '--autosign']
|
||||
+ ([fee_opt] if fee_opt else [])
|
||||
+ ([] if idx is None else [str(idx)])
|
||||
+ output_args,
|
||||
exit_val = 1 if bad_tx_expect else None)
|
||||
if bad_tx_expect:
|
||||
|
|
@ -308,6 +317,8 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
t.expect('Only sent transactions')
|
||||
t.expect(bad_tx_expect)
|
||||
else:
|
||||
if orig_tx_expect:
|
||||
t.expect(orig_tx_expect)
|
||||
if not output_args:
|
||||
t.expect(r'to deduct the fee from .* change output\): ', '\n', regex=True)
|
||||
t.expect(r'(Y/n): ', 'y') # output OK?
|
||||
|
|
@ -325,7 +336,7 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
return t
|
||||
|
||||
def alice_txbump1(self):
|
||||
return self._alice_txbump(bad_tx_expect='unsigned transaction')
|
||||
return self._alice_txbump(bad_tx_expect='unsigned transaction', idx=0)
|
||||
|
||||
def alice_txbump2(self):
|
||||
self._wait_signed('transaction')
|
||||
|
|
@ -339,7 +350,8 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
return self._alice_txbump(
|
||||
fee_opt = '--fee=3s',
|
||||
output_args = [f'{self.burn_addr},7.654321', f'{sid}:C:1'],
|
||||
low_fee_fix = '300s')
|
||||
low_fee_fix = '300s',
|
||||
idx = 0)
|
||||
|
||||
def alice_txbump_abort1(self):
|
||||
if not self.proto.cap('rbf'):
|
||||
|
|
@ -352,5 +364,8 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
fee_opt = '--fee=400s',
|
||||
output_args = ['data:message for posterity', f'{self.burn_addr},7.654321', f'{sid}:C:1'])
|
||||
|
||||
def alice_txbump6(self):
|
||||
return self._alice_txbump(idx=1, fee_opt='--fee=250s', orig_tx_expect='1.23456')
|
||||
|
||||
def alice_bal2(self):
|
||||
return self.user_bal('alice', self.bal2_chk[self.coin])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue