From dc5a3f343577703bb4f0e957b8aaebda4338c150 Mon Sep 17 00:00:00 2001 From: MMGen Date: Mon, 14 Oct 2019 14:45:03 +0000 Subject: [PATCH] test/unit_tests.py seedsplit: add last share collisions test --- mmgen/seed.py | 25 ++++++++++++++++++++----- test/unit_tests_d/ut_seedsplit.py | 20 +++++++++++++++++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/mmgen/seed.py b/mmgen/seed.py index a40f7336..141bb9aa 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -151,13 +151,19 @@ class SubSeedList(MMGenObject): do_msg(subseed) return subseed - def _collision_debug_msg(self,sid,idx,nonce,nonce_desc='nonce'): + def _collision_debug_msg(self,sid,idx,nonce,nonce_desc='nonce',debug_last_share=False): slen = 'short' if sid in self.data['short'] else 'long' m1 = 'add_subseed(idx={},{}):'.format(idx,slen) if sid == self.parent_seed.sid: m2 = 'collision with parent Seed ID {},'.format(sid) else: - m2 = 'collision with ID {} (idx={},{}),'.format(sid,self.data[slen][sid][0],slen) + if debug_last_share: + sl = g.debug_last_share_sid_len + colliding_idx = [d[:sl] for d in self.data[slen].keys].index(sid[:sl]) + 1 + sid = sid[:sl] + else: + colliding_idx = self.data[slen][sid][0] + m2 = 'collision with ID {} (idx={},{}),'.format(sid,colliding_idx,slen) msg('{:30} {:46} incrementing {} to {}'.format(m1,m2,nonce_desc,nonce+1)) def _generate(self,last_idx=None,last_sid=None): @@ -282,7 +288,7 @@ class SeedShareList(SubSeedList): count = MMGenImmutableAttr('count',SeedShareCount) id_str = MMGenImmutableAttr('id_str',SeedSplitIDString) - def __init__(self,parent_seed,count,id_str=None,master_idx=None): + def __init__(self,parent_seed,count,id_str=None,master_idx=None,debug_last_share=False): self.member_type = SeedShare self.parent_seed = parent_seed self.id_str = id_str or 'default' @@ -299,6 +305,15 @@ class SeedShareList(SubSeedList): return ms raise SubSeedNonceRangeExceeded('nonce range exceeded') + def last_share_debug(last_share): + if not debug_last_share: + return False + sid_len = g.debug_last_share_sid_len + lsid = last_share.sid[:sid_len] + psid = parent_seed.sid[:sid_len] + ssids = [d[:sid_len] for d in self.data['long'].keys] + return (lsid in ssids or lsid == psid) + self.master_share = make_master_share() if master_idx else None for nonce in range(SeedShare.max_nonce+1): @@ -308,10 +323,10 @@ class SeedShareList(SubSeedList): self.data['long'][self.master_share.sid] = (1,self.master_share.nonce) self._generate(count-1) self.last_share = ls = SeedShareLast(self) - if ls.sid in self.data['long'] or ls.sid == parent_seed.sid: + if last_share_debug(ls) or ls.sid in self.data['long'] or ls.sid == parent_seed.sid: # collision: throw out entire split list and redo with new start nonce if g.debug_subseed: - self._collision_debug_msg(ls.sid,count,nonce,nonce_desc='nonce_start') + self._collision_debug_msg(ls.sid,count,nonce,'nonce_start',debug_last_share) else: self.data['long'][ls.sid] = (count,nonce) break diff --git a/test/unit_tests_d/ut_seedsplit.py b/test/unit_tests_d/ut_seedsplit.py index 64496b0d..5e20f154 100755 --- a/test/unit_tests_d/ut_seedsplit.py +++ b/test/unit_tests_d/ut_seedsplit.py @@ -8,7 +8,7 @@ from mmgen.common import * class unit_test(object): def run_test(self,name): - from mmgen.seed import Seed + from mmgen.seed import Seed,SeedShareList from mmgen.obj import SeedShareIdx def basic_ops(master_idx): @@ -140,10 +140,28 @@ class unit_test(object): vmsg_r('\n{} collisions, last_sid {}'.format(collisions,last_sid)) msg('OK') + def last_share_collisions(): + msg_r('Testing last share collisions with shortened Seed IDs') + vmsg('') + seed_bin = bytes.fromhex('2eadbeef'*8) + seed = Seed(seed_bin) + ssm_save = SeedShareIdx.max_val + ssm = SeedShareIdx.max_val = 2048 + g.debug_last_share_sid_len = 3 + shares = SeedShareList(seed,count=ssm,id_str='foo',master_idx=1,debug_last_share=True) + lsid = shares.last_share.sid + collisions = shares.data['long'][lsid][1] + assert collisions == 2, collisions + assert lsid == 'B5B8AD09', lsid + SeedShareIdx.max_val = ssm_save + vmsg_r('{} collisions, last_share sid {}'.format(collisions,lsid)) + msg('..OK') + basic_ops(master_idx=None) basic_ops(master_idx=1) basic_ops(master_idx=5) defaults_and_limits() + last_share_collisions() collisions('1dabcdef'*4,65535,'B5CBCE0A',3,master_idx=None) collisions('18abcdef'*4,65535,'FF03CE82',3,master_idx=1)