tx.new: support relative fees < 1 unit; add test
This commit is contained in:
parent
c7b2626d6e
commit
1cab2f9d6d
5 changed files with 41 additions and 14 deletions
|
|
@ -73,8 +73,8 @@ class New(Base, TxNew):
|
|||
return fee_per_kb, fe_type
|
||||
|
||||
# given tx size, rel fee and units, return absolute fee
|
||||
def fee_rel2abs(self, tx_size, units, amt_in_units, unit):
|
||||
return self.proto.coin_amt(amt_in_units * tx_size, from_unit=units[unit])
|
||||
def fee_rel2abs(self, tx_size, amt_in_units, unit):
|
||||
return self.proto.coin_amt(int(amt_in_units * tx_size), from_unit=unit)
|
||||
|
||||
# given network fee estimate in BTC/kB, return absolute fee using estimated tx size
|
||||
def fee_est2abs(self, fee_per_kb, *, fe_type=None):
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ class Base(TxBase.Base):
|
|||
return self.outputs
|
||||
|
||||
def pretty_fmt_fee(self, fee):
|
||||
if fee < 1:
|
||||
ret = f'{fee:.8f}'.rstrip('0')
|
||||
return ret + '0' if ret.endswith('.') else ret
|
||||
if fee < 10:
|
||||
return f'{fee:.3f}'.rstrip('0').rstrip('.')
|
||||
return str(int(fee))
|
||||
|
||||
# given absolute fee in ETH, return gas price for display in selected unit
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ class New(Base, TxBase.New):
|
|||
assert self.usr_fee <= self.proto.max_tx_fee
|
||||
|
||||
# given rel fee and units, return absolute fee using self.gas
|
||||
def fee_rel2abs(self, tx_size, units, amt_in_units, unit):
|
||||
return self.proto.coin_amt(amt_in_units, from_unit=units[unit]) * self.gas.toWei()
|
||||
def fee_rel2abs(self, tx_size, amt_in_units, unit):
|
||||
return self.proto.coin_amt(int(amt_in_units * self.gas.toWei()), from_unit=unit)
|
||||
|
||||
# given fee estimate (gas price) in wei, return absolute fee, adjusting by self.cfg.fee_adjust
|
||||
def fee_est2abs(self, rel_fee, *, fe_type=None):
|
||||
|
|
|
|||
|
|
@ -70,6 +70,13 @@ def mmaddr2coinaddr(cfg, mmaddr, ad_w, ad_f, proto):
|
|||
|
||||
return CoinAddr(proto, coin_addr)
|
||||
|
||||
def parse_fee_spec(proto, fee_arg):
|
||||
import re
|
||||
units = {u[0]:u for u in proto.coin_amt.units}
|
||||
pat = re.compile(r'((?:[1-9][0-9]*)|(?:[0-9]+\.[0-9]+))({})'.format('|'.join(units)))
|
||||
if m := pat.match(fee_arg):
|
||||
return namedtuple('parsed_fee_spec', ['amt', 'unit'])(m[1], units[m[2]])
|
||||
|
||||
class New(Base):
|
||||
|
||||
fee_is_approximate = False
|
||||
|
|
@ -117,12 +124,8 @@ class New(Base):
|
|||
if fee := get_obj(self.proto.coin_amt, num=fee_arg, silent=True):
|
||||
return fee
|
||||
|
||||
import re
|
||||
units = {u[0]:u for u in self.proto.coin_amt.units}
|
||||
pat = re.compile(r'([1-9][0-9]*)({})'.format('|'.join(units)))
|
||||
if pat.match(fee_arg):
|
||||
amt, unit = pat.match(fee_arg).groups()
|
||||
return self.fee_rel2abs(tx_size, units, int(amt), unit)
|
||||
if res := parse_fee_spec(self.proto, fee_arg):
|
||||
return self.fee_rel2abs(tx_size, float(res.amt), res.unit)
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ test.modtest_d.ut_amt: CoinAmt unit tests for the MMGen suite
|
|||
from decimal import Decimal
|
||||
|
||||
from mmgen.protocol import init_proto
|
||||
from mmgen.tx.new import parse_fee_spec
|
||||
from mmgen.cfg import Config
|
||||
|
||||
from ..include.common import cfg, vmsg
|
||||
|
|
@ -26,9 +27,18 @@ def test_to_unit(data):
|
|||
assert res == int(chk), f'{res} != {int(chk)}'
|
||||
return True
|
||||
|
||||
def test_fee_spec(data):
|
||||
protos = get_protos(data)
|
||||
for proto, spec, amt, unit in data:
|
||||
vmsg(f' {proto.upper():6} {spec:<5} => {amt:<4} {unit}')
|
||||
res = parse_fee_spec(protos[proto], spec)
|
||||
assert res.amt == amt, f' {res.amt} != {amt}'
|
||||
assert res.unit == unit, f' {res.unit} != {unit}'
|
||||
return True
|
||||
|
||||
class unit_tests:
|
||||
|
||||
altcoin_deps = ('to_unit_alt',)
|
||||
altcoin_deps = ('fee_spec_alt', 'to_unit_alt')
|
||||
|
||||
def to_unit(self, name, ut, desc='CoinAmt.to_unit() (BTC)'):
|
||||
return test_to_unit((
|
||||
|
|
@ -54,3 +64,18 @@ class unit_tests:
|
|||
('xmr', '1', 'atomic', '1000000000000'),
|
||||
('xmr', '0.000000000001', 'atomic', '1'),
|
||||
('xmr', '1.234567890123', 'atomic', '1234567890123')))
|
||||
|
||||
def fee_spec(self, name, ut, desc='fee spec parsing (BTC)'):
|
||||
return test_fee_spec((
|
||||
('btc', '32s', '32', 'satoshi'),
|
||||
('btc', '1s', '1', 'satoshi')))
|
||||
|
||||
def fee_spec_alt(self, name, ut, desc='fee spec parsing (LTC, BCH, ETH, XMR)'):
|
||||
return test_fee_spec((
|
||||
('ltc', '3.07s', '3.07', 'satoshi'),
|
||||
('bch', '3.07s', '3.07', 'satoshi'),
|
||||
('eth', '3.07G', '3.07', 'Gwei'),
|
||||
('eth', '37M', '37', 'Mwei'),
|
||||
('eth', '3701w', '3701', 'wei'),
|
||||
('eth', '3.07M', '3.07', 'Mwei'),
|
||||
('xmr', '3.07a', '3.07', 'atomic')))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue