示例#1
0
    def test_prioritised_transactions(self):
        # Ensure that fee deltas used via prioritisetransaction are
        # correctly used by replacement logic

        # 1. Check that feeperkb uses modified fees
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))

        tx1a = CTransaction()
        tx1a.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
        tx1a_hex = tx_to_hex(tx1a)
        tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)

        # Higher fee, but the actual fee per KB is much lower.
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))]
        tx1b_hex = tx_to_hex(tx1b)

        # Verify tx1b cannot replace tx1a.
        assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)

        # Use prioritisetransaction to set tx1a's fee to 0.
        self.nodes[0].prioritisetransaction(txid=tx1a_txid, fee_delta=int(-0.1*COIN))

        # Now tx1b should be able to replace tx1a
        tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)

        assert(tx1b_txid in self.nodes[0].getrawmempool())

        # 2. Check that absolute fee checks use modified fee.
        tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))

        tx2a = CTransaction()
        tx2a.vin = [CTxIn(tx1_outpoint, n_sequence=0)]
        tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))]
        tx2a_hex = tx_to_hex(tx2a)
        self.nodes[0].sendrawtransaction(tx2a_hex, True)

        # Lower fee, but we'll prioritise it
        tx2b = CTransaction()
        tx2b.vin = [CTxIn(tx1_outpoint, n_sequence=0)]
        tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))]
        tx2b.rehash()
        tx2b_hex = tx_to_hex(tx2b)

        # Verify tx2b cannot replace tx2a.
        assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx2b_hex, True)

        # Now prioritise tx2b to have a higher modified fee
        self.nodes[0].prioritisetransaction(txid=tx2b.hash, fee_delta=int(0.1*COIN))

        # tx2b should now be accepted
        tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)

        assert(tx2b_txid in self.nodes[0].getrawmempool())
示例#2
0
    def test_too_many_replacements(self):
        """Replacements that evict too many transactions are rejected"""
        # Try directly replacing more than MAX_REPLACEMENT_LIMIT
        # transactions

        # Start by creating a single transaction with many outputs
        initial_n_value = 10 * COIN
        utxo = make_utxo(self.nodes[0], initial_n_value)
        fee = int(0.0001 * COIN)
        split_value = int(
            (initial_n_value - fee) / (MAX_REPLACEMENT_LIMIT + 1))

        outputs = []
        for i in range(MAX_REPLACEMENT_LIMIT + 1):
            outputs.append(CTxOut(split_value, CScript([1])))

        splitting_tx = CTransaction()
        splitting_tx.vin = [CTxIn(utxo, n_sequence=0)]
        splitting_tx.vout = outputs
        splitting_tx_hex = tx_to_hex(splitting_tx)

        txid = self.nodes[0].sendrawtransaction(splitting_tx_hex, True)
        txid = int(txid, 16)

        # Now spend each of those outputs individually
        for i in range(MAX_REPLACEMENT_LIMIT + 1):
            tx_i = CTransaction()
            tx_i.vin = [CTxIn(COutPoint(txid, i), n_sequence=0)]
            tx_i.vout = [CTxOut(split_value - fee, CScript([b'a']))]
            tx_i_hex = tx_to_hex(tx_i)
            self.nodes[0].sendrawtransaction(tx_i_hex, True)

        # Now create doublespend of the whole lot; should fail.
        # Need a big enough fee to cover all spending transactions and have
        # a higher fee rate
        double_spend_value = (split_value -
                              100 * fee) * (MAX_REPLACEMENT_LIMIT + 1)
        inputs = []
        for i in range(MAX_REPLACEMENT_LIMIT + 1):
            inputs.append(CTxIn(COutPoint(txid, i), n_sequence=0))
        double_tx = CTransaction()
        double_tx.vin = inputs
        double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))]
        double_tx_hex = tx_to_hex(double_tx)

        # This will raise an exception
        assert_raises_rpc_error(-26, "too many potential replacements",
                                self.nodes[0].sendrawtransaction,
                                double_tx_hex, True)

        # If we remove an input, it should pass
        double_tx = CTransaction()
        double_tx.vin = inputs[0:-1]
        double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))]
        double_tx_hex = tx_to_hex(double_tx)
        self.nodes[0].sendrawtransaction(double_tx_hex, True)
示例#3
0
    def test_simple_doublespend(self):
        """Simple doublespend"""
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1 * COIN))

        # make_utxo may have generated a bunch of blocks, so we need to sync
        # before we can spend the coins generated, or else the resulting
        # transactions might not be accepted by our peers.
        self.sync_all()

        tx1a = CTransaction()
        tx1a.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1a.vout = [CTxOut(1 * COIN, CScript([b'a']))]
        tx1a_hex = tx_to_hex(tx1a)
        tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)

        self.sync_all()

        # Should fail because we haven't changed the fee
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1b.vout = [CTxOut(1 * COIN, CScript([b'b']))]
        tx1b_hex = tx_to_hex(tx1b)

        # This will raise an exception due to insufficient fee
        assert_raises_rpc_error(-26, "insufficient fee",
                                self.nodes[0].sendrawtransaction, tx1b_hex,
                                True)
        # This will raise an exception due to transaction replacement being disabled
        assert_raises_rpc_error(-26, "txn-mempool-conflict",
                                self.nodes[1].sendrawtransaction, tx1b_hex,
                                True)

        # Extra 0.1 ESS fee
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b']))]
        tx1b_hex = tx_to_hex(tx1b)
        # Replacement still disabled even with "enough fee"
        assert_raises_rpc_error(-26, "txn-mempool-conflict",
                                self.nodes[1].sendrawtransaction, tx1b_hex,
                                True)
        # Works when enabled
        tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)

        mempool = self.nodes[0].getrawmempool()

        assert (tx1a_txid not in mempool)
        assert (tx1b_txid in mempool)

        assert_equal(tx1b_hex, self.nodes[0].getrawtransaction(tx1b_txid))

        # Second node is running mempoolreplacement=0, will not replace originally-seen txn
        mempool = self.nodes[1].getrawmempool()
        assert tx1a_txid in mempool
        assert tx1b_txid not in mempool
示例#4
0
    def run_test(self):
        self.log.info("Mining blocks...")
        self.nodes[0].generate(105)
        self.sync_all()

        chain_height = self.nodes[1].getblockcount()
        assert_equal(chain_height, 105)

        self.log.info("Testing transaction index...")

        #privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
        #address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"
        addressHash = bytes([11,47,10,12,49,191,224,64,107,12,204,19,129,253,190,49,25,70,218,220])
        scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG])
        unspent = self.nodes[0].listunspent()
        tx = CTransaction()
        amount = int(unspent[0]["amount"] * 10000000)
        tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
        tx.vout = [CTxOut(amount, scriptPubKey)]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()

        # Check verbose raw transaction results
        verbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1)
        assert_equal(verbose["vout"][0]["valueSat"], 500000000000)
        assert_equal(verbose["vout"][0]["value"], 5000)

        self.log.info("All Tests Passed")
示例#5
0
        def branch(prevout, initial_value, max_txs, tree_width=5, fee_val=0.0001 * COIN, _total_txs=None):
            if _total_txs is None:
                _total_txs = [0]
            if _total_txs[0] >= max_txs:
                return

            txout_value = (initial_value - fee_val) // tree_width
            if txout_value < fee_val:
                return

            vout = [CTxOut(txout_value, CScript([i+1]))
                    for i in range(tree_width)]
            tx_data = CTransaction()
            tx_data.vin = [CTxIn(prevout, n_sequence=0)]
            tx_data.vout = vout
            tx_hex = tx_to_hex(tx_data)

            assert(len(tx_data.serialize()) < 100000)
            txid = self.nodes[0].sendrawtransaction(tx_hex, True)
            yield tx_data
            _total_txs[0] += 1

            txid = int(txid, 16)

            for i, _ in enumerate(tx_data.vout):
                for x in branch(COutPoint(txid, i), txout_value,
                                max_txs,
                                tree_width=tree_width, fee_val=fee_val,
                                _total_txs=_total_txs):
                    yield x
示例#6
0
    def test_spends_of_conflicting_outputs(self):
        """Replacements that spend conflicting tx outputs are rejected"""
        utxo1 = make_utxo(self.nodes[0], int(1.2 * COIN))
        utxo2 = make_utxo(self.nodes[0], 3 * COIN)

        tx1a = CTransaction()
        tx1a.vin = [CTxIn(utxo1, n_sequence=0)]
        tx1a.vout = [CTxOut(int(1.1 * COIN), CScript([b'a']))]
        tx1a_hex = tx_to_hex(tx1a)
        tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)

        tx1a_txid = int(tx1a_txid, 16)

        # Direct spend an output of the transaction we're replacing.
        tx2 = CTransaction()
        tx2.vin = [CTxIn(utxo1, n_sequence=0), CTxIn(utxo2, n_sequence=0)]
        tx2.vin.append(CTxIn(COutPoint(tx1a_txid, 0), n_sequence=0))
        tx2.vout = tx1a.vout
        tx2_hex = tx_to_hex(tx2)

        # This will raise an exception
        assert_raises_rpc_error(-26, "bad-txns-spends-conflicting-tx",
                                self.nodes[0].sendrawtransaction, tx2_hex,
                                True)

        # Spend tx1a's output to test the indirect case.
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), n_sequence=0)]
        tx1b.vout = [CTxOut(1 * COIN, CScript([b'a']))]
        tx1b_hex = tx_to_hex(tx1b)
        tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
        tx1b_txid = int(tx1b_txid, 16)

        tx2 = CTransaction()
        tx2.vin = [
            CTxIn(utxo1, n_sequence=0),
            CTxIn(utxo2, n_sequence=0),
            CTxIn(COutPoint(tx1b_txid, 0))
        ]
        tx2.vout = tx1a.vout
        tx2_hex = tx_to_hex(tx2)

        # This will raise an exception
        assert_raises_rpc_error(-26, "bad-txns-spends-conflicting-tx",
                                self.nodes[0].sendrawtransaction, tx2_hex,
                                True)
示例#7
0
    def test_new_unconfirmed_inputs(self):
        """Replacements that add new unconfirmed inputs are rejected"""
        confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
        unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)

        tx1 = CTransaction()
        tx1.vin = [CTxIn(confirmed_utxo)]
        tx1.vout = [CTxOut(1*COIN, CScript([b'a']))]
        tx1_hex = tx_to_hex(tx1)
        self.nodes[0].sendrawtransaction(tx1_hex, True)

        tx2 = CTransaction()
        tx2.vin = [CTxIn(confirmed_utxo), CTxIn(unconfirmed_utxo)]
        tx2.vout = tx1.vout
        tx2_hex = tx_to_hex(tx2)

        # This will raise an exception
        assert_raises_rpc_error(-26, "replacement-adds-unconfirmed", self.nodes[0].sendrawtransaction, tx2_hex, True)
示例#8
0
    def test_replacement_fee_per_kb(self):
        """Replacement requires fee-per-KB to be higher"""
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))

        tx1a = CTransaction()
        tx1a.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
        tx1a_hex = tx_to_hex(tx1a)
        self.nodes[0].sendrawtransaction(tx1a_hex, True)

        # Higher fee, but the fee per KB is much lower, so the replacement is
        # rejected.
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
        tx1b_hex = tx_to_hex(tx1b)

        # This will raise an exception due to insufficient fee
        assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
示例#9
0
    def test_doublespend_chain(self):
        """Doublespend of a long chain"""

        initial_n_value = 5000 * COIN
        tx0_outpoint = make_utxo(self.nodes[0], initial_n_value)

        prevout = tx0_outpoint
        remaining_value = initial_n_value
        chain_txids = []
        while remaining_value > 1000 * COIN:
            remaining_value -= 100 * COIN
            tx = CTransaction()
            tx.vin = [CTxIn(prevout, n_sequence=0)]
            tx.vout = [CTxOut(remaining_value, CScript([1]))]
            tx_hex = tx_to_hex(tx)
            txid = self.nodes[0].sendrawtransaction(tx_hex, True)
            chain_txids.append(txid)
            prevout = COutPoint(int(txid, 16), 0)

        # Whether the double-spend is allowed is evaluated by including all
        # child fees - 40 ESS - so this attempt is rejected.
        dbl_tx = CTransaction()
        dbl_tx.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        dbl_tx.vout = [CTxOut(initial_n_value - 30 * COIN, CScript([1]))]
        dbl_tx_hex = tx_to_hex(dbl_tx)

        # This will raise an exception due to insufficient fee
        assert_raises_rpc_error(-26, "insufficient fee",
                                self.nodes[0].sendrawtransaction, dbl_tx_hex,
                                True)

        # Accepted with sufficient fee
        dbl_tx = CTransaction()
        dbl_tx.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        dbl_tx.vout = [CTxOut(1 * COIN, CScript([1]))]
        dbl_tx_hex = tx_to_hex(dbl_tx)
        self.nodes[0].sendrawtransaction(dbl_tx_hex, True)

        mempool = self.nodes[0].getrawmempool()
        for doublespent_txid in chain_txids:
            assert (doublespent_txid not in mempool)
示例#10
0
def SignatureHash(script, txTo, inIdx, hashtype):
    """Consensus-correct SignatureHash

    Returns (hash, err) to precisely match the consensus-critical behavior of
    the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
    """
    HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

    if inIdx >= len(txTo.vin):
        return (HASH_ONE,
                "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
    txtmp = CTransaction(txTo)

    for txin in txtmp.vin:
        txin.scriptSig = b''
    txtmp.vin[inIdx].scriptSig = FindAndDelete(script,
                                               CScript([OP_CODESEPARATOR]))

    if (hashtype & 0x1f) == SIGHASH_NONE:
        txtmp.vout = []

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    elif (hashtype & 0x1f) == SIGHASH_SINGLE:
        outIdx = inIdx
        if outIdx >= len(txtmp.vout):
            return (HASH_ONE,
                    "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))

        tmp = txtmp.vout[outIdx]
        txtmp.vout = []
        for i in range(outIdx):
            txtmp.vout.append(CTxOut())
        txtmp.vout.append(tmp)

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    if hashtype & SIGHASH_ANYONECANPAY:
        tmp = txtmp.vin[inIdx]
        txtmp.vin = []
        txtmp.vin.append(tmp)

    s = txtmp.serialize()
    s += struct.pack(b"<I", hashtype)

    hash = hash256(s)

    return (hash, None)
示例#11
0
def SignatureHash(script, txTo, inIdx, hashtype):
    """Consensus-correct SignatureHash

    Returns (hash, err) to precisely match the consensus-critical behavior of
    the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
    """
    HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

    if inIdx >= len(txTo.vin):
        return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
    txtmp = CTransaction(txTo)

    for txin in txtmp.vin:
        txin.scriptSig = b''
    txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR]))

    if (hashtype & 0x1f) == SIGHASH_NONE:
        txtmp.vout = []

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    elif (hashtype & 0x1f) == SIGHASH_SINGLE:
        outIdx = inIdx
        if outIdx >= len(txtmp.vout):
            return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))

        tmp = txtmp.vout[outIdx]
        txtmp.vout = []
        for i in range(outIdx):
            txtmp.vout.append(CTxOut())
        txtmp.vout.append(tmp)

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    if hashtype & SIGHASH_ANYONECANPAY:
        tmp = txtmp.vin[inIdx]
        txtmp.vin = []
        txtmp.vin.append(tmp)

    s = txtmp.serialize()
    s += struct.pack(b"<I", hashtype)

    hash = hash256(s)

    return (hash, None)
示例#12
0
def make_utxo(node, amount, confirmed=True, script_pub_key=CScript([1])):
    """Create a txout with a given amount and scriptPubKey

    Mines coins as needed.

    confirmed - txouts created will be confirmed in the blockchain;
                unconfirmed otherwise.
    """
    fee = 1 * COIN
    while node.getbalance() < satoshi_round((amount + fee) / COIN):
        node.generate(100)

    new_addr = node.getnewaddress()
    txid = node.sendtoaddress(new_addr, satoshi_round((amount + fee) / COIN))
    tx1 = node.getrawtransaction(txid, 1)
    txid = int(txid, 16)
    i = None

    for i, txout in enumerate(tx1['vout']):
        if txout['scriptPubKey']['addresses'] == [new_addr]:
            break
    assert i is not None

    tx2 = CTransaction()
    tx2.vin = [CTxIn(COutPoint(txid, i))]
    tx2.vout = [CTxOut(amount, script_pub_key)]
    tx2.rehash()

    signed_tx = node.signrawtransaction(tx_to_hex(tx2))

    txid = node.sendrawtransaction(signed_tx['hex'], True)

    # If requested, ensure txouts are confirmed.
    if confirmed:
        mempool_size = len(node.getrawmempool())
        while mempool_size > 0:
            node.generate(1)
            new_size = len(node.getrawmempool())
            # Error out if we have something stuck in the mempool, as this
            # would likely be a bug.
            assert (new_size < mempool_size)
            mempool_size = new_size

    return COutPoint(int(txid, 16), 0)
