mmgen-tool tw{export,import}: support editing of comments fields

This commit is contained in:
The MMGen Project 2022-07-23 11:49:32 +00:00
commit 30b94db2f8
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
7 changed files with 86 additions and 18 deletions

View file

@ -87,13 +87,15 @@ class EthereumTwJSON(TwJSON):
async def do_import(self,batch):
from ....obj import TwComment
def gen_data(data):
for d in data:
if hasattr(d,'address'):
if d.amount is None: # Python 3.9: {} | {}
yield (d.address, {'mmid':d.mmgen_id,'comment':d.comment})
yield (d.address, {'mmid':d.mmgen_id,'comment':TwComment(d.comment)})
else:
yield (d.address, {'mmid':d.mmgen_id,'comment':d.comment,'balance':d.amount})
yield (d.address, {'mmid':d.mmgen_id,'comment':TwComment(d.comment),'balance':d.amount})
else:
yield ('params', {'symbol':d.symbol,'decimals':d.decimals})

View file

@ -1 +1 @@
June 2022
July 2022

View file

@ -1 +1 @@
13.2.dev8
13.2.dev9

View file

@ -200,25 +200,31 @@ class tool_cmd(tool_cmd_base):
ret = await (await TrackingWallet(self.proto,mode='w')).rescan_blockchain(start_block,stop_block)
return True
async def twexport(self,include_amts=True):
async def twexport(self,include_amts=True,pretty=False):
"""
export a tracking wallet to JSON format
NOTE:
NOTES:
If include_amts is true (the default), Ethereum balances will be restored
from the dump upon import. For Bitcoin and forks, amount fields in the dump
are ignored.
If pretty is true, JSON will be dumped in human-readable format to allow
for editing of comment fields.
"""
from ..tw.json import TwJSON
await TwJSON.Export( self.proto, include_amts=include_amts )
await TwJSON.Export( self.proto, include_amts=include_amts, pretty=pretty )
return True
async def twimport(self,filename:str,ignore_checksum=False,batch=False):
"""
restore a tracking wallet from a JSON dump created by twexport
NOTE:
NOTES:
If comment fields in the JSON dump have been edited, ignore_checksum must
be set to true.
The restored tracking wallet will have correct balances but no record of
historical transactions. These may be restored by running mmgen-tool

View file

@ -50,8 +50,13 @@ class TwJSON:
def dump_fn(self):
return f'{self.fn_pfx}-{self.coin}-{self.network}.json'
def json_dump(self,data):
return json.dumps( data, cls=json_encoder, separators=(',', ':'), sort_keys=True )
def json_dump(self,data,pretty=False):
return json.dumps(
data,
cls = json_encoder,
sort_keys = True,
separators = None if pretty else (',', ':'),
indent = 4 if pretty else None )
def make_chksum(self,data):
return make_chksum_8( self.json_dump(data).encode() ).lower()
@ -128,7 +133,7 @@ class TwJSON:
class Export(Base,metaclass=AsyncInit):
async def __init__(self,proto,include_amts=True):
async def __init__(self,proto,include_amts=True,pretty=False):
super().__init__(proto)
@ -156,7 +161,10 @@ class TwJSON:
from ..fileutil import write_data_to_file
write_data_to_file(
outfile = self.dump_fn,
data = self.json_dump({
'checksum': self.make_chksum(data),
'data': data }),
data = self.json_dump(
{
'checksum': self.make_chksum(data),
'data': data
},
pretty = pretty ),
desc = f'tracking wallet JSON data' )

View file

@ -317,6 +317,12 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
('twmove', 'moving the tracking wallet'),
('twimport', 'importing the tracking wallet'),
('twcompare', 'comparing imported tracking wallet with original'),
('edit_json_twdump', 'editing the tracking wallet JSON dump'),
('twmove', 'moving the tracking wallet'),
('twimport_nochksum', 'importing the edited tracking wallet JSON dump (ignore_checksum=1)'),
('token_listaddresses3','listaddresses --token=mm1 showempty=1'),
('token_listaddresses4','listaddresses --token=mm2 showempty=1'),
('twview9', 'twview (check balance)'),
('stop', 'stopping daemon'),
@ -1143,6 +1149,10 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
return self.listaddresses(args=['--token=mm1'])
def token_listaddresses2(self):
return self.listaddresses(args=['--token=mm1'],tool_args=['showempty=1'])
def token_listaddresses3(self):
return self.listaddresses(args=['--token=mm1'],tool_args=['showempty=1'])
def token_listaddresses4(self):
return self.listaddresses(args=['--token=mm2'],tool_args=['showempty=1'])
def twview_cached_balances(self):
return self.twview(args=['--cached-balances'])
@ -1279,14 +1289,19 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
os.rename( tw.tw_fn, tw.tw_fn+'.bak.json' )
return 'ok'
def twimport(self,add_args=[]):
def twimport(self,add_args=[],expect_str=None):
from mmgen.tw.json import TwJSON
fn = joinpath( self.tmpdir, TwJSON.Base(self.proto).dump_fn )
t = self.spawn('mmgen-tool',self.eth_args + ['twimport',fn] + add_args)
t = self.spawn('mmgen-tool',self.eth_args_noquiet + ['twimport',fn] + add_args)
t.expect('(y/N): ','y')
if expect_str:
t.expect(expect_str)
t.written_to_file('tracking wallet data')
return t
def twimport_nochksum(self):
return self.twimport(add_args=['ignore_checksum=true'],expect_str='ignoring incorrect checksum')
def tw_chktotal(self):
self.spawn('',msg_only=True)
from mmgen.tw.json import TwJSON
@ -1305,6 +1320,16 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
cmp_or_die(*data,'tracking wallets')
return 'ok'
def edit_json_twdump(self):
self.spawn('',msg_only=True)
from mmgen.tw.json import TwJSON
fn = TwJSON.Base(self.proto).dump_fn
text = json.loads(self.read_from_tmpfile(fn))
token_addr = self.read_from_tmpfile('token_addr2').strip()
text['data']['entries']['tokens'][token_addr][2][3] = f'edited comment [фубар] [{gr_uc}]'
self.write_to_tmpfile( fn, json.dumps(text,indent=4) )
return 'ok'
def stop(self):
self.spawn('',msg_only=True)
if not opt.no_daemon_stop:

View file

@ -209,6 +209,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
('bob_rescan_blockchain_gb', 'rescanning the blockchain (Genesis block)'),
('bob_rescan_blockchain_one','rescanning the blockchain (single block)'),
('bob_rescan_blockchain_ss', 'rescanning the blockchain (range of blocks)'),
('bob_twexport', 'exporting a tracking wallet to JSON'),
('carol_twimport', 'importing a tracking wallet JSON dump'),
('carol_delete_wallet', 'unloading and deleting Carol’s tracking wallet'),
@ -216,6 +217,12 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
('carol_twimport_nochksum', 'importing a tracking wallet JSON dump (ignore_checksum=1)'),
('carol_delete_wallet', 'unloading and deleting Carol’s tracking wallet'),
('carol_twimport_batch', 'importing a tracking wallet JSON dump (batch=1)'),
('bob_twexport_pretty', 'exporting a tracking wallet to JSON (pretty=1)'),
('bob_edit_json_twdump', 'editing a tracking wallet JSON dump'),
('carol_delete_wallet', 'unloading and deleting Carol’s tracking wallet'),
('carol_twimport_pretty', 'importing an edited tracking wallet JSON dump (ignore_checksum=1)'),
('carol_listaddresses', 'viewing Carol’s tracking wallet'),
('bob_split2', "splitting Bob's funds"),
('bob_0conf0_getbalance', "Bob's balance (unconfirmed, minconf=0)"),
('bob_0conf1_getbalance', "Bob's balance (unconfirmed, minconf=1)"),
@ -986,12 +993,26 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
def bob_twexport_noamt(self):
return self.bob_twexport(add_args=['include_amts=0'])
def carol_twimport(self,add_args=[]):
def bob_twexport_pretty(self):
return self.bob_twexport(add_args=['pretty=1'])
def bob_edit_json_twdump(self):
self.spawn('',msg_only=True)
from mmgen.tw.json import TwJSON
fn = TwJSON.Base(self.proto).dump_fn
text = json.loads(self.read_from_tmpfile(fn))
text['data']['entries'][3][3] = f'edited comment [фубар] [{gr_uc}]'
self.write_to_tmpfile( fn, json.dumps(text,indent=4) )
return 'ok'
def carol_twimport(self,add_args=[],expect_str=None):
from mmgen.tw.json import TwJSON
fn = joinpath( self.tmpdir, TwJSON.Base(self.proto).dump_fn )
t = self.spawn('mmgen-tool',['--carol','twimport',fn] + add_args)
t.expect('(y/N): ','y')
if 'batch=true' in add_args:
if expect_str:
t.expect(expect_str)
elif 'batch=true' in add_args:
t.expect('{} addresses imported'.format(15 if self.proto.coin == 'BCH' else 25))
else:
t.expect('import completed OK')
@ -1004,6 +1025,12 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
def carol_twimport_batch(self):
return self.carol_twimport(add_args=['batch=true'])
def carol_twimport_pretty(self):
return self.carol_twimport(add_args=['ignore_checksum=true'],expect_str='ignoring incorrect checksum')
def carol_listaddresses(self):
return self.spawn('mmgen-tool',['--carol','listaddresses','showempty=1'])
async def carol_delete_wallet(self):
imsg(f'Unloading Carol’s tracking wallet')
t = self.spawn('mmgen-regtest',['cli','unloadwallet','carol'])