coin protocol, txview: minor cleanups
This commit is contained in:
parent
4204a32311
commit
28b4f56919
3 changed files with 53 additions and 46 deletions
|
|
@ -193,7 +193,7 @@ Network-estimated fees will be multiplied by the value of '--tx-fee-adj',
|
|||
if specified.
|
||||
|
||||
Ages of transactions are approximate based on an average block discovery
|
||||
interval of one per {g.proto.secs_per_block} seconds.
|
||||
interval of one per {g.proto.avg_bdi} seconds.
|
||||
|
||||
All addresses on the command line can be either {pnu} addresses or {pnm}
|
||||
addresses of the form <seed ID>:<index>.
|
||||
|
|
|
|||
|
|
@ -110,11 +110,10 @@ class CoinProtocol(MMGenObject):
|
|||
dfl_mmtype = 'L'
|
||||
data_subdir = ''
|
||||
rpc_port = 8332
|
||||
secs_per_block = 600
|
||||
coin_amt = BTCAmt
|
||||
max_tx_fee = BTCAmt('0.003')
|
||||
daemon_data_dir = os.path.join(os.getenv('APPDATA'),'Bitcoin') if g.platform == 'win' \
|
||||
else os.path.join(g.home_dir,'.bitcoin')
|
||||
daemon_data_dir = ( os.path.join(os.getenv('APPDATA'),'Bitcoin') if g.platform == 'win' else
|
||||
os.path.join(g.home_dir,'.bitcoin') )
|
||||
daemon_data_subdir = ''
|
||||
sighash_type = 'ALL'
|
||||
block0 = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
|
||||
|
|
@ -248,8 +247,8 @@ class CoinProtocol(MMGenObject):
|
|||
is_fork_of = 'Bitcoin'
|
||||
# TODO: assumes MSWin user installs in custom dir 'Bitcoin_ABC'
|
||||
daemon_name = 'bitcoind-abc'
|
||||
daemon_data_dir = os.path.join(os.getenv('APPDATA'),'Bitcoin_ABC') if g.platform == 'win' \
|
||||
else os.path.join(g.home_dir,'.bitcoin-abc')
|
||||
daemon_data_dir = ( os.path.join(os.getenv('APPDATA'),'Bitcoin_ABC') if g.platform == 'win' else
|
||||
os.path.join(g.home_dir,'.bitcoin-abc') )
|
||||
rpc_port = 8442
|
||||
mmtypes = ('L','C')
|
||||
sighash_type = 'ALL|FORKID'
|
||||
|
|
@ -276,8 +275,8 @@ class CoinProtocol(MMGenObject):
|
|||
class B2X(Bitcoin):
|
||||
is_fork_of = 'Bitcoin'
|
||||
daemon_name = 'bitcoind-2x'
|
||||
daemon_data_dir = os.path.join(os.getenv('APPDATA'),'Bitcoin_2X') if g.platform == 'win' \
|
||||
else os.path.join(g.home_dir,'.bitcoin-2x')
|
||||
daemon_data_dir = ( os.path.join(os.getenv('APPDATA'),'Bitcoin_2X') if g.platform == 'win' else
|
||||
os.path.join(g.home_dir,'.bitcoin-2x') )
|
||||
rpc_port = 8338
|
||||
coin_amt = B2XAmt
|
||||
max_tx_fee = B2XAmt('0.1')
|
||||
|
|
@ -295,19 +294,18 @@ class CoinProtocol(MMGenObject):
|
|||
class Litecoin(Bitcoin):
|
||||
block0 = '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2'
|
||||
daemon_name = 'litecoind'
|
||||
daemon_data_dir = os.path.join(os.getenv('APPDATA'),'Litecoin') if g.platform == 'win' \
|
||||
else os.path.join(g.home_dir,'.litecoin')
|
||||
daemon_data_dir = ( os.path.join(os.getenv('APPDATA'),'Litecoin') if g.platform == 'win' else
|
||||
os.path.join(g.home_dir,'.litecoin') )
|
||||
addr_ver_bytes = { '30': 'p2pkh', '32': 'p2sh', '05': 'p2sh' } # new p2sh ver 0x32 must come first
|
||||
wif_ver_num = { 'std': 'b0' }
|
||||
mmtypes = ('L','C','S','B')
|
||||
secs_per_block = 150
|
||||
rpc_port = 9332
|
||||
coin_amt = LTCAmt
|
||||
max_tx_fee = LTCAmt('0.3')
|
||||
base_coin = 'LTC'
|
||||
forks = []
|
||||
bech32_hrp = 'ltc'
|
||||
avg_bdi = 2 * 60
|
||||
avg_bdi = 150
|
||||
|
||||
class LitecoinTestnet(Litecoin):
|
||||
# addr ver nums same as Bitcoin testnet, except for 'p2sh'
|
||||
|
|
@ -327,7 +325,7 @@ class CoinProtocol(MMGenObject):
|
|||
class BitcoinAddrgenTestnet(BitcoinTestnet):
|
||||
mmcaps = ('key','addr')
|
||||
|
||||
class DummyWIF(object):
|
||||
class DummyWIF:
|
||||
|
||||
def hex2wif(self,hexpriv,pubkey_type,compressed):
|
||||
n = self.name.capitalize()
|
||||
|
|
@ -358,16 +356,18 @@ class CoinProtocol(MMGenObject):
|
|||
sign_mode = 'standalone'
|
||||
caps = ('token',)
|
||||
base_proto = 'Ethereum'
|
||||
avg_bdi = 15
|
||||
|
||||
def parse_addr(self,addr):
|
||||
from .util import is_hex_str_lc
|
||||
if is_hex_str_lc(addr) and len(addr) == self.addr_len * 2:
|
||||
return parsed_addr( bytes.fromhex(addr), 'ethereum' )
|
||||
if g.debug: Msg("Invalid address '{}'".format(addr))
|
||||
if g.debug:
|
||||
Msg(f'Invalid address: {addr}')
|
||||
return False
|
||||
|
||||
def pubhash2addr(self,pubkey_hash,p2sh):
|
||||
assert len(pubkey_hash) == 40,'{}: invalid length for pubkey hash'.format(len(pubkey_hash))
|
||||
assert len(pubkey_hash) == 40, f'{len(pubkey_hash)}: invalid length for pubkey hash'
|
||||
assert not p2sh,'Ethereum has no P2SH address format'
|
||||
return pubkey_hash
|
||||
|
||||
|
|
@ -390,6 +390,7 @@ class CoinProtocol(MMGenObject):
|
|||
wif_ver_num = { 'std': '80', 'zcash_z': 'ab36' }
|
||||
mmtypes = ('L','C','Z')
|
||||
dfl_mmtype = 'L'
|
||||
avg_bdi = 75
|
||||
|
||||
def get_addr_len(self,addr_fmt):
|
||||
return (20,64)[addr_fmt in ('zcash_z','viewkey')]
|
||||
|
|
@ -413,7 +414,7 @@ class CoinProtocol(MMGenObject):
|
|||
wif_ver_num = { 'std': 'ef', 'zcash_z': 'ac08' }
|
||||
addr_ver_bytes = { '1d25': 'p2pkh', '1cba': 'p2sh', '16b6': 'zcash_z', 'a8ac0c': 'viewkey' }
|
||||
|
||||
# https://github.com/monero-project/monero/blob/master/src/cryptonote_config.h
|
||||
# https://github.com/monero-project/monero/blob/master/src/cryptonote_config.h
|
||||
class Monero(DummyWIF,BitcoinAddrgen):
|
||||
base_coin = 'XMR'
|
||||
addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub' }
|
||||
|
|
@ -422,6 +423,7 @@ class CoinProtocol(MMGenObject):
|
|||
mmtypes = ('M',)
|
||||
dfl_mmtype = 'M'
|
||||
pubkey_type = 'monero' # required by DummyWIF
|
||||
avg_bdi = 120
|
||||
|
||||
def preprocess_key(self,sec,pubkey_type): # reduce key
|
||||
from .ed25519 import l
|
||||
|
|
@ -447,7 +449,7 @@ class CoinProtocol(MMGenObject):
|
|||
from .keccak import keccak_256
|
||||
|
||||
chk = keccak_256(ret[:-4]).digest()[:4]
|
||||
assert ret[-4:] == chk,'{}: incorrect checksum. Correct value: {}'.format(ret[-4:].hex(),chk.hex())
|
||||
assert ret[-4:] == chk, f'{ret[-4:].hex()}: incorrect checksum. Correct value: {chk.hex()}'
|
||||
|
||||
return self.parse_addr_bytes(ret)
|
||||
|
||||
|
|
@ -506,11 +508,9 @@ def init_genonly_altcoins(usr_coin=None,testnet=False):
|
|||
|
||||
cinfo = data[network][0]
|
||||
if not cinfo:
|
||||
m = '{!r}: unrecognized coin for network {}'
|
||||
raise ValueError(m.format(usr_coin.upper(),network.upper()))
|
||||
raise ValueError(f'{usr_coin.upper()!r}: unrecognized coin for network {network.upper()}')
|
||||
if cinfo.trust_level == -1:
|
||||
m = '{!r}: unsupported (disabled) coin for network {}'
|
||||
raise ValueError(m.format(usr_coin.upper(),network.upper()))
|
||||
raise ValueError(f'{usr_coin.upper()!r}: unsupported (disabled) coin for network {network.upper()}')
|
||||
|
||||
trust_level = cinfo.trust_level
|
||||
|
||||
|
|
@ -549,7 +549,6 @@ def make_init_genonly_altcoins_str(data):
|
|||
yield make_proto(e)
|
||||
for e in data['testnet']:
|
||||
yield make_proto(e,testnet=True)
|
||||
yield ''
|
||||
|
||||
for e in data['mainnet']:
|
||||
proto,coin = e.name,e.symbol
|
||||
|
|
|
|||
54
mmgen/tx.py
54
mmgen/tx.py
|
|
@ -1020,22 +1020,22 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam
|
|||
def format_view_body(self,blockcount,nonmm_str,max_mmwid,enl,terse,sort):
|
||||
|
||||
if sort not in self.view_sort_orders:
|
||||
m = '{!r}: invalid transaction view sort order. Valid options: {}'
|
||||
die(1,m.format(sort,','.join(self.view_sort_orders)))
|
||||
die(1,f'{sort!r}: invalid transaction view sort order. Valid options: {{}}'.format(
|
||||
','.join(self.view_sort_orders) ))
|
||||
|
||||
def format_io(desc):
|
||||
io = getattr(self,desc)
|
||||
ip = desc == 'inputs'
|
||||
out = desc.capitalize() + ':\n' + enl
|
||||
is_input = desc == 'inputs'
|
||||
yield desc.capitalize() + ':\n' + enl
|
||||
addr_w = max(len(e.addr) for e in io)
|
||||
confs_per_day = 60*60*24 // g.proto.secs_per_block
|
||||
confs_per_day = 60*60*24 // g.proto.avg_bdi
|
||||
io_sorted = {
|
||||
# prepend '/' (sorts before '0') to ensure non-MMGen addrs are displayed first
|
||||
'addr': lambda: sorted(io,key=lambda o: o.mmid.sort_key if o.mmid else '/'+o.addr),
|
||||
'raw': lambda: io
|
||||
}[sort]
|
||||
for n,e in enumerate(io_sorted()):
|
||||
if ip and blockcount:
|
||||
if is_input and blockcount:
|
||||
confs = e.confs + blockcount - self.blockcount
|
||||
days = int(confs // confs_per_day)
|
||||
if e.mmid:
|
||||
|
|
@ -1043,30 +1043,38 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam
|
|||
width=max_mmwid,
|
||||
encl='()',
|
||||
color=True,
|
||||
append_chars=('',' (chg)')[bool(not ip and e.is_chg and terse)],
|
||||
append_chars=('',' (chg)')[bool(not is_input and e.is_chg and terse)],
|
||||
append_color='green')
|
||||
else:
|
||||
mmid_fmt = MMGenID.fmtc(nonmm_str,width=max_mmwid,color=True)
|
||||
if terse:
|
||||
out += '{:3} {} {} {} {}\n'.format(n+1,
|
||||
yield '{:3} {} {} {} {}\n'.format(
|
||||
n+1,
|
||||
e.addr.fmt(color=True,width=addr_w),
|
||||
mmid_fmt,e.amt.hl(),g.dcoin)
|
||||
mmid_fmt,
|
||||
e.amt.hl(),
|
||||
g.dcoin )
|
||||
else:
|
||||
icommon = [
|
||||
((n+1,'')[ip],'address:',e.addr.fmt(color=True,width=addr_w) + ' '+mmid_fmt),
|
||||
('','comment:',e.label.hl() if e.label else ''),
|
||||
('','amount:','{} {}'.format(e.amt.hl(),g.dcoin))]
|
||||
items = [(n+1, 'tx,vout:','{},{}'.format(e.txid,e.vout))] + icommon + [
|
||||
('','confirmations:','{} (around {} days)'.format(confs,days) if blockcount else '')
|
||||
] if ip else icommon + [
|
||||
('','change:',green('True') if e.is_chg else '')]
|
||||
out += '\n'.join([('{:>3} {:<8} {}'.format(*d)) for d in items if d[2]]) + '\n\n'
|
||||
return out
|
||||
def gen():
|
||||
if is_input:
|
||||
yield (n+1, 'tx,vout:', e.txid + ',' + str(e.vout))
|
||||
yield ('', 'address:', e.addr.fmt(color=True,width=addr_w) + ' ' + mmid_fmt)
|
||||
else:
|
||||
yield (n+1, 'address:', e.addr.fmt(color=True,width=addr_w) + ' ' + mmid_fmt)
|
||||
if e.label:
|
||||
yield ('', 'comment:', e.label.hl())
|
||||
yield ('', 'amount:', e.amt.hl() + ' ' + g.dcoin)
|
||||
if is_input and blockcount:
|
||||
yield ('', 'confirmations:', f'{confs} (around {days} days)')
|
||||
if not is_input and e.is_chg:
|
||||
yield ('', 'change:', green('True'))
|
||||
yield '\n'.join('{:>3} {:<8} {}'.format(*d) for d in gen()) + '\n\n'
|
||||
|
||||
md = {'raw':'raw','addr':'address'}
|
||||
m = 'Displaying inputs and outputs in {} sort order'.format(md[sort])
|
||||
|
||||
return m + ('\n\n','\n')[terse] + format_io('inputs') + format_io('outputs')
|
||||
return (
|
||||
'Displaying inputs and outputs in {} sort order'.format({'raw':'raw','addr':'address'}[sort])
|
||||
+ ('\n\n','\n')[terse]
|
||||
+ ''.join(format_io('inputs'))
|
||||
+ ''.join(format_io('outputs')) )
|
||||
|
||||
def format_view_rel_fee(self,terse):
|
||||
return ' ({} {})\n'.format(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue