def test_spend_freeze_script(setup_tx_creation): ensure_bip65_activated() wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet'] wallet_service.sync_wallet(fast=True) mediantime = jm_single().bc_interface.rpc("getblockchaininfo", [])["mediantime"] timeoffset_success_tests = [(2, False), (-60 * 60 * 24 * 30, True), (60 * 60 * 24 * 30, False)] for timeoffset, required_success in timeoffset_success_tests: #generate keypair priv = b"\xaa" * 32 + b"\x01" pub = bitcoin.privkey_to_pubkey(priv) addr_locktime = mediantime + timeoffset redeem_script = bitcoin.mk_freeze_script(pub, addr_locktime) script_pub_key = bitcoin.redeem_script_to_p2wsh_script(redeem_script) # cannot convert to address within wallet service, as not known # to wallet; use engine directly: addr = wallet_service._ENGINE.script_to_address(script_pub_key) #fund frozen funds address amount = 100000000 funding_ins_full = wallet_service.select_utxos(0, amount) funding_txid = make_sign_and_push(funding_ins_full, wallet_service, amount, output_addr=addr) assert funding_txid #spend frozen funds frozen_in = (funding_txid, 0) output_addr = wallet_service.get_internal_addr(1) miner_fee = 5000 outs = [{'value': amount - miner_fee, 'address': output_addr}] tx = bitcoin.mktx([frozen_in], outs, locktime=addr_locktime + 1) i = 0 sig, success = bitcoin.sign(tx, i, priv, amount=amount, native=redeem_script) assert success push_success = jm_single().bc_interface.pushtx(tx.serialize()) assert push_success == required_success
def test_spend_freeze_script(setup_tx_creation): ensure_bip65_activated() wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet'] wallet_service.sync_wallet(fast=True) mediantime = jm_single().bc_interface.rpc("getblockchaininfo", [])["mediantime"] timeoffset_success_tests = [(2, False), (-60*60*24*30, True), (60*60*24*30, False)] for timeoffset, required_success in timeoffset_success_tests: #generate keypair priv = "aa"*32 + "01" pub = unhexlify(bitcoin.privkey_to_pubkey(priv)) addr_locktime = mediantime + timeoffset redeem_script = bitcoin.mk_freeze_script(pub, addr_locktime) script_pub_key = bitcoin.redeem_script_to_p2wsh_script(redeem_script) regtest_vbyte = 100 addr = bitcoin.script_to_address(script_pub_key, vbyte=regtest_vbyte) #fund frozen funds address amount = 100000000 funding_ins_full = wallet_service.select_utxos(0, amount) funding_txid = make_sign_and_push(funding_ins_full, wallet_service, amount, output_addr=addr) assert funding_txid #spend frozen funds frozen_in = funding_txid + ":0" output_addr = wallet_service.get_internal_addr(1) miner_fee = 5000 outs = [{'value': amount - miner_fee, 'address': output_addr}] tx = bitcoin.mktx([frozen_in], outs, locktime=addr_locktime+1) i = 0 sig = bitcoin.get_p2sh_signature(tx, i, redeem_script, priv, amount) assert bitcoin.verify_tx_input(tx, i, script_pub_key, sig, pub, scriptCode=redeem_script, amount=amount) tx = bitcoin.apply_freeze_signature(tx, i, redeem_script, sig) push_success = jm_single().bc_interface.pushtx(tx) assert push_success == required_success
def pubkey_to_script(cls, pubkey_locktime): redeem_script = cls.pubkey_to_script_code(pubkey_locktime) return btc.redeem_script_to_p2wsh_script(redeem_script)
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()