MMGenTxInput, MMGenTxOutput: make 'amt' attribute a property
- type checking 'amt' at runtime eliminates the need to reload tx module when g.proto changes
This commit is contained in:
parent
f08cd32e33
commit
785582e30d
7 changed files with 27 additions and 18 deletions
|
|
@ -162,7 +162,6 @@ def do_umount():
|
|||
subprocess.call(['umount',mountpoint])
|
||||
|
||||
def sign_tx_file(txfile):
|
||||
from importlib import reload
|
||||
try:
|
||||
g.testnet = False
|
||||
g.coin = 'BTC'
|
||||
|
|
@ -183,10 +182,6 @@ def sign_tx_file(txfile):
|
|||
g.token = tmp_tx.dcoin
|
||||
g.dcoin = tmp_tx.dcoin or g.coin
|
||||
|
||||
reload(sys.modules['mmgen.tx'])
|
||||
if g.proto.base_coin == 'ETH':
|
||||
reload(sys.modules['mmgen.altcoins.eth.tx'])
|
||||
|
||||
tx = mmgen.tx.MMGenTX(txfile)
|
||||
|
||||
if g.proto.sign_mode == 'daemon':
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ tx1.create_fn()
|
|||
gmsg("\nCreating transaction for short chain ({})".format(opt.other_coin))
|
||||
|
||||
init_coin(opt.other_coin)
|
||||
reload(sys.modules['mmgen.tx'])
|
||||
|
||||
tx2 = MMGenSplitTX()
|
||||
tx2.inputs = tx1.inputs
|
||||
|
|
|
|||
14
mmgen/obj.py
14
mmgen/obj.py
|
|
@ -192,9 +192,10 @@ class Hilite(object):
|
|||
# Reassignment and deletion forbidden
|
||||
class MMGenImmutableAttr(object): # Descriptor
|
||||
|
||||
def __init__(self,name,dtype,typeconv=True):
|
||||
def __init__(self,name,dtype,typeconv=True,no_type_check=False):
|
||||
self.typeconv = typeconv
|
||||
assert type(dtype) in (str,type)
|
||||
self.no_type_check = no_type_check
|
||||
assert type(dtype) in (str,type) or dtype is None
|
||||
self.name = name
|
||||
self.dtype = dtype
|
||||
|
||||
|
|
@ -214,10 +215,11 @@ class MMGenImmutableAttr(object): # Descriptor
|
|||
instance.__dict__[self.name] = \
|
||||
globals()[self.dtype](value,on_fail='raise') if type(self.dtype) == str else self.dtype(value)
|
||||
else: # check type
|
||||
if type(value) != self.dtype:
|
||||
if type(value) == self.dtype or self.no_type_check:
|
||||
instance.__dict__[self.name] = value
|
||||
else:
|
||||
m = "Attribute '{}' of {} instance must of type {}"
|
||||
raise TypeError(m.format(self.name,type(instance),self.dtype))
|
||||
instance.__dict__[self.name] = value
|
||||
|
||||
def __delete__(self,instance):
|
||||
m = "Atribute '{}' of {} instance cannot be deleted"
|
||||
|
|
@ -250,11 +252,13 @@ class MMGenListItemAttr(MMGenImmutableAttr): # Descriptor
|
|||
class MMGenListItem(MMGenObject):
|
||||
|
||||
valid_attrs = None
|
||||
valid_attrs_extra = set()
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
if self.valid_attrs == None:
|
||||
type(self).valid_attrs = (
|
||||
{e for e in dir(self) if e[:2] != '__'} - {'pformat','pmsg','pdie','valid_attrs'} )
|
||||
( {e for e in dir(self) if e[:2] != '__'} | self.valid_attrs_extra ) -
|
||||
{'pformat','pmsg','pdie','valid_attrs','valid_attrs_extra'} )
|
||||
if args:
|
||||
raise ValueError('Non-keyword args not allowed')
|
||||
for k in kwargs:
|
||||
|
|
|
|||
18
mmgen/tx.py
18
mmgen/tx.py
|
|
@ -209,7 +209,7 @@ class DeserializedTX(dict,MMGenObject):
|
|||
|
||||
class MMGenTxIO(MMGenListItem):
|
||||
vout = MMGenListItemAttr('vout',int,typeconv=False)
|
||||
amt = MMGenImmutableAttr('amt',g.proto.coin_amt,typeconv=False) # require amt to be of proper type
|
||||
_amt = MMGenImmutableAttr('amt',None,no_type_check=True,typeconv=False)
|
||||
label = MMGenListItemAttr('label','TwComment',reassign_ok=True)
|
||||
mmid = MMGenListItemAttr('mmid','MMGenID')
|
||||
addr = MMGenImmutableAttr('addr','CoinAddr')
|
||||
|
|
@ -217,6 +217,22 @@ class MMGenTxIO(MMGenListItem):
|
|||
txid = MMGenListItemAttr('txid','CoinTxID')
|
||||
have_wif = MMGenListItemAttr('have_wif',bool,typeconv=False,delete_ok=True)
|
||||
|
||||
valid_attrs_extra = {'amt'}
|
||||
|
||||
# Setting self.amt is runtime-dependent, so make it a property
|
||||
# Make underlying self._amt an MMGenImmutableAttr so that reassignment is prevented
|
||||
@property
|
||||
def amt(self):
|
||||
if type(self._amt) != g.proto.coin_amt:
|
||||
raise ValueError('{}: invalid coin_amt type (must be {})'.format(type(self._amt),g.proto.coin_amt))
|
||||
return self._amt
|
||||
|
||||
@amt.setter
|
||||
def amt(self,val):
|
||||
if type(val) != g.proto.coin_amt:
|
||||
raise ValueError('{}: invalid coin_amt type (must be {})'.format(type(val),g.proto.coin_amt))
|
||||
self._amt = val
|
||||
|
||||
class MMGenTxInput(MMGenTxIO):
|
||||
scriptPubKey = MMGenListItemAttr('scriptPubKey','HexStr')
|
||||
sequence = MMGenListItemAttr('sequence',int,typeconv=False)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ t_obj=(
|
|||
"$objtest_py --coin=ltc --testnet=1")
|
||||
f_obj='Data object test complete'
|
||||
|
||||
i_unit='Unit tests'
|
||||
i_unit='Unit'
|
||||
s_unit='Running unit'
|
||||
t_unit=("$unit_tests_py")
|
||||
f_unit='Unit tests run complete'
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ if opt.verbose:
|
|||
from mmgen.protocol import init_coin
|
||||
init_coin('BCH')
|
||||
|
||||
reload(sys.modules['mmgen.tx'])
|
||||
|
||||
if opt.verbose:
|
||||
gmsg('Converting transaction to {} format'.format(g.coin))
|
||||
|
||||
|
|
|
|||
|
|
@ -137,16 +137,13 @@ class UnitTests(object):
|
|||
('bch',False,'test/ref/460D4D-BCH[10.19764,tl=1320969600].rawtx') )
|
||||
from mmgen.protocol import init_coin
|
||||
from mmgen.tx import MMGenTX
|
||||
from importlib import reload
|
||||
print_info('test/ref/*rawtx','MMGen reference transactions')
|
||||
for n,(coin,tn,fn) in enumerate(fns):
|
||||
init_coin(coin,tn)
|
||||
rpc_init(reinit=True)
|
||||
reload(sys.modules['mmgen.tx'])
|
||||
test_tx(MMGenTX(fn).hex,fn,n+1)
|
||||
init_coin('btc',False)
|
||||
rpc_init(reinit=True)
|
||||
reload(sys.modules['mmgen.tx'])
|
||||
Msg('OK')
|
||||
|
||||
from mmgen.tx import DeserializedTX
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue