Example #1
0
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
Example #2
0
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
Example #3
0
 def pubkey_to_script_code(cls, pubkey_locktime):
     pubkey, locktime = pubkey_locktime
     return btc.mk_freeze_script(pubkey, locktime)
    def create_fidelity_bond_table(self, btc_unit):
        if jm_single().bc_interface == None:
            with self.taker.dblock:
                fbonds = self.taker.db.execute(
                    "SELECT * FROM fidelitybonds;").fetchall()
            fidelity_bond_data = []
            for fb in fbonds:
                try:
                    proof = FidelityBondProof.parse_and_verify_proof_msg(
                        fb["counterparty"], fb["takernick"], fb["proof"])
                except ValueError:
                    proof = None
                fidelity_bond_data.append((proof, None))
            fidelity_bond_values = [-1] * len(
                fidelity_bond_data)  #-1 means no data
            bond_outpoint_conf_times = [-1] * len(fidelity_bond_data)
            total_btc_committed_str = "unknown"
        else:
            (fidelity_bond_data, fidelity_bond_values, bond_outpoint_conf_times) =\
                get_fidelity_bond_data(self.taker)
            total_btc_committed_str = satoshi_to_unit(
                sum([
                    utxo_data["value"] for _, utxo_data in fidelity_bond_data
                ]), None, btc_unit, 0)

        RETARGET_INTERVAL = 2016
        elem = lambda e: "<td>" + e + "</td>"
        bondtable = ""
        for (bond_data, utxo_data), bond_value, conf_time in zip(
                fidelity_bond_data, fidelity_bond_values,
                bond_outpoint_conf_times):

            if bond_value == -1 or conf_time == -1 or utxo_data == None:
                bond_value_str = "No data"
                conf_time_str = "No data"
                utxo_value_str = "No data"
            else:
                bond_value_str = satoshi_to_unit_power(
                    bond_value, 2 * unit_to_power[btc_unit])
                conf_time_str = str(
                    datetime.utcfromtimestamp(0) +
                    timedelta(seconds=conf_time))
                utxo_value_str = satoshi_to_unit(utxo_data["value"], None,
                                                 btc_unit, 0)
            bondtable += (
                "<tr>" + elem(bond_data.maker_nick) + elem(
                    bintohex(bond_data.utxo[0]) + ":" + str(bond_data.utxo[1]))
                + elem(bond_value_str) + elem(
                    (datetime.utcfromtimestamp(0) + timedelta(
                        seconds=bond_data.locktime)).strftime("%Y-%m-%d")) +
                elem(utxo_value_str) + elem(conf_time_str) +
                elem(str(bond_data.cert_expiry * RETARGET_INTERVAL)) + elem(
                    bintohex(
                        btc.mk_freeze_script(bond_data.utxo_pub,
                                             bond_data.locktime))) + "</tr>")

        heading2 = (str(len(fidelity_bond_data)) +
                    " fidelity bonds found with " + total_btc_committed_str +
                    " " + btc_unit + " total locked up")
        choose_units_form = (
            '<form method="get" action="">' +
            '<select name="btcunit" onchange="this.form.submit();">' + ''.join(
                ('<option>' + u + ' </option>'
                 for u in sorted_units)) + '</select></form>')
        choose_units_form = choose_units_form.replace(
            '<option>' + btc_unit, '<option selected="selected">' + btc_unit)

        decodescript_tip = (
            "<br/>Tip: try running the RPC <code>decodescript " +
            "&lt;redeemscript&gt;</code> as proof that the fidelity bond address matches the "
            +
            "locktime.<br/>Also run <code>gettxout &lt;utxo_txid&gt; &lt;utxo_vout&gt;</code> "
            + "as proof that the fidelity bond UTXO is real.")

        return (heading2,
                choose_units_form + create_bonds_table_heading(btc_unit) +
                bondtable + "</table>" + decodescript_tip)
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()