示例#13
0
    def run_test(self):
        # Mine blocks to get spendable utxos
        self.nodes[0].generate(103)

        # Check that the first node has 3 utxos
        utxos = self.nodes[0].listunspent()
        assert_equal(len(utxos), 3)

        # Compare gettxouts results to results from gettxout RPC function
        gettxout_results = []
        for i in range(len(utxos)):
            gettxout_results.append(self.nodes[0].gettxout(txid=utxos[i]["txid"], n=utxos[i]["vout"],
                                              include_mempool=True))

        utxos_list = []
        for utxo in utxos:
            utxos_list.append({"txid": utxo["txid"], "n": utxo["vout"]})

        for i in range(len(utxos)):
            gettxouts_res = self.nodes[0].gettxouts(utxos_list[:i+1], ["*"], True)
            # compare values for each result
            for j in range(i+1):
                assert_equal(gettxouts_res["txouts"][j]["confirmations"], gettxout_results[j]["confirmations"])
                assert_equal(gettxouts_res["txouts"][j]["scriptPubKey"], gettxout_results[j]["scriptPubKey"]["hex"])
                assert_equal(gettxouts_res["txouts"][j]["scriptPubKeyLen"], len(gettxout_results[j]["scriptPubKey"]["hex"])/2)
                assert_equal(gettxouts_res["txouts"][j]["value"], gettxout_results[j]["value"])
                assert_equal(gettxouts_res["txouts"][j]["isStandard"], True)  # all transactions above are standard

        # Empty list of txid, n pairs should return empty list
        gettxouts = self.nodes[0].gettxouts([], ["*"], True)
        assert_equal(len(gettxouts["txouts"]), 0)

        # Check various combinations of return types
        gettxouts_res = self.nodes[0].gettxouts([{"txid": utxos[0]["txid"], "n": utxos[0]["vout"]}],
                                                ["scriptPubKey"], True)
        assert_equal(set(gettxouts_res["txouts"][0].keys()), {"scriptPubKey"})

        gettxouts_res = self.nodes[0].gettxouts([{"txid": utxos[0]["txid"], "n": utxos[0]["vout"]}],
                                                ["scriptPubKey", "value", "confirmations"], True)
        assert_equal(set(gettxouts_res["txouts"][0].keys()), {"scriptPubKey", "value", "confirmations"})

        gettxouts_res = self.nodes[0].gettxouts([{"txid": utxos[0]["txid"], "n": utxos[0]["vout"]}],
                                                ["*"], True)

        assert_equal(set(gettxouts_res["txouts"][0].keys()),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        assert_raises_rpc_error(
            -32602, "No return fields set",
            self.nodes[0].gettxouts, [{"txid": utxos[0]["txid"], "n": utxos[0]["vout"]}], [], True)

        # TXOs from mempool
        assert_equal(len(self.nodes[0].getrawmempool()), 0)

        # Create, sign and send transaction (from utxos[1])
        spent_utxo = utxos[1] #  utxo that we want to spend
        inputs = []
        outputs = {}
        inputs.append({"txid": spent_utxo["txid"], "vout": spent_utxo["vout"]})
        outputs[self.nodes[0].getnewaddress()] = spent_utxo["amount"] - 3
        raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
        signed_tx = self.nodes[0].signrawtransaction(raw_tx)
        self.nodes[0].sendrawtransaction(signed_tx["hex"], True)

        # new transaction should appear in the mempool
        assert_equal(len(self.nodes[0].getrawmempool()), 1)
        new_utxo_txid = self.nodes[0].getrawmempool()[0]
        spent_utxo_txid = spent_utxo["txid"]

        # Check if new_utxo_txid which is in mempool is discovered for mempool=True and not for mempool=Flase
        gettxouts_res = self.nodes[0].gettxouts([{"txid": new_utxo_txid, "n": 0}], ["*"], False)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])

        gettxouts_res = self.nodes[0].gettxouts([{"txid": new_utxo_txid, "n": 0}], ["*"], True)
        assert_equal(set(gettxouts_res["txouts"][0].keys()),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        # Check if spent_utxo_txid which is spent, but transaction that spends it is in mempool (and not in block)
        gettxouts_res = self.nodes[0].gettxouts([{"txid": spent_utxo_txid, "n": 0}], ["*"], False)
        assert_equal(set(gettxouts_res["txouts"][0].keys()),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        gettxouts_res = self.nodes[0].gettxouts([{"txid": spent_utxo_txid, "n": 0}], ["*"], True)
        assert_equal(gettxouts_res["txouts"][0]["error"], "spent")
        assert_equal(gettxouts_res["txouts"][0]["collidedWith"]["txid"], new_utxo_txid)

        # Check for multiple errors (missing, spent) and utxo that we can obtain
        gettxouts_res = self.nodes[0].gettxouts([{"txid": spent_utxo_txid, "n": 0}, {"txid": "abc", "n": 0},
                                                 {"txid": utxos[2]["txid"], "n": utxos[2]["vout"]}], ["*"], True)
        assert_equal(gettxouts_res["txouts"][0]["error"], "spent")
        assert_equal(gettxouts_res["txouts"][1]["error"], "missing")
        assert_equal(gettxouts_res["txouts"][2].keys(),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        # now generate block - transaction with txid: new_utxo_txid is now in block
        # it should be returned regardles of include_mempool parameter value
        self.nodes[0].generate(1)
        gettxouts_res = self.nodes[0].gettxouts([{"txid": new_utxo_txid, "n": 0}], ["*"], False)
        assert_equal(set(gettxouts_res["txouts"][0].keys()),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        gettxouts_res = self.nodes[0].gettxouts([{"txid": new_utxo_txid, "n": 0}], ["*"], True)
        assert_equal(set(gettxouts_res["txouts"][0].keys()),
                     {"scriptPubKey", "scriptPubKeyLen", "value", "isStandard", "confirmations"})

        # It should not be found after it is spent
        gettxouts_res = self.nodes[0].gettxouts([{"txid": spent_utxo_txid, "n": 0}], ["*"], False)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])
        gettxouts_res = self.nodes[0].gettxouts([{"txid": spent_utxo_txid, "n": 0}], ["*"], True)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])

        # Invalid TXOs (incorrect syntax on input)
        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{"abc": utxos[0]["txid"], "n": utxos[0]["vout"]}], ["*"], True)

        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{"txid": utxos[0]["txid"], "abc": utxos[0]["vout"]}], ["*"], True)

        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{"txid": utxos[0]["txid"]}], ["*"], True)

        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{"n": utxos[0]["vout"]}], ["*"], True)

        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{utxos[0]["txid"]: utxos[0]["vout"]}], ["*"], True)

        assert_raises_rpc_error(
            -32602, "Wrong format. Exactly \"txid\" and \"n\" are required fields.",
            self.nodes[0].gettxouts, [{}], ["*"], True)
        assert_raises_rpc_error(
            -32602, "\"*\" should not be used with other return fields",
            self.nodes[0].gettxouts, [{"abc": utxos[0]["txid"], "n": utxos[0]["vout"]}], ["*", "value"], True)

        assert_raises_rpc_error(
            -1, "JSON value is not an object as expected",
            self.nodes[0].gettxouts, [utxos[0]["txid"]], ["*"], True)

        assert_raises_rpc_error(
            -1, "JSON value is not an object as expected",
            self.nodes[0].gettxouts, [0], ["*"], True)

        assert_raises_rpc_error(
            -1, "JSON value is not an object as expected",
            self.nodes[0].gettxouts, [None], ["*"], True)

        # Missing/non-existing TXOs
        gettxouts_res = self.nodes[0].gettxouts([{"txid": "abc", "n": utxos[0]["vout"]}], ["*"], True)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])

        gettxouts_res = self.nodes[0].gettxouts([{"txid": utxos[0]["txid"], "n": len(utxos[0]) + 1}], ["*"], True)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])

        # Check with non hex string for txid
        gettxouts_res = self.nodes[0].gettxouts([{"txid": "z._", "n": utxos[0]["vout"]}], ["*"], True)
        assert_equal(gettxouts_res["txouts"], [{'error': 'missing'}])

        # check non standard transaction
        utxo = self.nodes[0].listunspent()[0]
        tx1 = CTransaction()
        tx1.vout = [CTxOut(450000, CScript([OP_TRUE]))]  # This is not a standard transactions
        tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), 0))]
        tx_hex = self.nodes[0].signrawtransaction(ToHex(tx1))['hex']
        self.nodes[0].sendrawtransaction(tx_hex, True)
        assert_equal(len(self.nodes[0].getrawmempool()), 1)
        new_tx = self.nodes[0].getrawmempool()[0]

        gettxouts_res = self.nodes[0].gettxouts([{"txid": new_tx, "n": 0}], ["*"], True)
        assert_equal(gettxouts_res["txouts"][0]["isStandard"], False)
示例#14
0
def SignatureHash(script, txTo, inIdx, hashtype, amount, consensusBranchId):
    """Consensus-correct SignatureHash"""
    if inIdx >= len(txTo.vin):
        raise ValueError("inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))

    if consensusBranchId != 0:
        # ZIP 243
        hashPrevouts = b'\x00' * 32
        hashSequence = b'\x00' * 32
        hashOutputs = b'\x00' * 32
        hashJoinSplits = b'\x00' * 32
        hashShieldedSpends = b'\x00' * 32
        hashShieldedOutputs = b'\x00' * 32

        if not (hashtype & SIGHASH_ANYONECANPAY):
            hashPrevouts = getHashPrevouts(txTo)

        if (not (hashtype & SIGHASH_ANYONECANPAY)) and \
            (hashtype & 0x1f) != SIGHASH_SINGLE and \
            (hashtype & 0x1f) != SIGHASH_NONE:
            hashSequence = getHashSequence(txTo)

        if (hashtype & 0x1f) != SIGHASH_SINGLE and \
            (hashtype & 0x1f) != SIGHASH_NONE:
            hashOutputs = getHashOutputs(txTo)
        elif (hashtype & 0x1f) == SIGHASH_SINGLE and \
            0 <= inIdx and inIdx < len(txTo.vout):
            digest = blake2b(digest_size=32, person=b'ZcashOutputsHash')
            digest.update(txTo.vout[inIdx].serialize())
            hashOutputs = digest.digest()

        if len(txTo.vJoinSplit) > 0:
            hashJoinSplits = getHashJoinSplits(txTo)

        if len(txTo.shieldedSpends) > 0:
            hashShieldedSpends = getHashShieldedSpends(txTo)

        if len(txTo.shieldedOutputs) > 0:
            hashShieldedOutputs = getHashShieldedOutputs(txTo)

        digest = blake2b(
            digest_size=32,
            person=b'ZcashSigHash' + struct.pack('<I', consensusBranchId),
        )

        digest.update(
            struct.pack('<I', (int(txTo.fOverwintered) << 31) | txTo.nVersion))
        digest.update(struct.pack('<I', txTo.nVersionGroupId))
        digest.update(hashPrevouts)
        digest.update(hashSequence)
        digest.update(hashOutputs)
        digest.update(hashJoinSplits)
        digest.update(hashShieldedSpends)
        digest.update(hashShieldedOutputs)
        digest.update(struct.pack('<I', txTo.nLockTime))
        digest.update(struct.pack('<I', txTo.nExpiryHeight))
        digest.update(struct.pack('<Q', txTo.valueBalance))
        digest.update(struct.pack('<I', hashtype))

        if inIdx is not None:
            digest.update(txTo.vin[inIdx].prevout.serialize())
            digest.update(ser_string(script))
            digest.update(struct.pack('<Q', amount))
            digest.update(struct.pack('<I', txTo.vin[inIdx].nSequence))

        return (digest.digest(), None)
    else:
        # Pre-Overwinter
        txtmp = CTransaction(txTo)

        for txin in txtmp.vin:
            txin.scriptSig = b''
        txtmp.vin[inIdx].scriptSig = script

        if (hashtype & 0x1f) == SIGHASH_NONE:
            txtmp.vout = []

            for i in range(len(txtmp.vin)):
                if i != inIdx:
                    txtmp.vin[i].nSequence = 0

        elif (hashtype & 0x1f) == SIGHASH_SINGLE:
            outIdx = inIdx
            if outIdx >= len(txtmp.vout):
                raise ValueError("outIdx %d out of range (%d)" %
                                 (outIdx, len(txtmp.vout)))

            tmp = txtmp.vout[outIdx]
            txtmp.vout = []
            for i in range(outIdx):
                txtmp.vout.append(CTxOut())
            txtmp.vout.append(tmp)

            for i in range(len(txtmp.vin)):
                if i != inIdx:
                    txtmp.vin[i].nSequence = 0

        if hashtype & SIGHASH_ANYONECANPAY:
            tmp = txtmp.vin[inIdx]
            txtmp.vin = []
            txtmp.vin.append(tmp)

        s = txtmp.serialize()
        s += struct.pack(b"<I", hashtype)

        hash = hash256(s)

        return (hash, None)
示例#15
0
    def run_test(self):

        # helper functions
        def getaddresstxids(node_index, addresses, start, end):
            return self.nodes[node_index].getaddresstxids({
                'addresses': addresses,
                'start': start,
                'end': end
            })

        def getaddressdeltas(node_index,
                             addresses,
                             start,
                             end,
                             chainInfo=None):
            params = {
                'addresses': addresses,
                'start': start,
                'end': end,
            }
            if chainInfo is not None:
                params.update({'chainInfo': chainInfo})
            return self.nodes[node_index].getaddressdeltas(params)

        # default received value is the balance value
        def check_balance(node_index,
                          address,
                          expected_balance,
                          expected_received=None):
            if isinstance(address, list):
                bal = self.nodes[node_index].getaddressbalance(
                    {'addresses': address})
            else:
                bal = self.nodes[node_index].getaddressbalance(address)
            assert_equal(bal['balance'], expected_balance)
            if expected_received is None:
                expected_received = expected_balance
            assert_equal(bal['received'], expected_received)

        # begin test

        self.nodes[0].generate(105)
        self.sync_all()
        assert_equal(self.nodes[0].getbalance(), 5 * 10)
        assert_equal(self.nodes[1].getblockcount(), 105)
        assert_equal(self.nodes[1].getbalance(), 0)

        # only the oldest 5; subsequent are not yet mature
        unspent_txids = [u['txid'] for u in self.nodes[0].listunspent()]

        # Currently our only unspents are coinbase transactions, choose any one
        tx = self.nodes[0].getrawtransaction(unspent_txids[0], 1)

        # It just so happens that the first output is the mining reward,
        # which has type pay-to-public-key-hash, and the second output
        # is the founders' reward, which has type pay-to-script-hash.
        addr_p2pkh = tx['vout'][0]['scriptPubKey']['addresses'][0]
        addr_p2sh = tx['vout'][1]['scriptPubKey']['addresses'][0]

        # Check that balances from mining are correct (105 blocks mined); in
        # regtest, all mining rewards from a single call to generate() are sent
        # to the same pair of addresses.
        check_balance(1, addr_p2pkh, 105 * 10 * COIN)
        check_balance(1, addr_p2sh, 105 * 2.5 * COIN)

        # Multiple address arguments, results are the sum
        check_balance(1, [addr_p2sh, addr_p2pkh], 105 * 12.5 * COIN)

        assert_equal(len(self.nodes[1].getaddresstxids(addr_p2pkh)), 105)
        assert_equal(len(self.nodes[1].getaddresstxids(addr_p2sh)), 105)
        # test getaddresstxids for lightwalletd
        assert_equal(len(self.nodes[3].getaddresstxids(addr_p2pkh)), 105)
        assert_equal(len(self.nodes[3].getaddresstxids(addr_p2sh)), 105)

        # only the oldest 5 transactions are in the unspent list,
        # dup addresses are ignored
        height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2pkh], 1, 5)
        assert_equal(sorted(height_txids), sorted(unspent_txids))

        height_txids = getaddresstxids(1, [addr_p2sh], 1, 5)
        assert_equal(sorted(height_txids), sorted(unspent_txids))

        # each txid should appear only once
        height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2sh], 1, 5)
        assert_equal(sorted(height_txids), sorted(unspent_txids))

        # do some transfers, make sure balances are good
        txids_a1 = []
        addr1 = self.nodes[1].getnewaddress()
        expected = 0
        expected_deltas = []  # for checking getaddressdeltas (below)
        for i in range(5):
            # first transaction happens at height 105, mined in block 106
            txid = self.nodes[0].sendtoaddress(addr1, i + 1)
            txids_a1.append(txid)
            self.nodes[0].generate(1)
            self.sync_all()
            expected += i + 1
            expected_deltas.append({
                'height': 106 + i,
                'satoshis': (i + 1) * COIN,
                'txid': txid,
            })
        check_balance(1, addr1, expected * COIN)
        assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)),
                     sorted(txids_a1))
        assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)),
                     sorted(txids_a1))

        # Restart all nodes to ensure indices are saved to disk and recovered
        stop_nodes(self.nodes)
        wait_bitcoinds()
        self.setup_network()

        bal = self.nodes[1].getaddressbalance(addr1)
        assert_equal(bal['balance'], expected * COIN)
        assert_equal(bal['received'], expected * COIN)
        assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)),
                     sorted(txids_a1))
        assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)),
                     sorted(txids_a1))

        # Send 3 from addr1, but -- subtlety alert! -- addr1 at this
        # time has 4 UTXOs, with values 1, 2, 3, 4. Sending value 3 requires
        # using up the value 4 UTXO, because of the tx fee
        # (the 3 UTXO isn't quite large enough).
        #
        # The txid from sending *from* addr1 is also added to the list of
        # txids associated with that address (test will verify below).

        addr2 = self.nodes[2].getnewaddress()
        txid = self.nodes[1].sendtoaddress(addr2, 3)
        self.sync_all()

        # the one tx in the mempool refers to addresses addr1 and addr2,
        # check that duplicate addresses are processed correctly
        mempool = self.nodes[0].getaddressmempool(
            {'addresses': [addr2, addr1, addr2]})
        assert_equal(len(mempool), 3)
        # test getaddressmempool for lightwalletd node
        mempool = self.nodes[3].getaddressmempool(
            {'addresses': [addr2, addr1, addr2]})
        assert_equal(len(mempool), 3)

        # addr2 (first arg)
        assert_equal(mempool[0]['address'], addr2)
        assert_equal(mempool[0]['satoshis'], 3 * COIN)
        assert_equal(mempool[0]['txid'], txid)

        # addr1 (second arg)
        assert_equal(mempool[1]['address'], addr1)
        assert_equal(mempool[1]['satoshis'], (-4) * COIN)
        assert_equal(mempool[1]['txid'], txid)

        # addr2 (third arg)
        assert_equal(mempool[2]['address'], addr2)
        assert_equal(mempool[2]['satoshis'], 3 * COIN)
        assert_equal(mempool[2]['txid'], txid)

        # a single address can be specified as a string (not json object)
        addr1_mempool = self.nodes[0].getaddressmempool(addr1)
        assert_equal(len(addr1_mempool), 1)
        # Don't check the timestamp; it's local to the node, and can mismatch
        # due to propagation delay.
        del addr1_mempool[0]['timestamp']
        for key in addr1_mempool[0].keys():
            assert_equal(mempool[1][key], addr1_mempool[0][key])

        tx = self.nodes[0].getrawtransaction(txid, 1)
        assert_equal(tx['vin'][0]['address'], addr1)
        assert_equal(tx['vin'][0]['value'], 4)
        assert_equal(tx['vin'][0]['valueSat'], 4 * COIN)

        txids_a1.append(txid)
        expected_deltas.append({
            'height': 111,
            'satoshis': (-4) * COIN,
            'txid': txid,
        })
        self.sync_all()  # ensure transaction is included in the next block
        self.nodes[0].generate(1)
        self.sync_all()

        # the send to addr2 tx is now in a mined block, no longer in the mempool
        mempool = self.nodes[0].getaddressmempool(
            {'addresses': [addr2, addr1]})
        assert_equal(len(mempool), 0)

        # Test DisconnectBlock() by invalidating the most recent mined block
        tip = self.nodes[1].getchaintips()[0]
        for i in range(self.num_nodes):
            node = self.nodes[i]
            # the value 4 UTXO is no longer in our balance
            check_balance(i, addr1, (expected - 4) * COIN, expected * COIN)
            check_balance(i, addr2, 3 * COIN)

            assert_equal(node.getblockcount(), 111)
            node.invalidateblock(tip['hash'])
            assert_equal(node.getblockcount(), 110)

            mempool = node.getaddressmempool({'addresses': [addr2, addr1]})
            assert_equal(len(mempool), 2)

            check_balance(i, addr1, expected * COIN)
            check_balance(i, addr2, 0)

        # now re-mine the addr1 to addr2 send
        self.nodes[0].generate(1)
        self.sync_all()
        for node in self.nodes:
            assert_equal(node.getblockcount(), 111)

        mempool = self.nodes[0].getaddressmempool(
            {'addresses': [addr2, addr1]})
        assert_equal(len(mempool), 0)

        # the value 4 UTXO is no longer in our balance
        check_balance(2, addr1, (expected - 4) * COIN, expected * COIN)

        # Ensure the change from that transaction appears
        tx = self.nodes[0].getrawtransaction(txid, 1)
        change_vout = list(
            filter(lambda v: v['valueZat'] != 3 * COIN, tx['vout']))
        change = change_vout[0]['scriptPubKey']['addresses'][0]

        # test getaddressbalance
        for node in (2, 3):
            bal = self.nodes[node].getaddressbalance(change)
            assert (bal['received'] > 0)

        # the inequality is due to randomness in the tx fee
        assert (bal['received'] < (4 - 3) * COIN)
        assert_equal(bal['received'], bal['balance'])
        assert_equal(self.nodes[2].getaddresstxids(change), [txid])

        # Further checks that limiting by height works

        # various ranges
        for i in range(5):
            height_txids = getaddresstxids(1, [addr1], 106, 106 + i)
            assert_equal(height_txids, txids_a1[0:i + 1])

        height_txids = getaddresstxids(1, [addr1], 1, 108)
        assert_equal(height_txids, txids_a1[0:3])

        # Further check specifying multiple addresses
        txids_all = list(txids_a1)
        txids_all += self.nodes[1].getaddresstxids(addr_p2pkh)
        txids_all += self.nodes[1].getaddresstxids(addr_p2sh)
        multitxids = self.nodes[1].getaddresstxids(
            {'addresses': [addr1, addr_p2sh, addr_p2pkh]})
        # No dups in return list from getaddresstxids
        assert_equal(len(multitxids), len(set(multitxids)))

        # set(txids_all) removes its (expected) duplicates
        assert_equal(set(multitxids), set(txids_all))

        # test getaddressdeltas
        for node in (1, 3):
            deltas = self.nodes[node].getaddressdeltas({'addresses': [addr1]})
            assert_equal(len(deltas), len(expected_deltas))
            for i in range(len(deltas)):
                assert_equal(deltas[i]['address'], addr1)
                assert_equal(deltas[i]['height'], expected_deltas[i]['height'])
                assert_equal(deltas[i]['satoshis'],
                             expected_deltas[i]['satoshis'])
                assert_equal(deltas[i]['txid'], expected_deltas[i]['txid'])

        # 106-111 is the full range (also the default)
        deltas_limited = getaddressdeltas(1, [addr1], 106, 111)
        assert_equal(deltas_limited, deltas)

        # only the first element missing
        deltas_limited = getaddressdeltas(1, [addr1], 107, 111)
        assert_equal(deltas_limited, deltas[1:])

        deltas_limited = getaddressdeltas(1, [addr1], 109, 109)
        assert_equal(deltas_limited, deltas[3:4])

        # the full range (also the default)
        deltas_info = getaddressdeltas(1, [addr1], 106, 111, chainInfo=True)
        assert_equal(deltas_info['deltas'], deltas)

        # check the additional items returned by chainInfo
        assert_equal(deltas_info['start']['height'], 106)
        block_hash = self.nodes[1].getblockhash(106)
        assert_equal(deltas_info['start']['hash'], block_hash)

        assert_equal(deltas_info['end']['height'], 111)
        block_hash = self.nodes[1].getblockhash(111)
        assert_equal(deltas_info['end']['hash'], block_hash)

        # Test getaddressutxos by comparing results with deltas
        utxos = self.nodes[3].getaddressutxos(addr1)

        # The value 4 note was spent, so won't show up in the utxo list,
        # so for comparison, remove the 4 (and -4 for output) from the
        # deltas list
        deltas = self.nodes[1].getaddressdeltas({'addresses': [addr1]})
        deltas = list(filter(lambda d: abs(d['satoshis']) != 4 * COIN, deltas))
        assert_equal(len(utxos), len(deltas))
        for i in range(len(utxos)):
            assert_equal(utxos[i]['address'], addr1)
            assert_equal(utxos[i]['height'], deltas[i]['height'])
            assert_equal(utxos[i]['satoshis'], deltas[i]['satoshis'])
            assert_equal(utxos[i]['txid'], deltas[i]['txid'])

        # Check that outputs with the same address in the same tx return one txid
        # (can't use createrawtransaction() as it combines duplicate addresses)
        addr = "t2LMJ6Arw9UWBMWvfUr2QLHM4Xd9w53FftS"
        addressHash = unhexlify("97643ce74b188f4fb6bbbb285e067a969041caf2")
        scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL])
        # Add an unrecognized script type to vout[], a legal script that pays,
        # but won't modify the addressindex (since the address can't be extracted).
        # (This extra output has no effect on the rest of the test.)
        scriptUnknown = CScript(
            [OP_HASH160, OP_DUP, OP_DROP, addressHash, OP_EQUAL])
        unspent = list(
            filter(lambda u: u['amount'] >= 4, self.nodes[0].listunspent()))
        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]['txid'], 16), unspent[0]['vout']))
        ]
        tx.vout = [
            CTxOut(1 * COIN, scriptPubKey),
            CTxOut(2 * COIN, scriptPubKey),
            CTxOut(7 * COIN, scriptUnknown),
        ]
        tx = self.nodes[0].signrawtransaction(
            hexlify(tx.serialize()).decode('utf-8'))
        txid = self.nodes[0].sendrawtransaction(tx['hex'], True)
        self.nodes[0].generate(1)
        self.sync_all()

        assert_equal(self.nodes[1].getaddresstxids(addr), [txid])
        check_balance(2, addr, 3 * COIN)
    def run_test(self):
        self.log.info("Mining blocks...")
        self.nodes[0].generate(105)
        self.sync_all()

        chain_height = self.nodes[1].getblockcount()
        assert_equal(chain_height, 105)
        assert_equal(self.nodes[1].getbalance(), 0)
        assert_equal(self.nodes[2].getbalance(), 0)

        # Check that balances are correct
        balance0 = self.nodes[1].getaddressbalance(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
        assert_equal(balance0["balance"], 0)

        # Check p2pkh and p2sh address indexes
        self.log.info("Testing p2pkh and p2sh address index...")

        tx_id0 = self.nodes[0].sendtoaddress(
            "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 10)
        self.nodes[0].generate(1)

        tx_idb0 = self.nodes[0].sendtoaddress(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 10)
        self.nodes[0].generate(1)

        tx_id1 = self.nodes[0].sendtoaddress(
            "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 15)
        self.nodes[0].generate(1)

        tx_idb1 = self.nodes[0].sendtoaddress(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 15)
        self.nodes[0].generate(1)

        tx_id2 = self.nodes[0].sendtoaddress(
            "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 20)
        self.nodes[0].generate(1)

        tx_idb2 = self.nodes[0].sendtoaddress(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 20)
        self.nodes[0].generate(1)

        self.sync_all()

        txids = self.nodes[1].getaddresstxids(
            "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs")
        assert_equal(len(txids), 3)
        assert_equal(txids[0], tx_id0)
        assert_equal(txids[1], tx_id1)
        assert_equal(txids[2], tx_id2)

        tx_idsb = self.nodes[1].getaddresstxids(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
        assert_equal(len(tx_idsb), 3)
        assert_equal(tx_idsb[0], tx_idb0)
        assert_equal(tx_idsb[1], tx_idb1)
        assert_equal(tx_idsb[2], tx_idb2)

        # Check that limiting by height works
        self.log.info("Testing querying txids by range of block heights..")
        height_txids = self.nodes[1].getaddresstxids({
            "addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br"],
            "start":
            105,
            "end":
            110
        })
        assert_equal(len(height_txids), 2)
        assert_equal(height_txids[0], tx_idb0)
        assert_equal(height_txids[1], tx_idb1)

        # Check that multiple addresses works
        multi_tx_ids = self.nodes[1].getaddresstxids({
            "addresses": [
                "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br",
                "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs"
            ]
        })
        assert_equal(len(multi_tx_ids), 6)
        assert_equal(multi_tx_ids[0], tx_id0)
        assert_equal(multi_tx_ids[1], tx_idb0)
        assert_equal(multi_tx_ids[2], tx_id1)
        assert_equal(multi_tx_ids[3], tx_idb1)
        assert_equal(multi_tx_ids[4], tx_id2)
        assert_equal(multi_tx_ids[5], tx_idb2)

        # Check that balances are correct
        balance0 = self.nodes[1].getaddressbalance(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
        assert_equal(balance0["balance"], 45 * 100000000)

        # Check that outputs with the same address will only return one txid
        self.log.info("Testing for txid uniqueness...")
        address_hash = bytes([
            99, 73, 164, 24, 252, 69, 120, 209, 10, 55, 43, 84, 180, 92, 40,
            12, 200, 196, 56, 47
        ])
        script_pub_key = CScript([OP_HASH160, address_hash, OP_EQUAL])
        unspent = self.nodes[0].listunspent()
        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        tx.vout = [CTxOut(10, script_pub_key), CTxOut(11, script_pub_key)]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)

        self.nodes[0].generate(1)
        self.sync_all()

        tx_ids_many = self.nodes[1].getaddresstxids(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
        assert_equal(len(tx_ids_many), 4)
        assert_equal(tx_ids_many[3], sent_txid)

        # Check that balances are correct
        self.log.info("Testing balances...")
        balance0 = self.nodes[1].getaddressbalance(
            "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
        assert_equal(balance0["balance"], 45 * 100000000 + 21)

        # Check that balances are correct after spending
        self.log.info("Testing balances after spending...")
        privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
        address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"
        address_hash2 = bytes([
            11, 47, 10, 12, 49, 191, 224, 64, 107, 12, 204, 19, 129, 253, 190,
            49, 25, 70, 218, 220
        ])
        script_pub_key2 = CScript(
            [OP_DUP, OP_HASH160, address_hash2, OP_EQUALVERIFY, OP_CHECKSIG])
        self.nodes[0].importprivkey(privkey2)

        unspent = self.nodes[0].listunspent()
        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        amount = int(unspent[0]["amount"] * 100000000 - 230000)
        tx.vout = [CTxOut(amount, script_pub_key2)]
        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        spending_txid = self.nodes[0].sendrawtransaction(
            signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()
        balance1 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance1["balance"], amount)

        tx = CTransaction()
        tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))]
        send_amount = 1 * 100000000 + 12840
        change_amount = amount - send_amount - 230000
        tx.vout = [
            CTxOut(change_amount, script_pub_key2),
            CTxOut(send_amount, script_pub_key)
        ]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()

        balance2 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance2["balance"], change_amount)

        # Check that deltas are returned correctly
        deltas = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start": 1,
            "end": 200
        })
        balance3 = 0
        for delta in deltas:
            balance3 += delta["satoshis"]
        assert_equal(balance3, change_amount)
        assert_equal(deltas[0]["address"], address2)
        assert_equal(deltas[0]["blockindex"], 1)

        # Check that entire range will be queried
        deltas_all = self.nodes[1].getaddressdeltas({"addresses": [address2]})
        assert_equal(len(deltas_all), len(deltas))

        # Check that deltas can be returned from range of block heights
        deltas = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start": 113,
            "end": 113
        })
        assert_equal(len(deltas), 1)

        # Check that unspent outputs can be queried
        self.log.info("Testing utxos...")
        utxos = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos), 1)
        assert_equal(utxos[0]["satoshis"], change_amount)

        # Check that indexes will be updated with a reorg
        self.log.info("Testing reorg...")

        best_hash = self.nodes[0].getbestblockhash()
        self.nodes[0].invalidateblock(best_hash)
        self.nodes[1].invalidateblock(best_hash)
        self.nodes[2].invalidateblock(best_hash)
        self.nodes[3].invalidateblock(best_hash)
        self.sync_all()

        balance4 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance4, balance1)

        utxos2 = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos2), 1)
        assert_equal(utxos2[0]["satoshis"], amount)

        # Check sorting of utxos
        self.nodes[2].generate(150)

        self.nodes[2].sendtoaddress(address2, 50)
        self.nodes[2].generate(1)
        self.nodes[2].sendtoaddress(address2, 50)
        self.nodes[2].generate(1)
        self.sync_all()

        utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos3), 3)
        assert_equal(utxos3[0]["height"], 114)
        assert_equal(utxos3[1]["height"], 264)
        assert_equal(utxos3[2]["height"], 265)

        # Check mempool indexing
        self.log.info("Testing mempool indexing...")

        priv_key3 = "cVfUn53hAbRrDEuMexyfgDpZPhF7KqXpS8UZevsyTDaugB7HZ3CD"
        address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB"
        address_hash3 = bytes([
            170, 152, 114, 181, 187, 205, 181, 17, 216, 158, 14, 17, 170, 39,
            218, 115, 253, 44, 63, 80
        ])
        script_pub_key3 = CScript(
            [OP_DUP, OP_HASH160, address_hash3, OP_EQUALVERIFY, OP_CHECKSIG])
        #address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ"
        script_pub_key4 = CScript([OP_HASH160, address_hash3, OP_EQUAL])
        unspent = self.nodes[2].listunspent()

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        amount = int(unspent[0]["amount"] * 100000000 - 230000)
        tx.vout = [CTxOut(amount, script_pub_key3)]
        tx.rehash()
        signed_tx = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        mem_txid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True)
        time.sleep(2)

        tx2 = CTransaction()
        tx2.vin = [
            CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))
        ]
        amount = int(unspent[1]["amount"] * 100000000 - 300000)
        tx2.vout = [
            CTxOut(int(amount / 4), script_pub_key3),
            CTxOut(int(amount / 4), script_pub_key3),
            CTxOut(int(amount / 4), script_pub_key4),
            CTxOut(int(amount / 4), script_pub_key4)
        ]
        tx2.rehash()
        signed_tx2 = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx2.serialize()).decode("utf-8"))
        mem_txid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
        time.sleep(2)

        mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool), 3)
        assert_equal(mempool[0]["txid"], mem_txid1)
        assert_equal(mempool[0]["address"], address3)
        assert_equal(mempool[0]["index"], 0)
        assert_equal(mempool[1]["txid"], mem_txid2)
        assert_equal(mempool[1]["index"], 0)
        assert_equal(mempool[2]["txid"], mem_txid2)
        assert_equal(mempool[2]["index"], 1)

        self.nodes[2].generate(1)
        self.sync_all()
        mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool2), 0)

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(mem_txid2, 16), 0)),
            CTxIn(COutPoint(int(mem_txid2, 16), 1))
        ]
        tx.vout = [CTxOut(int(amount / 2 - 340000), script_pub_key2)]
        tx.rehash()
        self.nodes[2].importprivkey(priv_key3)
        signed_tx3 = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[2].sendrawtransaction(signed_tx3["hex"], True)
        time.sleep(2)

        mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool3), 2)
        assert_equal(mempool3[0]["prevtxid"], mem_txid2)
        assert_equal(mempool3[0]["prevout"], 0)
        assert_equal(mempool3[1]["prevtxid"], mem_txid2)
        assert_equal(mempool3[1]["prevout"], 1)

        # sending and receiving to the same address
        privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8"
        address1 = "myAUWSHnwsQrhuMWv4Br6QsCnpB41vFwHn"
        address1hash = bytes([
            193, 146, 191, 247, 81, 175, 142, 254, 193, 81, 53, 212, 43, 254,
            237, 249, 26, 111, 62, 52
        ])
        address1script = CScript(
            [OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG])

        self.nodes[0].sendtoaddress(address1, 10)
        self.nodes[0].generate(1)
        self.sync_all()

        utxos = self.nodes[1].getaddressutxos({"addresses": [address1]})
        assert_equal(len(utxos), 1)

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(utxos[0]["txid"], 16),
                            utxos[0]["outputIndex"]))
        ]
        amount = int(utxos[0]["satoshis"] - 200000)
        tx.vout = [CTxOut(amount, address1script)]
        tx.rehash()
        self.nodes[0].importprivkey(privkey1)
        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[0].sendrawtransaction(signed_tx["hex"], True)

        self.sync_all()
        mempool_deltas = self.nodes[2].getaddressmempool(
            {"addresses": [address1]})
        assert_equal(len(mempool_deltas), 2)

        # Include chaininfo in results
        self.log.info("Testing results with chain info...")

        deltas_with_info = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start":
            1,
            "end":
            200,
            "chainInfo":
            True
        })
        start_block_hash = self.nodes[1].getblockhash(1)
        end_block_hash = self.nodes[1].getblockhash(200)
        assert_equal(deltas_with_info["start"]["height"], 1)
        assert_equal(deltas_with_info["start"]["hash"], start_block_hash)
        assert_equal(deltas_with_info["end"]["height"], 200)
        assert_equal(deltas_with_info["end"]["hash"], end_block_hash)

        utxos_with_info = self.nodes[1].getaddressutxos({
            "addresses": [address2],
            "chainInfo": True
        })
        expected_tip_block_hash = self.nodes[1].getblockhash(267)
        assert_equal(utxos_with_info["height"], 267)
        assert_equal(utxos_with_info["hash"], expected_tip_block_hash)

        self.log.info("All Tests Passed")
示例#17
0
    def run_test(self):
        self.log.info("Mining blocks...")
        self.nodes[0].generate(105)
        self.sync_all()

        chain_height = self.nodes[1].getblockcount()
        assert_equal(chain_height, 105)

        # Check that
        self.log.info("Testing spent index...")

        fee_satoshis = 192000
        privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
        #address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"
        address_hash = bytes([
            11, 47, 10, 12, 49, 191, 224, 64, 107, 12, 204, 19, 129, 253, 190,
            49, 25, 70, 218, 220
        ])
        script_pub_key = CScript(
            [OP_DUP, OP_HASH160, address_hash, OP_EQUALVERIFY, OP_CHECKSIG])
        unspent = self.nodes[0].listunspent()
        tx = CTransaction()
        amount = int(unspent[0]["amount"] * 100000000 - fee_satoshis)
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        tx.vout = [CTxOut(amount, script_pub_key)]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()

        self.log.info("Testing getspentinfo method...")

        # Check that the spentinfo works standalone
        info = self.nodes[1].getspentinfo({
            "txid": unspent[0]["txid"],
            "index": unspent[0]["vout"]
        })
        assert_equal(info["txid"], txid)
        assert_equal(info["index"], 0)
        assert_equal(info["height"], 106)

        self.log.info("Testing getrawtransaction method...")

        # Check that verbose raw transaction includes spent info
        tx_verbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1)
        assert_equal(tx_verbose["vout"][unspent[0]["vout"]]["spentTxId"], txid)
        assert_equal(tx_verbose["vout"][unspent[0]["vout"]]["spentIndex"], 0)
        assert_equal(tx_verbose["vout"][unspent[0]["vout"]]["spentHeight"],
                     106)

        # Check that verbose raw transaction includes input values
        tx_verbose2 = self.nodes[3].getrawtransaction(txid, 1)
        assert_equal(float(tx_verbose2["vin"][0]["value"]),
                     (amount + fee_satoshis) / 100000000)
        assert_equal(tx_verbose2["vin"][0]["valueSat"], amount + fee_satoshis)

        # Check that verbose raw transaction includes address values and input values
        #privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
        address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"
        address_hash2 = bytes([
            11, 47, 10, 12, 49, 191, 224, 64, 107, 12, 204, 19, 129, 253, 190,
            49, 25, 70, 218, 220
        ])
        script_pub_key2 = CScript(
            [OP_DUP, OP_HASH160, address_hash2, OP_EQUALVERIFY, OP_CHECKSIG])
        tx2 = CTransaction()
        tx2.vin = [CTxIn(COutPoint(int(txid, 16), 0))]
        amount = int(amount - fee_satoshis)
        tx2.vout = [CTxOut(amount, script_pub_key2)]
        tx.rehash()
        self.nodes[0].importprivkey(privkey)
        signed_tx2 = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx2.serialize()).decode("utf-8"))
        txid2 = self.nodes[0].sendrawtransaction(signed_tx2["hex"], True)

        # Check the mempool index
        self.sync_all()
        tx_verbose3 = self.nodes[1].getrawtransaction(txid2, 1)
        assert_equal(tx_verbose3["vin"][0]["address"], address2)
        assert_equal(tx_verbose3["vin"][0]["valueSat"], amount + fee_satoshis)
        assert_equal(float(tx_verbose3["vin"][0]["value"]),
                     (amount + fee_satoshis) / 100000000)

        # Check the database index
        block_hash = self.nodes[0].generate(1)
        self.sync_all()

        tx_verbose4 = self.nodes[3].getrawtransaction(txid2, 1)
        assert_equal(tx_verbose4["vin"][0]["address"], address2)
        assert_equal(tx_verbose4["vin"][0]["valueSat"], amount + fee_satoshis)
        assert_equal(float(tx_verbose4["vin"][0]["value"]),
                     (amount + fee_satoshis) / 100000000)

        # Check block deltas
        self.log.info("Testing getblockdeltas...")

        block = self.nodes[3].getblockdeltas(block_hash[0])
        assert_equal(len(block["deltas"]), 2)
        assert_equal(block["deltas"][0]["index"], 0)
        assert_equal(len(block["deltas"][0]["inputs"]), 0)
        assert_equal(len(block["deltas"][0]["outputs"]), 0)
        assert_equal(block["deltas"][1]["index"], 1)
        assert_equal(block["deltas"][1]["txid"], txid2)
        assert_equal(block["deltas"][1]["inputs"][0]["index"], 0)
        assert_equal(block["deltas"][1]["inputs"][0]["address"],
                     "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW")
        assert_equal(block["deltas"][1]["inputs"][0]["satoshis"],
                     (amount + fee_satoshis) * -1)
        assert_equal(block["deltas"][1]["inputs"][0]["prevtxid"], txid)
        assert_equal(block["deltas"][1]["inputs"][0]["prevout"], 0)
        assert_equal(block["deltas"][1]["outputs"][0]["index"], 0)
        assert_equal(block["deltas"][1]["outputs"][0]["address"],
                     "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW")
        assert_equal(block["deltas"][1]["outputs"][0]["satoshis"], amount)

        self.log.info("All Tests Passed")
示例#18
0
    def test_opt_in(self):
        """Replacing should only work if orig tx opted in"""
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1 * COIN))

        # Create a non-opting in transaction
        tx1a = CTransaction()
        tx1a.vin = [CTxIn(tx0_outpoint, n_sequence=0xffffffff)]
        tx1a.vout = [CTxOut(1 * COIN, CScript([b'a']))]
        tx1a_hex = tx_to_hex(tx1a)
        tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)

        # Shouldn't be able to double-spend
        tx1b = CTransaction()
        tx1b.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        tx1b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b']))]
        tx1b_hex = tx_to_hex(tx1b)

        # This will raise an exception
        assert_raises_rpc_error(-26, "txn-mempool-conflict",
                                self.nodes[0].sendrawtransaction, tx1b_hex,
                                True)

        tx1_outpoint = make_utxo(self.nodes[0], int(1.1 * COIN))

        # Create a different non-opting in transaction
        tx2a = CTransaction()
        tx2a.vin = [CTxIn(tx1_outpoint, n_sequence=0xfffffffe)]
        tx2a.vout = [CTxOut(1 * COIN, CScript([b'a']))]
        tx2a_hex = tx_to_hex(tx2a)
        tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True)

        # Still shouldn't be able to double-spend
        tx2b = CTransaction()
        tx2b.vin = [CTxIn(tx1_outpoint, n_sequence=0)]
        tx2b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b']))]
        tx2b_hex = tx_to_hex(tx2b)

        # This will raise an exception
        assert_raises_rpc_error(-26, "txn-mempool-conflict",
                                self.nodes[0].sendrawtransaction, tx2b_hex,
                                True)

        # Now create a new transaction that spends from tx1a and tx2a
        # opt-in on one of the inputs
        # Transaction should be replaceable on either input

        tx1a_txid = int(tx1a_txid, 16)
        tx2a_txid = int(tx2a_txid, 16)

        tx3a = CTransaction()
        tx3a.vin = [
            CTxIn(COutPoint(tx1a_txid, 0), n_sequence=0xffffffff),
            CTxIn(COutPoint(tx2a_txid, 0), n_sequence=0xfffffffd)
        ]
        tx3a.vout = [
            CTxOut(int(0.9 * COIN), CScript([b'c'])),
            CTxOut(int(0.9 * COIN), CScript([b'd']))
        ]
        tx3a_hex = tx_to_hex(tx3a)

        self.nodes[0].sendrawtransaction(tx3a_hex, True)

        tx3b = CTransaction()
        tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), n_sequence=0)]
        tx3b.vout = [CTxOut(int(0.5 * COIN), CScript([b'e']))]
        tx3b_hex = tx_to_hex(tx3b)

        tx3c = CTransaction()
        tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), n_sequence=0)]
        tx3c.vout = [CTxOut(int(0.5 * COIN), CScript([b'f']))]
        tx3c_hex = tx_to_hex(tx3c)

        self.nodes[0].sendrawtransaction(tx3b_hex, True)
        # If tx3b was accepted, tx3c won't look like a replacement,
        # but make sure it is accepted anyway
        self.nodes[0].sendrawtransaction(tx3c_hex, True)
示例#19
0
    def run_test(self):
        print "Mining blocks..."
        self.nodes[0].generate(105)
        self.sync_all()

        chain_height = self.nodes[1].getblockcount()
        assert_equal(chain_height, 105)
        assert_equal(self.nodes[1].getbalance(), 0)
        assert_equal(self.nodes[2].getbalance(), 0)

        addr1 = "zrCBKy4Uoy1X5jws6cxLqrMuE1ukuctSqfS"
        addr2 = "ztano5XjpquCJdSipz7VRGFgdLqNjXmV9cD"

        # Check that balances are correct
        balance0 = self.nodes[1].getaddressbalance(addr1)
        assert_equal(balance0["balance"], 0)

        # Check p2pkh and p2sh address indexes
        print "Testing p2pkh and p2sh address index..."

        txid0 = self.nodes[0].sendtoaddress(addr2, 10)
        self.nodes[0].generate(1)

        txidb0 = self.nodes[0].sendtoaddress(addr1, 10)
        self.nodes[0].generate(1)

        txid1 = self.nodes[0].sendtoaddress(addr2, 15)
        self.nodes[0].generate(1)

        txidb1 = self.nodes[0].sendtoaddress(addr1, 15)
        self.nodes[0].generate(1)

        txid2 = self.nodes[0].sendtoaddress(addr2, 20)
        self.nodes[0].generate(1)

        txidb2 = self.nodes[0].sendtoaddress(addr1, 20)
        self.nodes[0].generate(1)

        self.sync_all()

        txids = self.nodes[1].getaddresstxids(addr2)
        assert_equal(len(txids), 3)
        assert_equal(txids[0], txid0)
        assert_equal(txids[1], txid1)
        assert_equal(txids[2], txid2)

        txidsb = self.nodes[1].getaddresstxids(addr1)
        assert_equal(len(txidsb), 3)
        assert_equal(txidsb[0], txidb0)
        assert_equal(txidsb[1], txidb1)
        assert_equal(txidsb[2], txidb2)

        # Check that limiting by height works
        print "Testing querying txids by range of block heights.."
        height_txids = self.nodes[1].getaddresstxids({
            "addresses": [addr1],
            "start": 105,
            "end": 110
        })
        assert_equal(len(height_txids), 2)
        assert_equal(height_txids[0], txidb0)
        assert_equal(height_txids[1], txidb1)

        # Check that multiple addresses works
        multitxids = self.nodes[1].getaddresstxids(
            {"addresses": [addr1, addr2]})
        assert_equal(len(multitxids), 6)
        assert_equal(multitxids[0], txid0)
        assert_equal(multitxids[1], txidb0)
        assert_equal(multitxids[2], txid1)
        assert_equal(multitxids[3], txidb1)
        assert_equal(multitxids[4], txid2)
        assert_equal(multitxids[5], txidb2)

        # Check that balances are correct
        balance0 = self.nodes[1].getaddressbalance(addr1)
        assert_equal(balance0["balance"], 45 * 100000000)

        # Check that outputs with the same address will only return one txid
        print "Testing for txid uniqueness..."
        op_hash160 = "a9"
        op_push_20_bytes_onto_the_stack = "14"
        addressHash = "6349a418fc4578d10a372b54b45c280cc8c4382f"
        op_equal = "87"
        genesisCbah = "20bb1acf2c1fc1228967a611c7db30632098f0c641855180b5fe23793b72eea50d00b4"
        scriptPubKey = binascii.unhexlify(op_hash160 +
                                          op_push_20_bytes_onto_the_stack +
                                          addressHash + op_equal + genesisCbah)
        unspent = self.nodes[0].listunspent()
        unspent.sort(key=lambda x: x["amount"], reverse=True)
        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        tx.vout = [CTxOut(10, scriptPubKey), CTxOut(11, scriptPubKey)]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)

        self.nodes[0].generate(1)
        self.sync_all()

        txidsmany = self.nodes[1].getaddresstxids(addr1)
        assert_equal(len(txidsmany), 4)
        assert_equal(txidsmany[3], sent_txid)

        # Check that balances are correct
        print "Testing balances..."
        balance0 = self.nodes[1].getaddressbalance(addr1)
        assert_equal(balance0["balance"], 45 * 100000000 + 21)

        # Check that balances are correct after spending
        print "Testing balances after spending..."
        privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
        address2 = "ztUB6YWTcj2uUe5Rbucnc7oFevn7wCKyN63"
        op_dup = "76"
        addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc"
        op_equalverify = "88"
        op_checksig = "ac"
        scriptPubKey2 = binascii.unhexlify(op_dup + op_hash160 +
                                           op_push_20_bytes_onto_the_stack +
                                           addressHash2 + op_equalverify +
                                           op_checksig + genesisCbah)
        self.nodes[0].importprivkey(privkey2)

        unspent = self.nodes[0].listunspent()
        unspent.sort(key=lambda x: x["amount"], reverse=True)
        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        amount = unspent[0]["amount"] * 100000000
        tx.vout = [CTxOut(amount, scriptPubKey2)]
        tx.rehash()
        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        spending_txid = self.nodes[0].sendrawtransaction(
            signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()
        balance1 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance1["balance"], amount)

        tx = CTransaction()
        tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))]
        send_amount = 1 * 100000000 + 12840
        change_amount = amount - send_amount - 10000
        tx.vout = [
            CTxOut(change_amount, scriptPubKey2),
            CTxOut(send_amount, scriptPubKey)
        ]
        tx.rehash()

        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
        self.nodes[0].generate(1)
        self.sync_all()

        balance2 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance2["balance"], change_amount)

        # Check that deltas are returned correctly
        deltas = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start": 1,
            "end": 200
        })
        balance3 = 0
        for delta in deltas:
            balance3 += delta["satoshis"]
        assert_equal(balance3, change_amount)
        assert_equal(deltas[0]["address"], address2)
        assert_equal(deltas[0]["blockindex"], 1)

        # Check that entire range will be queried
        deltasAll = self.nodes[1].getaddressdeltas({"addresses": [address2]})
        assert_equal(len(deltasAll), len(deltas))

        # Check that deltas can be returned from range of block heights
        deltas = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start": 113,
            "end": 113
        })
        assert_equal(len(deltas), 1)

        # Check that unspent outputs can be queried
        print "Testing utxos..."
        utxos = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos), 1)
        assert_equal(utxos[0]["satoshis"], change_amount)

        # Check that indexes will be updated with a reorg
        print "Testing reorg..."

        best_hash = self.nodes[0].getbestblockhash()
        self.nodes[0].invalidateblock(best_hash)
        self.nodes[1].invalidateblock(best_hash)
        self.nodes[2].invalidateblock(best_hash)
        self.nodes[3].invalidateblock(best_hash)
        self.sync_all()

        balance4 = self.nodes[1].getaddressbalance(address2)
        assert_equal(balance4, balance1)

        utxos2 = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos2), 1)
        assert_equal(utxos2[0]["satoshis"], amount)

        # Check sorting of utxos
        self.nodes[2].generate(150)

        self.nodes[2].sendtoaddress(address2, 50)
        self.nodes[2].generate(1)
        self.nodes[2].sendtoaddress(address2, 50)
        self.nodes[2].generate(1)
        self.sync_all()

        utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]})
        assert_equal(len(utxos3), 3)
        assert_equal(utxos3[0]["height"], 114)
        assert_equal(utxos3[1]["height"], 264)
        assert_equal(utxos3[2]["height"], 265)

        # Check mempool indexing
        print "Testing mempool indexing..."

        privKey3 = "cVfUn53hAbRrDEuMexyfgDpZPhF7KqXpS8UZevsyTDaugB7HZ3CD"
        address3 = "ztihzFwiPbcoMVWzvMAHf37o8jw9VSHdLtC"
        addressHash3 = "aa9872b5bbcdb511d89e0e11aa27da73fd2c3f50"
        scriptPubKey3 = binascii.unhexlify(op_dup + op_hash160 +
                                           op_push_20_bytes_onto_the_stack +
                                           addressHash3 + op_equalverify +
                                           op_checksig + genesisCbah)
        #address4 = "zrJgNMHvfLY26avAQCeHk8NAQxubq7CExqH"
        scriptPubKey4 = binascii.unhexlify(op_hash160 +
                                           op_push_20_bytes_onto_the_stack +
                                           addressHash3 + op_equal +
                                           genesisCbah)
        unspent = self.nodes[2].listunspent()
        unspent.sort(key=lambda x: x["amount"], reverse=True)

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))
        ]
        amount = unspent[0]["amount"] * 100000000
        tx.vout = [CTxOut(amount, scriptPubKey3)]
        tx.rehash()
        signed_tx = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True)
        time.sleep(2)

        tx2 = CTransaction()
        tx2.vin = [
            CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))
        ]
        amount = unspent[1]["amount"] * 100000000
        tx2.vout = [
            CTxOut(amount / 4, scriptPubKey3),
            CTxOut(amount / 4, scriptPubKey3),
            CTxOut(amount / 4, scriptPubKey4),
            CTxOut(amount / 4, scriptPubKey4)
        ]
        tx2.rehash()
        signed_tx2 = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx2.serialize()).decode("utf-8"))
        memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
        time.sleep(2)

        mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool), 3)
        assert_equal(mempool[0]["txid"], memtxid1)
        assert_equal(mempool[0]["address"], address3)
        assert_equal(mempool[0]["index"], 0)
        assert_equal(mempool[1]["txid"], memtxid2)
        assert_equal(mempool[1]["index"], 0)
        assert_equal(mempool[2]["txid"], memtxid2)
        assert_equal(mempool[2]["index"], 1)

        self.nodes[2].generate(1)
        self.sync_all()
        mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool2), 0)

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(memtxid2, 16), 0)),
            CTxIn(COutPoint(int(memtxid2, 16), 1))
        ]
        tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)]
        tx.rehash()
        self.nodes[2].importprivkey(privKey3)
        signed_tx3 = self.nodes[2].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[2].sendrawtransaction(signed_tx3["hex"], True)
        time.sleep(2)

        mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
        assert_equal(len(mempool3), 2)
        assert_equal(mempool3[0]["prevtxid"], memtxid2)
        assert_equal(mempool3[0]["prevout"], 0)
        assert_equal(mempool3[1]["prevtxid"], memtxid2)
        assert_equal(mempool3[1]["prevout"], 1)

        # sending and receiving to the same address
        privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8"
        address1 = "ztkoUySJkS8SMoQEjR6SkSgmDXtMB531yiw"
        address1hash = "c192bff751af8efec15135d42bfeedf91a6f3e34"
        address1script = binascii.unhexlify(op_dup + op_hash160 +
                                            op_push_20_bytes_onto_the_stack +
                                            address1hash + op_equalverify +
                                            op_checksig + genesisCbah)

        self.nodes[0].sendtoaddress(address1, 10)
        self.nodes[0].generate(1)
        self.sync_all()

        utxos = self.nodes[1].getaddressutxos({"addresses": [address1]})
        assert_equal(len(utxos), 1)

        tx = CTransaction()
        tx.vin = [
            CTxIn(COutPoint(int(utxos[0]["txid"], 16),
                            utxos[0]["outputIndex"]))
        ]
        amount = utxos[0]["satoshis"] - 1000
        tx.vout = [CTxOut(amount, address1script)]
        tx.rehash()
        self.nodes[0].importprivkey(privkey1)
        signed_tx = self.nodes[0].signrawtransaction(
            binascii.hexlify(tx.serialize()).decode("utf-8"))
        self.nodes[0].sendrawtransaction(signed_tx["hex"], True)

        self.sync_all()
        mempool_deltas = self.nodes[2].getaddressmempool(
            {"addresses": [address1]})
        assert_equal(len(mempool_deltas), 2)

        # Include chaininfo in results
        print "Testing results with chain info..."

        deltas_with_info = self.nodes[1].getaddressdeltas({
            "addresses": [address2],
            "start":
            1,
            "end":
            200,
            "chainInfo":
            True
        })
        start_block_hash = self.nodes[1].getblockhash(1)
        end_block_hash = self.nodes[1].getblockhash(200)
        assert_equal(deltas_with_info["start"]["height"], 1)
        assert_equal(deltas_with_info["start"]["hash"], start_block_hash)
        assert_equal(deltas_with_info["end"]["height"], 200)
        assert_equal(deltas_with_info["end"]["hash"], end_block_hash)

        utxos_with_info = self.nodes[1].getaddressutxos({
            "addresses": [address2],
            "chainInfo": True
        })
        expected_tip_block_hash = self.nodes[1].getblockhash(267)
        assert_equal(utxos_with_info["height"], 267)
        assert_equal(utxos_with_info["hash"], expected_tip_block_hash)

        # Check that indexes don't get updated when checking a new block (e.g. when calling getBlockTemplate)

        # Initial balance is 0 and no index has been stored for addr3
        addr3 = self.nodes[1].getnewaddress()
        addr3_balance = self.nodes[2].getaddressbalance(addr3)
        addr3_txs = self.nodes[2].getaddresstxids(addr3)
        addr3_utxos = self.nodes[2].getaddressutxos(addr3)
        addr3_mempool = self.nodes[2].getaddressmempool(addr3)

        # The initial balance must be 0
        assert_equal(addr3_balance["balance"], 0)

        # At the beginning no address index must be stored
        assert_equal(addr3_txs, [])

        # At the beginning no unspent index must be stored
        assert_equal(addr3_utxos, [])

        # At the beginning no address mempool index must be stored
        assert_equal(addr3_mempool, [])

        # Add to mempool a transaction that sends money to addr3
        addr3_amount = 0.1
        addr3_txid = self.nodes[2].sendtoaddress(addr3, addr3_amount)
        addr3_balance = self.nodes[2].getaddressbalance(addr3)
        addr3_txs = self.nodes[2].getaddresstxids(addr3)
        addr3_utxos = self.nodes[2].getaddressutxos(addr3)
        addr3_mempool = self.nodes[2].getaddressmempool(addr3)

        # The balance must still be 0
        assert_equal(addr3_balance["balance"], 0)

        # The address index must still be empty
        assert_equal(addr3_txs, [])

        # The unspent index must still be empty
        assert_equal(addr3_utxos, [])

        # The address mempool index must contain the new transaction
        assert_equal(len(addr3_mempool), 1)
        assert_equal(addr3_mempool[0]["txid"], addr3_txid)

        # Call getBlockTemplate to trigger a call to VerifyBlock() => ConnectBlock()
        # It should not update any index
        self.nodes[2].getblocktemplate()
        addr3_balance = self.nodes[2].getaddressbalance(addr3)
        addr3_txs = self.nodes[2].getaddresstxids(addr3)
        addr3_utxos = self.nodes[2].getaddressutxos(addr3)
        addr3_mempool = self.nodes[2].getaddressmempool(addr3)

        # The balance must still be 0
        assert_equal(addr3_balance["balance"], 0)

        # The address index must still be empty
        assert_equal(addr3_txs, [])

        # The unspent index must still be empty
        assert_equal(addr3_utxos, [])

        # The address mempool index must still be empty
        assert_equal(len(addr3_mempool), 1)
        assert_equal(addr3_mempool[0]["txid"], addr3_txid)

        # Connect a new block "validating" the transaction sending money to addr3
        self.nodes[2].generate(1)
        self.sync_all()
        addr3_balance = self.nodes[2].getaddressbalance(addr3)
        addr3_txs = self.nodes[2].getaddresstxids(addr3)
        addr3_utxos = self.nodes[2].getaddressutxos(addr3)
        addr3_mempool = self.nodes[2].getaddressmempool(addr3)

        # The balance must be updated
        assert_equal(addr3_balance["balance"], 0.1 * 1e8)

        # The address index must contain only the new transaction
        assert_equal(len(addr3_txs), 1)
        assert_equal(addr3_txs[0], addr3_txid)

        # The unspent index must contain only the new transaction
        assert_equal(len(addr3_utxos), 1)
        assert_equal(addr3_utxos[0]["txid"], addr3_txid)

        # The address mempool index must be empty again
        assert_equal(addr3_mempool, [])

        print "Passed\n"
