def test_make_commitment(createcmtdata, failquery, external): def clean_up(): jm_single().config.set("POLICY", "taker_utxo_age", old_taker_utxo_age) jm_single().config.set("POLICY", "taker_utxo_amtpercent", old_taker_utxo_amtpercent) set_commitment_file(old_commitment_file) jm_single().bc_interface.setQUSFail(False) os.remove('dummyext') old_commitment_file = get_commitment_file() with open('dummyext', 'wb') as f: f.write(json.dumps(t_dummy_ext, indent=4).encode('utf-8')) if external: set_commitment_file('dummyext') old_taker_utxo_age = jm_single().config.get("POLICY", "taker_utxo_age") old_taker_utxo_amtpercent = jm_single().config.get( "POLICY", "taker_utxo_amtpercent") jm_single().config.set("POLICY", "taker_utxo_age", "5") jm_single().config.set("POLICY", "taker_utxo_amtpercent", "20") mixdepth = 0 amount = 110000000 taker = get_taker([(mixdepth, amount, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]) taker.cjamount = amount taker.input_utxos = t_utxos_by_mixdepth[0] if failquery: jm_single().bc_interface.setQUSFail(True) taker.make_commitment() clean_up()
def test_make_commitment(createcmtdata, failquery, external): def clean_up(): jm_single().config.set("POLICY", "taker_utxo_age", old_taker_utxo_age) jm_single().config.set("POLICY", "taker_utxo_amtpercent", old_taker_utxo_amtpercent) set_commitment_file(old_commitment_file) jm_single().bc_interface.setQUSFail(False) os.remove('dummyext') old_commitment_file = get_commitment_file() with open('dummyext', 'wb') as f: f.write(json.dumps(t_dummy_ext, indent=4)) if external: set_commitment_file('dummyext') old_taker_utxo_age = jm_single().config.get("POLICY", "taker_utxo_age") old_taker_utxo_amtpercent = jm_single().config.get( "POLICY", "taker_utxo_amtpercent") jm_single().config.set("POLICY", "taker_utxo_age", "5") jm_single().config.set("POLICY", "taker_utxo_amtpercent", "20") mixdepth = 0 amount = 110000000 taker = get_taker([(mixdepth, amount, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]) taker.wallet.unspent = { 'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': { 'address': u'n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D', 'value': 10000000 }, 'f780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1': { 'address': u'mmVEKH61BZbLbnVEmk9VmojreB4G4PmBPd', 'value': 20000000 }, 'fe574db96a4d43a99786b3ea653cda9e4388f377848f489332577e018380cff1:0': { 'address': u'msxyyydNXTiBmt3SushXbH5Qh2ukBAThk3', 'value': 500000000 }, 'fd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': { 'address': u'musGZczug3BAbqobmYherywCwL9REgNaNm', 'value': 500000000 } } taker.cjamount = amount taker.input_utxos = { 'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': { 'address': u'n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D', 'value': 10000000 } } if failquery: jm_single().bc_interface.setQUSFail(True) taker.make_commitment() clean_up()
def setup_podle(request): load_test_config() if not os.path.exists("cmtdata"): os.mkdir("cmtdata") prev_commits = False #back up any existing commitments pcf = get_commitment_file() log.debug("Podle file: " + pcf) if os.path.exists(pcf): os.rename(pcf, pcf + ".bak") prev_commits = True def teardown(): if prev_commits: os.rename(pcf + ".bak", pcf) else: if os.path.exists(pcf): os.remove(pcf) request.addfinalizer(teardown)
def test_external_commitments(setup_podle): """Add this generated commitment to the external list {txid:N:{'P':pubkey, 'reveal':{1:{'P2':P2,'s':s,'e':e}, 2:{..},..}}} Note we do this *after* the sendpayment test so that the external commitments will not erroneously used (they are fake). """ #ensure the file exists even if empty update_commitments() ecs = {} tries = jm_single().config.getint("POLICY","taker_utxo_retries") for i in range(10): priv = os.urandom(32) dummy_utxo = (bitcoin.Hash(priv), 2) ecs[dummy_utxo] = {} ecs[dummy_utxo]['reveal']={} for j in range(tries): P, P2, s, e, commit = generate_single_podle_sig(priv, j) if 'P' not in ecs[dummy_utxo]: ecs[dummy_utxo]['P']=P ecs[dummy_utxo]['reveal'][j] = {'P2':P2, 's':s, 'e':e} add_external_commitments(ecs) used, external = get_podle_commitments() for u in external: assert external[u]['P'] == ecs[u]['P'] for i in range(tries): for x in ['P2', 's', 'e']: assert external[u]['reveal'][i][x] == ecs[u]['reveal'][i][x] #add a dummy used commitment, then try again update_commitments(commitment=b"\xab"*32) ecs = {} known_commits = [] known_utxos = [] tries = 3 for i in range(1, 6): u = (struct.pack(b'B', i)*32, i+3) known_utxos.append(u) priv = struct.pack(b'B', i)*32+b"\x01" ecs[u] = {} ecs[u]['reveal']={} for j in range(tries): P, P2, s, e, commit = generate_single_podle_sig(priv, j) known_commits.append(commit) if 'P' not in ecs[u]: ecs[u]['P'] = P ecs[u]['reveal'][j] = {'P2':P2, 's':s, 'e':e} add_external_commitments(ecs) #simulate most of those external being already used for c in known_commits[:-1]: update_commitments(commitment=c) #this should find the remaining one utxo and return from it assert generate_podle([], max_tries=tries, allow_external=known_utxos) #test commitment removal tru = (struct.pack(b"B", 3)*32, 3+3) to_remove = {tru: ecs[tru]} update_commitments(external_to_remove=to_remove) #test that an incorrectly formatted file raises with open(get_commitment_file(), "rb") as f: validjson = json.loads(f.read().decode('utf-8')) corruptjson = copy.deepcopy(validjson) del corruptjson['used'] with open(get_commitment_file(), "wb") as f: f.write(json.dumps(corruptjson, indent=4).encode('utf-8')) with pytest.raises(PoDLEError) as e_info: get_podle_commitments() #clean up with open(get_commitment_file(), "wb") as f: f.write(json.dumps(validjson, indent=4).encode('utf-8'))
def test_make_commitment(setup_taker, mixdepth, cjamt, failquery, external, expected_success, amtpercent, age, mixdepth_extras): def clean_up(): jm_single().config.set("POLICY", "taker_utxo_age", old_taker_utxo_age) jm_single().config.set("POLICY", "taker_utxo_amtpercent", old_taker_utxo_amtpercent) set_commitment_file(old_commitment_file) jm_single().bc_interface.setQUSFail(False) jm_single().bc_interface.reset_confs() os.remove('dummyext') old_commitment_file = get_commitment_file() with open('dummyext', 'wb') as f: f.write(json.dumps(t_dummy_ext, indent=4).encode('utf-8')) if external: set_commitment_file('dummyext') # define the appropriate podle acceptance parameters in the global config: old_taker_utxo_age = jm_single().config.get("POLICY", "taker_utxo_age") old_taker_utxo_amtpercent = jm_single().config.get( "POLICY", "taker_utxo_amtpercent") if expected_success: # set to defaults for mainnet newtua = "5" newtuap = "20" else: newtua = str(age) newtuap = str(amtpercent) jm_single().config.set("POLICY", "taker_utxo_age", newtua) jm_single().config.set("POLICY", "taker_utxo_amtpercent", newtuap) taker = get_taker([(mixdepth, cjamt, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw", NO_ROUNDING)]) # modify or add any extra utxos for this run: for k, v in mixdepth_extras.items(): if k == "confchange": for k2, v2 in v.items(): # set the utxos in mixdepth k2 to have confs v2: cdict = taker.wallet_service.get_utxos_by_mixdepth()[k2] jm_single().bc_interface.set_confs( {utxo: v2 for utxo in cdict.keys()}) elif k == "custom-script": # note: this is inspired by fidelity bonds, and currently # uses scripts of that specific timelock type, but is really # only testing the general concept: that commitments must # not be made on any non-standard script type. for k2, v2 in v.items(): priv = os.urandom(32) + b"\x01" tl = random.randrange(1430454400, 1430494400) script_inner = bitcoin.mk_freeze_script( bitcoin.privkey_to_pubkey(priv), tl) script_outer = bitcoin.redeem_script_to_p2wsh_script( script_inner) taker.wallet_service.wallet._script_map[script_outer] = ( "nonstandard_path", ) taker.wallet_service.add_extra_utxo(os.urandom(32), 0, v2, k2, script=script_outer) else: for value in v: taker.wallet_service.add_extra_utxo(os.urandom(32), 0, value, k) taker.cjamount = cjamt taker.input_utxos = taker.wallet_service.get_utxos_by_mixdepth()[mixdepth] taker.mixdepth = mixdepth if failquery: jm_single().bc_interface.setQUSFail(True) comm, revelation, msg = taker.make_commitment() if expected_success and failquery: # for manual tests, show the error message: print("Failure case due to QUS fail: ") print("Erromsg: ", msg) assert not comm elif expected_success: assert comm, "podle was not generated but should have been." else: # in these cases we have set the podle acceptance # parameters such that our in-mixdepth utxos are not good # enough. # for manual tests, show the errormsg: print("Failure case, errormsg: ", msg) assert not comm, "podle was generated but should not have been." clean_up()
def test_make_commitment(setup_taker, mixdepth, cjamt, failquery, external, expected_success, amtpercent, age, mixdepth_extras): def clean_up(): jm_single().config.set("POLICY", "taker_utxo_age", old_taker_utxo_age) jm_single().config.set("POLICY", "taker_utxo_amtpercent", old_taker_utxo_amtpercent) set_commitment_file(old_commitment_file) jm_single().bc_interface.setQUSFail(False) jm_single().bc_interface.reset_confs() os.remove('dummyext') old_commitment_file = get_commitment_file() with open('dummyext', 'wb') as f: f.write(json.dumps(t_dummy_ext, indent=4).encode('utf-8')) if external: set_commitment_file('dummyext') # define the appropriate podle acceptance parameters in the global config: old_taker_utxo_age = jm_single().config.get("POLICY", "taker_utxo_age") old_taker_utxo_amtpercent = jm_single().config.get( "POLICY", "taker_utxo_amtpercent") if expected_success: # set to defaults for mainnet newtua = "5" newtuap = "20" else: newtua = str(age) newtuap = str(amtpercent) jm_single().config.set("POLICY", "taker_utxo_age", newtua) jm_single().config.set("POLICY", "taker_utxo_amtpercent", newtuap) taker = get_taker([(mixdepth, cjamt, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw", NO_ROUNDING)]) # modify or add any extra utxos for this run: for k, v in mixdepth_extras.items(): if k == "confchange": for k2, v2 in v.items(): # set the utxos in mixdepth k2 to have confs v2: cdict = taker.wallet_service.get_utxos_by_mixdepth()[k2] jm_single().bc_interface.set_confs( {utxo: v2 for utxo in cdict.keys()}) else: for value in v: taker.wallet_service.add_extra_utxo(os.urandom(32), 0, value, k) taker.cjamount = cjamt taker.input_utxos = taker.wallet_service.get_utxos_by_mixdepth()[mixdepth] taker.mixdepth = mixdepth if failquery: jm_single().bc_interface.setQUSFail(True) comm, revelation, msg = taker.make_commitment() if expected_success and failquery: # for manual tests, show the error message: print("Failure case due to QUS fail: ") print("Erromsg: ", msg) assert not comm elif expected_success: assert comm, "podle was not generated but should have been." else: # in these cases we have set the podle acceptance # parameters such that our in-mixdepth utxos are not good # enough. # for manual tests, show the errormsg: print("Failure case, errormsg: ", msg) assert not comm, "podle was generated but should not have been." clean_up()