From dee57d88869a8c9c6c22bbf01bc07de35de7545e Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Fri, 18 Oct 2024 10:33:47 +0000 Subject: [PATCH] update for MMGen Wallet CoinAmt changes --- mmgen_node_tools/BlocksInfo.py | 27 +++++++++++++++++++-------- mmgen_node_tools/main_addrbal.py | 4 ++-- test/cmdtest_py_d/ct_regtest.py | 9 +++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/mmgen_node_tools/BlocksInfo.py b/mmgen_node_tools/BlocksInfo.py index 40cc6e5..26e6cfa 100755 --- a/mmgen_node_tools/BlocksInfo.py +++ b/mmgen_node_tools/BlocksInfo.py @@ -23,6 +23,7 @@ mmgen_node_tools.BlocksInfo: Display information about a block or range of block import re,json from collections import namedtuple from time import strftime,gmtime +from decimal import Decimal from mmgen.util import msg,Msg,Msg_r,die,suf,secs_to_ms,secs_to_dhms,is_int from mmgen.rpc import json_encoder @@ -241,14 +242,14 @@ class BlocksInfo: 'tf': lambda arg: '{:.8f}'.format(arg * from_satoshi), 'su': lambda arg: str(arg * from_satoshi).rstrip('0').rstrip('.'), 'fe': lambda arg: str(arg), - 'di': lambda arg: '{:.2e}'.format(arg), + 'di': lambda arg: '{:.2e}'.format(Decimal(arg)), } if self.cfg.coin == 'BCH': self.fmt_funcs.update({ 'su': lambda arg: str(arg).rstrip('0').rstrip('.'), - 'fe': lambda arg: str(int(arg * to_satoshi)), - 'tf': lambda arg: '{:.8f}'.format(arg), + 'fe': lambda arg: str(int(Decimal(arg) * to_satoshi)), + 'tf': lambda arg: '{:.8f}'.format(Decimal(arg)), }) self.fnames = tuple( @@ -547,7 +548,7 @@ class BlocksInfo: else: sample_blks = min(min_sample_blks,self.tip) start_hdr = await c.call('getblockheader',await c.call('getblockhash',self.tip-sample_blks)) - diff_adj = float(tip_hdr['difficulty'] / start_hdr['difficulty']) + diff_adj = Decimal(tip_hdr['difficulty']) / Decimal(start_hdr['difficulty']) time1 = rel_hdr['time'] - start_hdr['time'] time2 = tip_hdr['time'] - rel_hdr['time'] bdi = ((time1 * diff_adj) + time2) / sample_blks @@ -570,17 +571,26 @@ class BlocksInfo: 'sample_blks': ('{}', sample_blks) } ), - ('Cur difficulty: {}', 'cur_diff', '{:.2e}', tip_hdr['difficulty']), + ('Cur difficulty: {}', 'cur_diff', '{:.2e}', Decimal(tip_hdr['difficulty'])), ('Est. diff adjust: {}%', 'est_diff_adjust_pct', '{:+.2f}', ((600 / bdi) - 1) * 100), )) + def sum_field_avg(self, field): + return self.sum_field_total(field) // len(self.res) + + def sum_field_total(self, field): + if isinstance(getattr(self.res[0], field), str): + return sum(Decimal(getattr(block, field)) for block in self.res) + else: + return sum(getattr(block, field) for block in self.res) + async def create_col_avg_stats(self): def gen(): for field in self.fnames: if field in self.avg_stats_skip: yield ( field, ('{}','') ) else: - ret = sum(getattr(block,field) for block in self.res) // len(self.res) + ret = self.sum_field_avg(field) func = self.fields[field].fmt_func yield ( field, ( (self.fmt_funcs[func] if func else '{}'), ret )) if not self.header_printed: @@ -590,9 +600,10 @@ class BlocksInfo: def avg_stats_data(self,data,spec_conv,spec_val): coin = self.rpc.proto.coin + return data( hdr = 'Averages for processed blocks:', - func = lambda field: sum(getattr(block,field) for block in self.res) // len(self.res), + func = self.sum_field_avg, spec_sufs = { 'subsidy': f' {coin}', 'totalfee': f' {coin}' }, spec_convs = { 'interval': spec_conv(0, lambda arg: secs_to_ms(arg)), @@ -616,7 +627,7 @@ class BlocksInfo: coin = self.rpc.proto.coin return data( hdr = 'Totals for processed blocks:', - func = lambda field: sum(getattr(block,field) for block in self.res), + func = self.sum_field_total, spec_sufs = { 'subsidy': f' {coin}', 'totalfee': f' {coin}', 'reward': f' {coin}' }, spec_convs = { 'interval': spec_conv(0, lambda arg: secs_to_dhms(arg)), diff --git a/mmgen_node_tools/main_addrbal.py b/mmgen_node_tools/main_addrbal.py index e78a53e..7dd37a3 100755 --- a/mmgen_node_tools/main_addrbal.py +++ b/mmgen_node_tools/main_addrbal.py @@ -44,7 +44,7 @@ def do_output(proto,addr_data,blk_hdrs): heights = { u['height'] for u in unspents } Msg('{}Balance: {}'.format( indent, - proto.coin_amt(sum(u['amount'] for u in unspents)).hl2(unit=True,fs='{:,}') )), + sum(proto.coin_amt(u['amount']) for u in unspents).hl2(unit=True, fs='{:,}'))), Msg('{}{} unspent output{} in {} block{}'.format( indent, red(str(len(unspents))), @@ -99,7 +99,7 @@ def do_output_tabular(proto,addr_data,blk_hdrs): t = make_timestr( blk_hdrs[unspents[0]['height']]['time'] ), B = unspents[-1]['height'], T = make_timestr( blk_hdrs[unspents[-1]['height']]['time'] ), - A = proto.coin_amt(sum(u['amount'] for u in unspents)).fmt(color=True,iwidth=7,prec=8) + A = sum(proto.coin_amt(u['amount']) for u in unspents).fmt(color=True, iwidth=7, prec=8) )) else: Msg(fs.format( diff --git a/test/cmdtest_py_d/ct_regtest.py b/test/cmdtest_py_d/ct_regtest.py index 0807a16..f1b2774 100755 --- a/test/cmdtest_py_d/ct_regtest.py +++ b/test/cmdtest_py_d/ct_regtest.py @@ -13,6 +13,7 @@ test.cmdtest_py_d.ct_regtest: Regtest tests for the cmdtest.py test suite """ import sys,os +from decimal import Decimal from mmgen.util import msg_r,die,gmsg from mmgen.protocol import init_proto @@ -316,13 +317,13 @@ class CmdTestRegtest(CmdTestBase): # very approximate tx size estimation: ibytes,wbytes,obytes = (148,0,34) if self.proto.coin == 'BCH' else (43,108,31) - x = (ibytes + (wbytes//4) + (obytes * nPairs)) * self.proto.coin_amt(self.proto.coin_amt.satoshi) + x = (ibytes + (wbytes//4) + (obytes * nPairs)) * self.proto.coin_amt.satoshi n = n_in - 1 vmax = high - low for i in range(n_in): - yield (low + (i/n)**6 * vmax) * x + yield Decimal(low + (i/n)**6 * vmax) * x async def do_tx(inputs,outputs,wif): tx_hex = await r.rpc_call( 'createrawtransaction', inputs, outputs ) @@ -335,14 +336,14 @@ class CmdTestRegtest(CmdTestBase): tx_input = us[7] # 25 BTC in coinbase -- us[0] could have < 25 BTC fee = self.proto.coin_amt('0.001') outputs = {p.addr:tx1_amt for p in pairs[:nTxs]} - outputs.update({burn_addr: tx_input['amount'] - (tx1_amt*nTxs) - fee}) + outputs.update({burn_addr: self.proto.coin_amt(tx_input['amount']) - (tx1_amt*nTxs) - fee}) return await do_tx( [{ 'txid': tx_input['txid'], 'vout': 0 }], outputs, await r.miner_wif) async def do_tx2(tx,pairno): - fee = fees[pairno] + fee = self.proto.coin_amt(fees[pairno], from_decimal=True) outputs = {p.addr:tx2_amt for p in pairs} outputs.update({burn_addr: tx1_amt - (tx2_amt*len(pairs)) - fee}) return await do_tx(