示例#20
0
    def test_doublespend_tree(self):
        """Doublespend of a big tree of transactions"""

        initial_n_value = 50 * COIN
        tx0_outpoint = make_utxo(self.nodes[0], initial_n_value)

        def branch(prevout,
                   initial_value,
                   max_txs,
                   tree_width=5,
                   fee_val=0.0001 * COIN,
                   _total_txs=None):
            if _total_txs is None:
                _total_txs = [0]
            if _total_txs[0] >= max_txs:
                return

            txout_value = (initial_value - fee_val) // tree_width
            if txout_value < fee_val:
                return

            vout = [
                CTxOut(txout_value, CScript([i + 1]))
                for i in range(tree_width)
            ]
            tx_data = CTransaction()
            tx_data.vin = [CTxIn(prevout, n_sequence=0)]
            tx_data.vout = vout
            tx_hex = tx_to_hex(tx_data)

            assert (len(tx_data.serialize()) < 100000)
            txid = self.nodes[0].sendrawtransaction(tx_hex, True)
            yield tx_data
            _total_txs[0] += 1

            txid = int(txid, 16)

            for i, _ in enumerate(tx_data.vout):
                for x in branch(COutPoint(txid, i),
                                txout_value,
                                max_txs,
                                tree_width=tree_width,
                                fee_val=fee_val,
                                _total_txs=_total_txs):
                    yield x

        fee = int(0.0001 * COIN)
        n = MAX_REPLACEMENT_LIMIT
        tree_txs = list(branch(tx0_outpoint, initial_n_value, n, fee_val=fee))
        assert_equal(len(tree_txs), n)

        # Attempt double-spend, will fail because too little fee paid
        dbl_tx = CTransaction()
        dbl_tx.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        dbl_tx.vout = [CTxOut(initial_n_value - fee * n, CScript([1]))]
        dbl_tx_hex = tx_to_hex(dbl_tx)
        # This will raise an exception due to insufficient fee
        assert_raises_rpc_error(-26, "insufficient fee",
                                self.nodes[0].sendrawtransaction, dbl_tx_hex,
                                True)

        # 1 ESS fee is enough
        dbl_tx = CTransaction()
        dbl_tx.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
        dbl_tx.vout = [
            CTxOut(initial_n_value - fee * n - 1 * COIN, CScript([1]))
        ]
        dbl_tx_hex = tx_to_hex(dbl_tx)
        self.nodes[0].sendrawtransaction(dbl_tx_hex, True)

        mempool = self.nodes[0].getrawmempool()

        for tx in tree_txs:
            tx.rehash()
            assert (tx.hash not in mempool)

        # Try again, but with more total transactions than the "max txs
        # double-spent at once" anti-DoS limit.
        for n in (MAX_REPLACEMENT_LIMIT + 1, MAX_REPLACEMENT_LIMIT * 2):
            fee = int(0.0001 * COIN)
            tx0_outpoint = make_utxo(self.nodes[0], initial_n_value)
            tree_txs = list(
                branch(tx0_outpoint, initial_n_value, n, fee_val=fee))
            assert_equal(len(tree_txs), n)

            dbl_tx = CTransaction()
            dbl_tx.vin = [CTxIn(tx0_outpoint, n_sequence=0)]
            dbl_tx.vout = [CTxOut(initial_n_value - 2 * fee * n, CScript([1]))]
            dbl_tx_hex = tx_to_hex(dbl_tx)
            # This will raise an exception
            assert_raises_rpc_error(-26, "too many potential replacements",
                                    self.nodes[0].sendrawtransaction,
                                    dbl_tx_hex, True)

            for tx in tree_txs:
                tx.rehash()
                self.nodes[0].getrawtransaction(tx.hash)