fixes and cleanups throughout
This commit is contained in:
parent
ef5f6e4b22
commit
7b6717d85a
11 changed files with 79 additions and 62 deletions
|
|
@ -164,34 +164,26 @@ async def main():
|
|||
kal = kl = sign_and_send = None
|
||||
else:
|
||||
orig_tx = await CompletedTX(cfg=cfg, filename=tx_file)
|
||||
kal = get_keyaddrlist(cfg, orig_tx.proto)
|
||||
kl = get_keylist(cfg)
|
||||
sign_and_send = any([seed_files, kl, kal])
|
||||
|
||||
if not silent:
|
||||
msg(green('ORIGINAL TRANSACTION'))
|
||||
msg(orig_tx.info.format(terse=True))
|
||||
|
||||
if not cfg.autosign:
|
||||
kal = get_keyaddrlist(cfg, orig_tx.proto)
|
||||
kl = get_keylist(cfg)
|
||||
sign_and_send = any([seed_files, kl, kal])
|
||||
|
||||
from .tw.ctl import TwCtl
|
||||
tx = await BumpTX(
|
||||
cfg = cfg,
|
||||
data = orig_tx.__dict__,
|
||||
automount = cfg.autosign,
|
||||
check_sent = cfg.autosign or sign_and_send,
|
||||
new_outputs = bool(cfg._args),
|
||||
twctl = await TwCtl(cfg, orig_tx.proto) if orig_tx.proto.tokensym else None)
|
||||
|
||||
tx.orig_rel_fee = tx.get_orig_rel_fee()
|
||||
|
||||
if cfg._args:
|
||||
tx.new_outputs = True
|
||||
tx.is_swap = False
|
||||
tx.outputs = tx.OutputList(tx)
|
||||
tx.cfg = cfg # NB: with --automount, must use current cfg opts, not those from orig_tx
|
||||
if tx.new_outputs:
|
||||
await tx.create(cfg._args, caller='txdo' if sign_and_send else 'txcreate')
|
||||
else:
|
||||
tx.new_outputs = False
|
||||
await tx.create_feebump(silent=silent)
|
||||
|
||||
if not silent:
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ from .new import New, TokenNew
|
|||
class Bump(Completed, New, TxBase.Bump):
|
||||
desc = 'fee-bumped transaction'
|
||||
|
||||
def get_orig_rel_fee(self): # disable this check for ETH
|
||||
return 0
|
||||
def get_orig_rel_fee(self):
|
||||
return self.txobj['gasPrice'].to_unit('Gwei')
|
||||
|
||||
@property
|
||||
def min_fee(self):
|
||||
|
|
|
|||
|
|
@ -15,16 +15,29 @@ tx.bump: transaction bump class
|
|||
from .new import New
|
||||
from .completed import Completed
|
||||
from ..util import msg, ymsg, is_int, die
|
||||
from ..color import pink
|
||||
|
||||
class Bump(Completed, New):
|
||||
desc = 'fee-bumped transaction'
|
||||
ext = 'rawtx'
|
||||
bump_output_idx = None
|
||||
is_bump = True
|
||||
swap_attrs = ('is_swap',)
|
||||
|
||||
def __init__(self, check_sent, *args, **kwargs):
|
||||
def __init__(self, *, check_sent, new_outputs, **kwargs):
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.new_outputs = new_outputs
|
||||
self.orig_rel_fee = self.get_orig_rel_fee()
|
||||
|
||||
if new_outputs:
|
||||
from .base import Base
|
||||
if self.is_swap:
|
||||
for attr in self.swap_attrs:
|
||||
setattr(self, attr, getattr(Base, attr))
|
||||
self.outputs = self.OutputList(self)
|
||||
self.cfg = kwargs['cfg'] # must use current cfg opts, not those from orig_tx
|
||||
|
||||
if not self.is_replaceable():
|
||||
die(1, f'Transaction {self.txid} is not replaceable')
|
||||
|
|
@ -60,7 +73,11 @@ class Bump(Completed, New):
|
|||
output_idx = self.choose_output()
|
||||
|
||||
if not silent:
|
||||
msg(f'Minimum fee for new transaction: {self.min_fee.hl()} {self.proto.coin}')
|
||||
msg('Minimum fee for new transaction: {} {} ({} {})'.format(
|
||||
self.min_fee.hl(),
|
||||
self.proto.coin,
|
||||
pink(self.fee_abs2rel(self.min_fee)),
|
||||
self.rel_fee_disp))
|
||||
|
||||
self.usr_fee = self.get_usr_fee_interactive(fee=self.cfg.fee, desc='User-selected')
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,9 @@ class New(Base):
|
|||
_funds_available = namedtuple('funds_available', ['is_positive', 'amt'])
|
||||
|
||||
def __init__(self, *args, target=None, **kwargs):
|
||||
self.is_swap = target == 'swaptx'
|
||||
if target == 'swaptx':
|
||||
self.is_swap = True
|
||||
self.swap_proto = kwargs['cfg'].swap_proto
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def warn_insufficient_funds(self, amt, coin):
|
||||
|
|
@ -183,6 +185,8 @@ class New(Base):
|
|||
|
||||
arg, amt = arg_in.split(',', 1) if ',' in arg_in else (arg_in, None)
|
||||
|
||||
coin_addr, mmid = (None, None)
|
||||
|
||||
if mmid := get_obj(MMGenID, proto=proto, id_str=arg, silent=True):
|
||||
coin_addr = mmaddr2coinaddr(self.cfg, arg, ad_w, ad_f, proto)
|
||||
elif is_coin_addr(proto, arg):
|
||||
|
|
@ -191,7 +195,6 @@ class New(Base):
|
|||
if proto.base_proto_coin != 'BTC':
|
||||
die(2, f'Change addresses not supported for {proto.name} protocol')
|
||||
self.chg_autoselected = True
|
||||
coin_addr = None
|
||||
else:
|
||||
die(2, f'{arg_in}: invalid command-line argument')
|
||||
|
||||
|
|
@ -219,7 +222,7 @@ class New(Base):
|
|||
|
||||
parsed_args = [self.parse_cmdline_arg(self.proto, arg, ad_f, ad_w) for arg in cmd_args]
|
||||
|
||||
chg_args = [a for a in parsed_args if not ((a.amt and a.addr) or a.data)]
|
||||
chg_args = [a for a in parsed_args if not (a.amt or a.data)]
|
||||
|
||||
if len(chg_args) > 1:
|
||||
desc = 'requested' if self.chg_autoselected else 'listed'
|
||||
|
|
@ -229,13 +232,15 @@ class New(Base):
|
|||
if a.data:
|
||||
self.add_output(None, self.proto.coin_amt('0'), data=a.data)
|
||||
else:
|
||||
exclude = [a.mmid for a in parsed_args if a.mmid]
|
||||
self.add_output(
|
||||
coinaddr = a.addr or (
|
||||
await self.get_autochg_addr(self.proto, a.arg, exclude=exclude, desc='change address')
|
||||
).addr,
|
||||
amt = self.proto.coin_amt(a.amt or '0'),
|
||||
is_chg = not a.amt)
|
||||
await self.get_autochg_addr(
|
||||
self.proto,
|
||||
a.arg,
|
||||
exclude = [a.mmid for a in parsed_args if a.mmid],
|
||||
desc = 'change address')).addr,
|
||||
amt = self.proto.coin_amt(a.amt or '0'),
|
||||
is_chg = not a.amt)
|
||||
|
||||
if self.chg_idx is None:
|
||||
die(2,
|
||||
|
|
@ -387,13 +392,14 @@ class New(Base):
|
|||
sel_unspent,
|
||||
outputs_sum):
|
||||
return False
|
||||
|
||||
self.copy_inputs_from_tw(sel_unspent) # makes self.inputs
|
||||
return True
|
||||
|
||||
async def get_fee(self, fee, outputs_sum):
|
||||
async def get_fee(self, fee, outputs_sum, start_fee_desc):
|
||||
|
||||
if fee:
|
||||
self.usr_fee = self.get_usr_fee_interactive(fee, 'User-selected')
|
||||
self.usr_fee = self.get_usr_fee_interactive(fee, start_fee_desc)
|
||||
else:
|
||||
fee_per_kb, fe_type = await self.get_rel_fee_from_network()
|
||||
self.usr_fee = self.get_usr_fee_interactive(
|
||||
|
|
@ -468,7 +474,10 @@ class New(Base):
|
|||
fee_hint = None
|
||||
if self.is_swap:
|
||||
fee_hint = self.update_vault_output(self.vault_output.amt or self.sum_inputs())
|
||||
if funds_left := await self.get_fee(fee_hint or self.cfg.fee, outputs_sum):
|
||||
if funds_left := await self.get_fee(
|
||||
self.cfg.fee or fee_hint,
|
||||
outputs_sum,
|
||||
'User-selected' if self.cfg.fee else 'Recommended' if fee_hint else None):
|
||||
break
|
||||
|
||||
self.check_non_mmgen_inputs(caller)
|
||||
|
|
|
|||
|
|
@ -123,6 +123,15 @@ def exec_wrapper_tracemalloc_log():
|
|||
s = sum(stat.size for stat in stats) / 1024,
|
||||
w = col1w))
|
||||
|
||||
def exec_wrapper_do_exit(e, exit_val):
|
||||
if exit_val != 0:
|
||||
exec_wrapper_write_traceback(e, exit_val)
|
||||
else:
|
||||
if exec_wrapper_os.getenv('MMGEN_TRACEMALLOC'):
|
||||
exec_wrapper_tracemalloc_log()
|
||||
exec_wrapper_end_msg()
|
||||
exec_wrapper_sys.exit(exit_val)
|
||||
|
||||
import sys as exec_wrapper_sys
|
||||
import os as exec_wrapper_os
|
||||
import time as exec_wrapper_time
|
||||
|
|
@ -145,17 +154,10 @@ try:
|
|||
with open(exec_wrapper_execed_file) as fp:
|
||||
exec(fp.read())
|
||||
except SystemExit as e:
|
||||
if e.code != 0:
|
||||
exec_wrapper_write_traceback(e, e.code)
|
||||
else:
|
||||
if exec_wrapper_os.getenv('MMGEN_TRACEMALLOC'):
|
||||
exec_wrapper_tracemalloc_log()
|
||||
exec_wrapper_end_msg()
|
||||
exec_wrapper_sys.exit(e.code)
|
||||
exec_wrapper_do_exit(e, e.code)
|
||||
except Exception as e:
|
||||
exit_val = e.mmcode if hasattr(e, 'mmcode') else e.code if hasattr(e, 'code') else 1
|
||||
exec_wrapper_write_traceback(e, exit_val)
|
||||
exec_wrapper_sys.exit(exit_val)
|
||||
exec_wrapper_do_exit(
|
||||
e, e.mmcode if hasattr(e, 'mmcode') else e.code if hasattr(e, 'code') else 1)
|
||||
|
||||
if exec_wrapper_os.getenv('MMGEN_TRACEMALLOC'):
|
||||
exec_wrapper_tracemalloc_log()
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ class CmdGroupMgr:
|
|||
yield ' {} - {}'.format(
|
||||
yellow(name.ljust(13)),
|
||||
(cls.__doc__.strip() if cls.__doc__ else cls.__name__))
|
||||
if hasattr(cls, 'cmd_subgroups'):
|
||||
if 'cmd_subgroups' in cls.__dict__:
|
||||
subgroups = {k:v for k, v in cls.cmd_subgroups.items() if not k.startswith('_')}
|
||||
max_w = max(len(k) for k in subgroups)
|
||||
for k, v in subgroups.items():
|
||||
|
|
@ -762,7 +762,8 @@ class CmdTestRunner:
|
|||
if isinstance(e, KeyError) and e.args[0] == cmdname:
|
||||
ret = getattr(self.tg, cmdname)()
|
||||
if type(ret).__name__ == 'coroutine':
|
||||
asyncio.run(ret)
|
||||
ret = asyncio.run(ret)
|
||||
self.process_retval(cmdname, ret)
|
||||
else:
|
||||
raise
|
||||
do_between()
|
||||
|
|
|
|||
|
|
@ -14,14 +14,15 @@ test.cmdtest_d.ct_automount: autosigning with automount tests for the cmdtest.py
|
|||
import time
|
||||
|
||||
from .ct_autosign import CmdTestAutosignThreaded
|
||||
from .ct_regtest import CmdTestRegtestBDBWallet, rt_pw
|
||||
from .ct_regtest import CmdTestRegtest, rt_pw
|
||||
from ..include.common import cfg, gr_uc
|
||||
|
||||
class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet):
|
||||
class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
||||
'automounted transacting operations via regtest mode'
|
||||
|
||||
networks = ('btc', 'bch', 'ltc')
|
||||
tmpdir_nums = [49]
|
||||
bdb_wallet = True
|
||||
|
||||
rt_data = {
|
||||
'rtFundAmt': {'btc':'500', 'bch':'500', 'ltc':'5500'},
|
||||
|
|
@ -78,7 +79,7 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtestBDBWallet)
|
|||
self.coins = [cfg.coin.lower()]
|
||||
|
||||
CmdTestAutosignThreaded.__init__(self, trunner, cfgs, spawn)
|
||||
CmdTestRegtestBDBWallet.__init__(self, trunner, cfgs, spawn)
|
||||
CmdTestRegtest.__init__(self, trunner, cfgs, spawn)
|
||||
|
||||
if trunner is None:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -441,19 +441,22 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase):
|
|||
no_insert_check = False
|
||||
threaded = True
|
||||
|
||||
def _wait_loop_start(self):
|
||||
def _wait_loop_start(self, add_opts=[]):
|
||||
t = self.spawn(
|
||||
'mmgen-autosign',
|
||||
self.opts + ['--full-summary', 'wait'],
|
||||
self.opts + add_opts + ['--full-summary', 'wait'],
|
||||
direct_exec = True,
|
||||
no_passthru_opts = True,
|
||||
spawn_env_override = self.spawn_env | {'EXEC_WRAPPER_DO_RUNTIME_MSG': ''})
|
||||
self.write_to_tmpfile('autosign_thread_pid', str(t.ep.pid))
|
||||
return t
|
||||
|
||||
def wait_loop_start(self):
|
||||
def wait_loop_start(self, add_opts=[]):
|
||||
import threading
|
||||
threading.Thread(target=self._wait_loop_start, name='Autosign wait loop').start()
|
||||
threading.Thread(
|
||||
target = self._wait_loop_start,
|
||||
kwargs = {'add_opts': add_opts},
|
||||
name = 'Autosign wait loop').start()
|
||||
time.sleep(0.1) # try to ensure test output is displayed before next test starts
|
||||
return 'silent'
|
||||
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|||
('bob_split1', 'splitting Bob’s funds'),
|
||||
('generate', 'mining a block'),
|
||||
('bob_bal2', 'Bob’s balance'),
|
||||
('bob_rbf_1output_create', 'creating RBF tx with one output'),
|
||||
('bob_rbf_1output_bump', 'bumping RBF tx with one output'),
|
||||
('bob_rbf_1output_create', 'creating RBF TX with one output'),
|
||||
('bob_rbf_1output_bump', 'creating replacement TX with one output'),
|
||||
('bob_bal2a', 'Bob’s balance (age_fmt=confs)'),
|
||||
('bob_bal2b', 'Bob’s balance (showempty=1)'),
|
||||
('bob_bal2c', 'Bob’s balance (showempty=1 minconf=2 age_fmt=days)'),
|
||||
|
|
@ -1122,7 +1122,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|||
one_output = True)
|
||||
|
||||
def bob_send_maybe_rbf(self):
|
||||
outputs_cl = self._create_tx_outputs('alice', (('L', 1, ', 60'), ('C', 1, ', 40')))
|
||||
outputs_cl = self._create_tx_outputs('alice', (('L', 1, ',60'), ('C', 1, ',40')))
|
||||
outputs_cl += [self._user_sid('bob')+':'+rtBobOp3]
|
||||
return self.user_txdo(
|
||||
user = 'bob',
|
||||
|
|
@ -2174,4 +2174,5 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|||
return 'ok'
|
||||
|
||||
class CmdTestRegtestBDBWallet(CmdTestRegtest):
|
||||
'transacting and tracking wallet operations via regtest mode (legacy BDB wallet)'
|
||||
bdb_wallet = True
|
||||
|
|
|
|||
|
|
@ -13,15 +13,8 @@ test.cmdtest_d.ct_swap: asset swap tests for the cmdtest.py test suite
|
|||
"""
|
||||
|
||||
from mmgen.protocol import init_proto
|
||||
|
||||
from ..include.common import gr_uc
|
||||
|
||||
from .ct_regtest import (
|
||||
CmdTestRegtest,
|
||||
rt_data,
|
||||
dfl_wcls,
|
||||
rt_pw,
|
||||
cfg)
|
||||
from .ct_regtest import CmdTestRegtest, rt_data, dfl_wcls, rt_pw, cfg
|
||||
|
||||
sample1 = gr_uc[:24]
|
||||
sample2 = '00010203040506'
|
||||
|
|
|
|||
|
|
@ -217,9 +217,7 @@ do_reexec() {
|
|||
|
||||
install_secp256k1_mod_maybe() {
|
||||
if [[ "$repo" =~ ^mmgen[-_]wallet ]]; then
|
||||
[ -e mmgen/proto/secp256k1/secp256k1*$(python3 --version | sed 's/.* //;s/\.//;s/\..*//')* ] || {
|
||||
eval "python3 setup.py build_ext --inplace $STDOUT_DEVNULL"
|
||||
}
|
||||
eval "python3 setup.py build_ext --inplace $STDOUT_DEVNULL"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue