def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = self.generate(wallet, 1) + self.generate(node, 99)
        blocks = list(
            map(lambda block: from_hex(CBlock(), node.getblock(block, False)),
                block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = self.generateblock(node,
                                      output=wallet.get_address(),
                                      transactions=[txid])
        blocks.append(
            from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(
            node.gettxoutsetinfo()['hash_serialized_2'],
            "1ec3e58b0be79fca5917c7c30b9761f12adb609d0233cf2b42fa17ec419f0056")
        assert_equal(
            node.gettxoutsetinfo("muhash")['muhash'],
            "faee25ca4765facb643b7a2d96531c568cb52ad84de5ae3d420a92967621ec17")
    def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = self.generate(wallet, 1) + self.generate(node, 99)
        blocks = list(
            map(lambda block: from_hex(CBlock(), node.getblock(block, False)),
                block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = self.generateblock(node,
                                      output=wallet.get_address(),
                                      transactions=[txid])
        blocks.append(
            from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(
            node.gettxoutsetinfo()['hash_serialized_2'],
            "5b1b44097406226c0eb8e1362cd17a1f346522cf9390a8175a57a5262cb1963f")
        assert_equal(
            node.gettxoutsetinfo("muhash")['muhash'],
            "4b8803075d7151d06fad3e88b68ba726886794873fbfa841d12aefb2cc2b881b")
Beispiel #3
0
    def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = self.generate(wallet, 1) + self.generate(node, 99)
        blocks = list(
            map(lambda block: from_hex(CBlock(), node.getblock(block, False)),
                block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = self.generateblock(node,
                                      output=wallet.get_address(),
                                      transactions=[txid])
        blocks.append(
            from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(
            node.gettxoutsetinfo()['hash_serialized_2'],
            "3a570529b4c32e77268de1f81b903c75cc2da53c48df0d125c1e697ba7c8c7b7")
        assert_equal(
            node.gettxoutsetinfo("muhash")['muhash'],
            "a13e0e70eb8acc786549596e3bc154623f1a5a622ba2f70715f6773ec745f435")
Beispiel #4
0
    def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = self.generate(wallet, 1) + self.generate(node, 99)
        blocks = list(
            map(lambda block: from_hex(CBlock(), node.getblock(block, False)),
                block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = self.generateblock(node,
                                      output=wallet.get_address(),
                                      transactions=[txid])
        blocks.append(
            from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(
            node.gettxoutsetinfo()['hash_serialized_2'],
            "221f245cf4c9010eeb7f5183d342c002ae6c1c27e98aa357dccb788c21d98049")
        assert_equal(
            node.gettxoutsetinfo("muhash")['muhash'],
            "7c0890c68501f7630d36aeb3999dc924e63af084ae1bbfba11dd462144637635")
Beispiel #5
0
    def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = wallet.generate(1) + node.generate(99)
        blocks = list(
            map(lambda block: from_hex(CBlock(), node.getblock(block, False)),
                block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = node.generateblock(output=wallet.get_address(),
                                      transactions=[txid])
        blocks.append(
            from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(
            node.gettxoutsetinfo()['hash_serialized_2'],
            "03f3bedef7a3e64686e13b57ec08b1ada40528d8e01f64e077750e225ddb8c07")
        assert_equal(
            node.gettxoutsetinfo("muhash")['muhash'],
            "69ebd7142d443a89c227637ef9a21c05287a98f0acdd40ba7e3ef79d1f4e412d")
Beispiel #6
0
    def run_test(self):
        self.log.info("Read headers data")
        self.headers_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
        with open(self.headers_file_path, encoding='utf-8') as headers_data:
            h_lines = [l.strip() for l in headers_data.readlines()]

        # The headers data is taken from testnet3 for early blocks from genesis until the first checkpoint. There are
        # two headers with valid POW at height 1 and 2, forking off from genesis. They are indicated by the FORK_PREFIX.
        FORK_PREFIX = 'fork:'
        self.headers = [l for l in h_lines if not l.startswith(FORK_PREFIX)]
        self.headers_fork = [l[len(FORK_PREFIX):] for l in h_lines if l.startswith(FORK_PREFIX)]

        self.headers = [from_hex(CBlockHeader(), h) for h in self.headers]
        self.headers_fork = [from_hex(CBlockHeader(), h) for h in self.headers_fork]

        self.log.info("Feed all non-fork headers, including and up to the first checkpoint")
        peer_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
        peer_checkpoint.send_and_ping(msg_headers(self.headers))
        assert {
            'height': 546,
            'hash': '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70',
            'branchlen': 546,
            'status': 'headers-only',
        } in self.nodes[0].getchaintips()

        self.log.info("Feed all fork headers (fails due to checkpoint)")
        with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint']):
            peer_checkpoint.send_message(msg_headers(self.headers_fork))
            peer_checkpoint.wait_for_disconnect()

        self.log.info("Feed all fork headers (succeeds without checkpoint)")
        # On node 0 it succeeds because checkpoints are disabled
        self.restart_node(0, extra_args=['-nocheckpoints', "-minimumchainwork=0x0"])
        peer_no_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
        peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork))
        assert {
            "height": 2,
            "hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
            "branchlen": 2,
            "status": "headers-only",
        } in self.nodes[0].getchaintips()

        # On node 1 it succeeds because no checkpoint has been reached yet by a chain tip
        peer_before_checkpoint = self.nodes[1].add_p2p_connection(P2PInterface())
        peer_before_checkpoint.send_and_ping(msg_headers(self.headers_fork))
        assert {
            "height": 2,
            "hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
            "branchlen": 2,
            "status": "headers-only",
        } in self.nodes[1].getchaintips()
    def test_muhash_implementation(self):
        self.log.info("Test MuHash implementation consistency")

        node = self.nodes[0]
        wallet = MiniWallet(node)
        mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
        node.setmocktime(mocktime)

        # Generate 100 blocks and remove the first since we plan to spend its
        # coinbase
        block_hashes = self.generate(wallet, 1) + self.generate(node, 99)
        blocks = list(map(lambda block: from_hex(CBlock(), node.getblock(block, False)), block_hashes))
        blocks.pop(0)

        # Create a spending transaction and mine a block which includes it
        txid = wallet.send_self_transfer(from_node=node)['txid']
        tx_block = self.generateblock(node, output=wallet.get_address(), transactions=[txid])
        blocks.append(from_hex(CBlock(), node.getblock(tx_block['hash'], False)))

        # Serialize the outputs that should be in the UTXO set and add them to
        # a MuHash object
        muhash = MuHash3072()

        for height, block in enumerate(blocks):
            # The Genesis block coinbase is not part of the UTXO set and we
            # spent the first mined block
            height += 2

            for tx in block.vtx:
                for n, tx_out in enumerate(tx.vout):
                    coinbase = 1 if not tx.vin[0].prevout.hash else 0

                    # Skip witness commitment
                    if (coinbase and n > 0):
                        continue

                    data = COutPoint(int(tx.rehash(), 16), n).serialize()
                    data += struct.pack("<i", height * 2 + coinbase)
                    data += tx_out.serialize()

                    muhash.insert(data)

        finalized = muhash.digest()
        node_muhash = node.gettxoutsetinfo("muhash")['muhash']

        assert_equal(finalized[::-1].hex(), node_muhash)

        self.log.info("Test deterministic UTXO set hash results")
        assert_equal(node.gettxoutsetinfo()['hash_serialized_2'], "f9aa4fb5ffd10489b9a6994e70ccf1de8a8bfa2d5f201d9857332e9954b0855d")
        assert_equal(node.gettxoutsetinfo("muhash")['muhash'], "d1725b2fe3ef43e55aa4907480aea98d406fc9e0bf8f60169e2305f1fbf5961b")
Beispiel #8
0
    def test_getmnlistdiff_base(self, baseBlockHash, blockHash):
        hexstr = self.nodes[0].getblockheader(blockHash, False)
        header = from_hex(CBlockHeader(), hexstr)

        d = self.test_node.getmnlistdiff(int(baseBlockHash, 16), int(blockHash, 16))
        assert_equal(d.baseBlockHash, int(baseBlockHash, 16))
        assert_equal(d.blockHash, int(blockHash, 16))

        # Check that the merkle proof is valid
        proof = CMerkleBlock()
        proof.header = header
        proof.txn = d.merkleProof
        proof = proof.serialize().hex()
        # merkle proof first hash should be coinbase
        assert_equal(self.nodes[0].verifytxoutproof(proof), [format(d.merkleProof.vHash[0], '064x')])

        # Check if P2P messages match with RPCs
        d2 = self.nodes[0].protx_diff(baseBlockHash, blockHash)
        assert_equal(d2["baseBlockHash"], baseBlockHash)
        assert_equal(d2["blockHash"], blockHash)
        assert_equal(d2["cbTxMerkleTree"], d.merkleProof.serialize().hex())
        assert_equal(set([int(e, 16) for e in d2["deletedMNs"]]), set(d.deletedMNs))
        assert_equal(set([int(e["proRegTxHash"], 16) for e in d2["mnList"]]), set([e.proRegTxHash for e in d.mnList]))
        assert_equal(set([QuorumId(e["llmqType"], int(e["quorumHash"], 16)) for e in d2["deletedQuorums"]]), set(d.deletedQuorums))
        assert_equal(set([QuorumId(e["llmqType"], int(e["quorumHash"], 16)) for e in d2["newQuorums"]]), set([QuorumId(e.llmqType, e.quorumHash) for e in d.newQuorums]))

        return d
Beispiel #9
0
    def test_compactblock_construction(self, test_node, use_witness_address=True):
        version = test_node.cmpct_version
        node = self.nodes[0]
        # Generate a bunch of transactions.
        node.generate(COINBASE_MATURITY + 1)
        num_transactions = 25
        address = node.getnewaddress()

        segwit_tx_generated = False
        for _ in range(num_transactions):
            txid = node.sendtoaddress(address, 0.1)
            hex_tx = node.gettransaction(txid)["hex"]
            tx = tx_from_hex(hex_tx)
            if not tx.wit.is_null():
                segwit_tx_generated = True

        if use_witness_address:
            assert segwit_tx_generated  # check that our test is not broken

        # Wait until we've seen the block announcement for the resulting tip
        tip = int(node.getbestblockhash(), 16)
        test_node.wait_for_block_announcement(tip)

        # Make sure we will receive a fast-announce compact block
        self.request_cb_announcements(test_node)

        # Now mine a block, and look at the resulting compact block.
        test_node.clear_block_announcement()
        block_hash = int(node.generate(1)[0], 16)

        # Store the raw block in our internal format.
        block = from_hex(CBlock(), node.getblock("%064x" % block_hash, False))
        for tx in block.vtx:
            tx.calc_sha256()
        block.rehash()

        # Wait until the block was announced (via compact blocks)
        test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30)

        # Now fetch and check the compact block
        header_and_shortids = None
        with p2p_lock:
            # Convert the on-the-wire representation to absolute indexes
            header_and_shortids = HeaderAndShortIDs(test_node.last_message["cmpctblock"].header_and_shortids)
        self.check_compactblock_construction_from_block(version, header_and_shortids, block_hash, block)

        # Now fetch the compact block using a normal non-announce getdata
        test_node.clear_block_announcement()
        inv = CInv(MSG_CMPCT_BLOCK, block_hash)
        test_node.send_message(msg_getdata([inv]))

        test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30)

        # Now fetch and check the compact block
        header_and_shortids = None
        with p2p_lock:
            # Convert the on-the-wire representation to absolute indexes
            header_and_shortids = HeaderAndShortIDs(test_node.last_message["cmpctblock"].header_and_shortids)
        self.check_compactblock_construction_from_block(version, header_and_shortids, block_hash, block)
Beispiel #10
0
    def test_getblocktxn_handler(self, test_node):
        version = test_node.cmpct_version
        node = self.nodes[0]
        # bitcoind will not send blocktxn responses for blocks whose height is
        # more than 10 blocks deep.
        MAX_GETBLOCKTXN_DEPTH = 10
        chain_height = node.getblockcount()
        current_height = chain_height
        while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH):
            block_hash = node.getblockhash(current_height)
            block = from_hex(CBlock(), node.getblock(block_hash, False))

            msg = msg_getblocktxn()
            msg.block_txn_request = BlockTransactionsRequest(
                int(block_hash, 16), [])
            num_to_request = random.randint(1, len(block.vtx))
            msg.block_txn_request.from_absolute(
                sorted(random.sample(range(len(block.vtx)), num_to_request)))
            test_node.send_message(msg)
            test_node.wait_until(lambda: "blocktxn" in test_node.last_message,
                                 timeout=10)

            [tx.calc_sha256() for tx in block.vtx]
            with p2p_lock:
                assert_equal(
                    test_node.last_message["blocktxn"].block_transactions.
                    blockhash, int(block_hash, 16))
                all_indices = msg.block_txn_request.to_absolute()
                for index in all_indices:
                    tx = test_node.last_message[
                        "blocktxn"].block_transactions.transactions.pop(0)
                    tx.calc_sha256()
                    assert_equal(tx.sha256, block.vtx[index].sha256)
                    if version == 1:
                        # Witnesses should have been stripped
                        assert tx.wit.is_null()
                    else:
                        # Check that the witness matches
                        assert_equal(tx.calc_sha256(True),
                                     block.vtx[index].calc_sha256(True))
                test_node.last_message.pop("blocktxn", None)
            current_height -= 1

        # Next request should send a full block response, as we're past the
        # allowed depth for a blocktxn response.
        block_hash = node.getblockhash(current_height)
        msg.block_txn_request = BlockTransactionsRequest(
            int(block_hash, 16), [0])
        with p2p_lock:
            test_node.last_message.pop("block", None)
            test_node.last_message.pop("blocktxn", None)
        test_node.send_and_ping(msg)
        with p2p_lock:
            test_node.last_message["block"].block.calc_sha256()
            assert_equal(test_node.last_message["block"].block.sha256,
                         int(block_hash, 16))
            assert "blocktxn" not in test_node.last_message
Beispiel #11
0
    def mine_double_spend(self, node, txins, target_address, use_mnmerkleroot_from_tip=False):
        amount = Decimal(0)
        for txin in txins:
            txout = node.gettxout(txin['txid'], txin['vout'], False)
            amount += txout['value']
        amount -= Decimal("0.001") # fee

        rawtx = node.createrawtransaction(txins, {target_address: amount})
        rawtx = node.signrawtransactionwithwallet(rawtx)['hex']
        tx = from_hex(CTransaction(), rawtx)

        self.mine_block(node, [tx], use_mnmerkleroot_from_tip=use_mnmerkleroot_from_tip)
Beispiel #12
0
    def _test_getblockheader(self):
        self.log.info("Test getblockheader")
        node = self.nodes[0]

        assert_raises_rpc_error(
            -8, "hash must be of length 64 (not 8, for 'nonsense')",
            node.getblockheader, "nonsense")
        assert_raises_rpc_error(
            -8,
            "hash must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')",
            node.getblockheader,
            "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
        assert_raises_rpc_error(
            -5, "Block not found", node.getblockheader,
            "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(HEIGHT - 1)
        header = node.getblockheader(blockhash=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], HEIGHT)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_is_hex_string(header['chainwork'])
        assert_equal(header['nTx'], 1)
        assert_is_hash_string(header['hash'])
        assert_is_hash_string(header['previousblockhash'])
        assert_is_hash_string(header['merkleroot'])
        assert_is_hash_string(header['bits'], length=None)
        assert isinstance(header['time'], int)
        assert_equal(header['mediantime'], TIME_RANGE_MTP)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)

        # Test with verbose=False, which should return the header as hex.
        header_hex = node.getblockheader(blockhash=besthash, verbose=False)
        assert_is_hex_string(header_hex)

        header = from_hex(CBlockHeader(), header_hex)
        header.calc_sha256()
        assert_equal(header.hash, besthash)

        assert 'previousblockhash' not in node.getblockheader(
            node.getblockhash(0))
        assert 'nextblockhash' not in node.getblockheader(
            node.getbestblockhash())
Beispiel #13
0
    def run_test(self):
        self.log.info("Check that nodes set minfilter to MAX_MONEY while still in IBD")
        for node in self.nodes:
            assert node.getblockchaininfo()['initialblockdownload']
            self.wait_until(lambda: all(peer['minfeefilter'] == MAX_FEE_FILTER for peer in node.getpeerinfo()))

        self.log.info("Check that nodes don't send getdatas for transactions while still in IBD")
        peer_inver = self.nodes[0].add_p2p_connection(P2PDataStore())
        txid = 0xdeadbeef
        peer_inver.send_and_ping(msg_inv([CInv(t=MSG_WTX, h=txid)]))
        # The node should not send a getdata, but if it did, it would first delay 2 seconds
        self.nodes[0].setmocktime(int(time.time() + NONPREF_PEER_TX_DELAY))
        peer_inver.sync_send_with_ping()
        with p2p_lock:
            assert txid not in peer_inver.getdata_requests
        self.nodes[0].disconnect_p2ps()

        self.log.info("Check that nodes don't process unsolicited transactions while still in IBD")
        # A transaction hex pulled from tx_valid.json. There are no valid transactions since no UTXOs
        # exist yet, but it should be a well-formed transaction.
        rawhex = "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a01ff473" + \
            "04402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e168" + \
            "1a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696a" + \
            "d990364e555c271ad504b88ac00000000"
        assert self.nodes[1].decoderawtransaction(rawhex) # returns a dict, should not throw
        tx = from_hex(CTransaction(), rawhex)
        peer_txer = self.nodes[0].add_p2p_connection(P2PInterface())
        with self.nodes[0].assert_debug_log(expected_msgs=["received: tx"], unexpected_msgs=["was not accepted"]):
            peer_txer.send_and_ping(msg_tx(tx))
        self.nodes[0].disconnect_p2ps()

        # Come out of IBD by generating a block
        self.generate(self.nodes[0], 1)

        self.log.info("Check that nodes reset minfilter after coming out of IBD")
        for node in self.nodes:
            assert not node.getblockchaininfo()['initialblockdownload']
            self.wait_until(lambda: all(peer['minfeefilter'] == NORMAL_FEE_FILTER for peer in node.getpeerinfo()))

        self.log.info("Check that nodes process the same transaction, even when unsolicited, when no longer in IBD")
        peer_txer = self.nodes[0].add_p2p_connection(P2PInterface())
        with self.nodes[0].assert_debug_log(expected_msgs=["was not accepted"]):
            peer_txer.send_and_ping(msg_tx(tx))
Beispiel #14
0
    def run_test(self):
        self.log.info("Mining blocks...")
        self.generate(self.nodes[0], COINBASE_MATURITY + 1)

        # address
        address1 = self.nodes[0].getnewaddress()
        # pubkey
        address2 = self.nodes[0].getnewaddress()
        # privkey
        eckey = ECKey()
        eckey.generate()
        address3_privkey = bytes_to_wif(eckey.get_bytes())
        address3 = key_to_p2wpkh(eckey.get_pubkey().get_bytes())
        self.nodes[0].importprivkey(address3_privkey)

        # Check only one address
        address_info = self.nodes[0].getaddressinfo(address1)
        assert_equal(address_info['ismine'], True)

        self.sync_all()

        # Node 1 sync test
        assert_equal(self.nodes[1].getblockcount(), COINBASE_MATURITY + 1)

        # Address Test - before import
        address_info = self.nodes[1].getaddressinfo(address1)
        assert_equal(address_info['iswatchonly'], False)
        assert_equal(address_info['ismine'], False)

        address_info = self.nodes[1].getaddressinfo(address2)
        assert_equal(address_info['iswatchonly'], False)
        assert_equal(address_info['ismine'], False)

        address_info = self.nodes[1].getaddressinfo(address3)
        assert_equal(address_info['iswatchonly'], False)
        assert_equal(address_info['ismine'], False)

        # Send funds to self
        txnid1 = self.nodes[0].sendtoaddress(address1, 0.1)
        self.generate(self.nodes[0], 1)
        rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex']
        proof1 = self.nodes[0].gettxoutproof([txnid1])

        txnid2 = self.nodes[0].sendtoaddress(address2, 0.05)
        self.generate(self.nodes[0], 1)
        rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex']
        proof2 = self.nodes[0].gettxoutproof([txnid2])

        txnid3 = self.nodes[0].sendtoaddress(address3, 0.025)
        self.generate(self.nodes[0], 1)
        rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex']
        proof3 = self.nodes[0].gettxoutproof([txnid3])

        self.sync_all()

        # Import with no affiliated address
        assert_raises_rpc_error(-5, "No addresses", self.nodes[1].importprunedfunds, rawtxn1, proof1)

        balance1 = self.nodes[1].getbalance()
        assert_equal(balance1, Decimal(0))

        # Import with affiliated address with no rescan
        self.nodes[1].createwallet('wwatch', disable_private_keys=True)
        wwatch = self.nodes[1].get_wallet_rpc('wwatch')
        wwatch.importaddress(address=address2, rescan=False)
        wwatch.importprunedfunds(rawtransaction=rawtxn2, txoutproof=proof2)
        assert [tx for tx in wwatch.listtransactions(include_watchonly=True) if tx['txid'] == txnid2]

        # Import with private key with no rescan
        w1 = self.nodes[1].get_wallet_rpc(self.default_wallet_name)
        w1.importprivkey(privkey=address3_privkey, rescan=False)
        w1.importprunedfunds(rawtxn3, proof3)
        assert [tx for tx in w1.listtransactions() if tx['txid'] == txnid3]
        balance3 = w1.getbalance()
        assert_equal(balance3, Decimal('0.025'))

        # Addresses Test - after import
        address_info = w1.getaddressinfo(address1)
        assert_equal(address_info['iswatchonly'], False)
        assert_equal(address_info['ismine'], False)
        address_info = wwatch.getaddressinfo(address2)
        if self.options.descriptors:
            assert_equal(address_info['iswatchonly'], False)
            assert_equal(address_info['ismine'], True)
        else:
            assert_equal(address_info['iswatchonly'], True)
            assert_equal(address_info['ismine'], False)
        address_info = w1.getaddressinfo(address3)
        assert_equal(address_info['iswatchonly'], False)
        assert_equal(address_info['ismine'], True)

        # Remove transactions
        assert_raises_rpc_error(-8, "Transaction does not exist in wallet.", w1.removeprunedfunds, txnid1)
        assert not [tx for tx in w1.listtransactions(include_watchonly=True) if tx['txid'] == txnid1]

        wwatch.removeprunedfunds(txnid2)
        assert not [tx for tx in wwatch.listtransactions(include_watchonly=True) if tx['txid'] == txnid2]

        w1.removeprunedfunds(txnid3)
        assert not [tx for tx in w1.listtransactions(include_watchonly=True) if tx['txid'] == txnid3]

        # Check various RPC parameter validation errors
        assert_raises_rpc_error(-22, "TX decode failed", w1.importprunedfunds, b'invalid tx'.hex(), proof1)
        assert_raises_rpc_error(-5, "Transaction given doesn't exist in proof", w1.importprunedfunds, rawtxn2, proof1)

        mb = from_hex(CMerkleBlock(), proof1)
        mb.header.hashMerkleRoot = 0xdeadbeef  # cause mismatch between merkle root and merkle block
        assert_raises_rpc_error(-5, "Something wrong with merkleblock", w1.importprunedfunds, rawtxn1, mb.serialize().hex())

        mb = from_hex(CMerkleBlock(), proof1)
        mb.header.nTime += 1  # modify arbitrary block header field to change block hash
        assert_raises_rpc_error(-5, "Block not found in chain", w1.importprunedfunds, rawtxn1, mb.serialize().hex())
Beispiel #15
0
    def run_test(self):
        self.log.info("Read headers data")
        self.headers_file_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
        with open(self.headers_file_path, encoding='utf-8') as headers_data:
            h_lines = [l.strip() for l in headers_data.readlines()]

        # The headers data is taken from testnet3 for early blocks from genesis until the first checkpoint. There are
        # two headers with valid POW at height 1 and 2, forking off from genesis. They are indicated by the FORK_PREFIX.
        FORK_PREFIX = 'fork:'
        self.headers = [l for l in h_lines if not l.startswith(FORK_PREFIX)]
        self.headers_fork = [
            l[len(FORK_PREFIX):] for l in h_lines if l.startswith(FORK_PREFIX)
        ]

        self.headers = [from_hex(CBlockHeader(), h) for h in self.headers]
        self.headers_fork = [
            from_hex(CBlockHeader(), h) for h in self.headers_fork
        ]

        self.log.info(
            "Feed all non-fork headers, including and up to the first checkpoint"
        )
        peer_checkpoint = self.nodes[0].add_outbound_p2p_connection(
            P2PInterface(), p2p_idx=0)
        peer_checkpoint.send_and_ping(msg_headers(self.headers))
        assert {
            'height': 546,
            'hash':
            '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70',
            'branchlen': 546,
            'status': 'headers-only',
        } in self.nodes[0].getchaintips()

        self.log.info("Feed all fork headers (fails due to checkpoint)")
        with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint']):
            peer_checkpoint.send_message(msg_headers(self.headers_fork))
            peer_checkpoint.wait_for_disconnect()

        self.log.info("Feed all fork headers (succeeds without checkpoint)")
        # On node 0 it succeeds because checkpoints are disabled
        self.restart_node(0,
                          extra_args=['-nocheckpoints', "-minimumchainwork=0"])
        peer_no_checkpoint = self.nodes[0].add_outbound_p2p_connection(
            P2PInterface(), p2p_idx=0)
        peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork))
        assert {
            "height": 2,
            "hash":
            "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
            "branchlen": 2,
            "status": "headers-only",
        } in self.nodes[0].getchaintips()

        # On node 1 it succeeds because no checkpoint has been reached yet by a chain tip
        peer_before_checkpoint = self.nodes[1].add_outbound_p2p_connection(
            P2PInterface(), p2p_idx=1)
        peer_before_checkpoint.send_and_ping(msg_headers(self.headers_fork))
        assert {
            "height": 2,
            "hash":
            "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
            "branchlen": 2,
            "status": "headers-only",
        } in self.nodes[1].getchaintips()

        self.log.info(
            "Feed checkpoint-violating block (succeeds up until the checkpoint mismatch, then fails)"
        )
        block = CBlockHeader(self.headers_fork[-1])
        headers_fork2 = []
        for time_offset, nonce in (
            (3, 0x023ec36d),
            (3, 0x9e4f929b),
            (0, 0x8bb04400),
            (3, 0x31bbae20),
            (0, 0xd53e5028),
            (2, 0x7841f4e3),
            (5, 0x7a8990a4),
            (2, 0x489e28a1),
            (1, 0x68bdb61a),
            (-1, 0xf6d2a9fb),
            (5, 0x487dcf25),
            (3, 0x546da3d4),
            (4, 0xc1f844d2),
            (3, 0x0c086f6f),
            (0, 0xc2321e55),
            (6, 0xde1aa13c),
            (0, 0x05227358),
            (4, 0x5e021e88),
            (1, 0xab2a18ae),
            (8, 0x80c58047),
            (5, 0xfaed66b9),
            (4, 0x85e64899),
            (6, 0x3a0de669),
            (1, 0x5c519d58),
            (4, 0x992f74d0),
            (4, 0xf9eb3bef),
            (4, 0x07673e35),
            (5, 0x21b99d08),
            (3, 0xef38d256),
            (2, 0xa4f1dc1b),
            (1, 0x2c8a4530),
            (0, 0x2b5ea5b4),
            (6, 0xf2284fc5),
            (0, 0x1dfbd513),
            (0, 0x0b17a886),
            (2, 0x0bc3f397),
            (0, 0x22cc4db0),
            (9, 0x297d6621),
            (1, 0xa6ae996b),
            (0, 0x48749a3f),
            (0, 0x989bf1a2),
            (6, 0xa052d387),
            (1, 0x9e2f6137),
            (3, 0x6a0be10c),
            (1, 0xef64e362),
            (4, 0xce516de6),
            (0, 0x2d077f41),
            (1, 0x6188fb5d),
            (3, 0xa72b0388),
            (2, 0xd1065e3b),
            (0, 0x73641cc7),
            (4, 0xa667e807),
            (3, 0x343f4941),
            (2, 0xe62c5e97),
            (2, 0x64ccbe3f),
            (2, 0x891494ce),
            (2, 0x1a1593ba),
            (1, 0x7fb3165c),
            (3, 0x9210c30b),
            (0, 0x221e0eb6),
            (2, 0x9e80023b),
            (5, 0xb8981525),
            (4, 0xa9eb35ed),
            (0, 0x0cfe8f68),
            (4, 0x31868c9d),
            (0, 0xbc0fa60e),
            (5, 0xcca64b21),
            (0, 0x28a1f860),
            (2, 0xbf629fb5),
            (2, 0x4e0673ab),
            (0, 0x8271fd15),
            (2, 0x1d1ba6fd),
            (1, 0xf8552431),
            (1, 0x4a5847a3),
            (2, 0x60e70a8b),
            (0, 0x28e05674),
            (1, 0x3a52baa0),
            (4, 0x93cc4193),
            (1, 0xb9e83452),
            (-1, 0x02578099),
            (6, 0xf1deecdb),
            (3, 0xbfc713f0),
            (1, 0xd42411c2),
            (3, 0x2ff09457),
            (4, 0xca26349a),
            (5, 0x11e45b8a),
            (2, 0x21861128),
            (0, 0xc2f0cf4d),
            (4, 0x8934b604),
            (0, 0xcc822981),
            (4, 0xef67ee2c),
            (2, 0x940a8496),
            (2, 0xd67ea903),
            (3, 0xd6975b4c),
            (1, 0x39d3775b),
            (3, 0x33e2a45a),
            (0, 0x43452dd5),
            (5, 0xf0221dda),
            (2, 0x24440716),
            (1, 0x9c160e08),
            (4, 0xd0e7252a),
            (1, 0x447411d2),
            (3, 0x958eaa10),
            (-3, 0xb9c956ec),
            (1, 0x5cd63c9c),
            (1, 0x4af69deb),
            (3, 0x90b93454),
            (2, 0x17959b09),
            (3, 0xb05154ec),
            (0, 0x058f9e11),
            (1, 0x227d9c1e),
            (4, 0xacb7701f),
            (4, 0x9542721f),
            (2, 0x1e05aa42),
            (1, 0x933d4365),
            (1, 0xb5c3a67e),
            (0, 0xac9cc6a6),
            (1, 0x4a76055a),
            (2, 0x7721afe9),
            (5, 0xe12b457e),
            (1, 0xaecdc119),
            (0, 0xe8e4ca43),
            (1, 0x6e42e836),
            (1, 0x1d4dec49),
            (1, 0xf8056d54),
            (1, 0x584bccb8),
            (1, 0x1932259b),
            (0, 0xdf53ee37),
            (0, 0x74e1f913),
            (1, 0xc7d3a7e2),
            (4, 0xef483c04),
            (0, 0x60ad07f0),
            (3, 0x89c790ea),
            (0, 0xb7cadd7e),
            (2, 0x38a82398),
            (1, 0xfb93ea07),
            (0, 0x200d8ecd),
            (0, 0xf1339a41),
            (3, 0x6af69ec7),
            (3, 0xaffa785f),
            (2, 0x67552c61),
            (3, 0xec447684),
            (0, 0xa28c3c1b),
            (0, 0x1a3218f3),
            (3, 0xc291da2c),
            (0, 0x497d588f),
            (3, 0x9fc4f865),
            (0, 0x68070cc7),
            (4, 0x9b7c0842),
            (3, 0x3ea910ac),
            (0, 0x5c793e79),
            (3, 0x839fca4c),
            (1, 0x16a801e7),
            (0, 0x26ad46a3),
            (2, 0x7709be6c),
            (2, 0xc57d1b58),
            (4, 0x9a4a49c1),
            (4, 0xd59ee673),
            (7, 0x8d1ded67),
            (1, 0x9ddc3594),
            (0, 0xf3af3d45),
            (3, 0xbbb210be),
            (0, 0xec262c80),
            (4, 0x6731951b),
            (0, 0xdc36282b),
            (2, 0xae470ed2),
            (1, 0x22c57186),
            (1, 0xde307b71),
            (4, 0x3d185e05),
            (-3, 0x58d53609),
            (1, 0xb25fc17d),
            (2, 0x6c490b64),
            (5, 0x03d05d9b),
            (2, 0x3e84e2ce),
            (0, 0x2c38303d),
            (1, 0x487c092c),
            (1, 0x23a3da6e),
            (3, 0x2854a040),
            (1, 0xa546be54),
            (1, 0x50bfd84d),
            (1, 0x6795f353),
            (0, 0x82e77285),
            (1, 0x24dd5aa3),
            (1, 0x0563f0ea),
            (2, 0xb2b9be8d),
            (1, 0x54e70019),
            (0, 0xb4a31d38),
            (0, 0xfd3c816d),
            (4, 0x84bfd3a7),
            (3, 0x47ecc30d),
            (2, 0x6e1caa0c),
            (1, 0x47097b3e),
            (0, 0x30316532),
            (0, 0xca42b48d),
            (6, 0xb5f05a80),
            (5, 0xcf1f9c0f),
            (1, 0xc7c9c0a0),
            (7, 0xdce826fa),
            (2, 0x92478133),
            (0, 0xdeff31ab),
            (2, 0xfeba362f),
            (2, 0x143b78db),
            (0, 0x48dfb442),
            (1, 0x7b660255),
            (0, 0x9b2d9613),
            (0, 0xc81a0b46),
            (5, 0xfa0257c2),
            (0, 0xcb799eac),
            (3, 0xe66885b5),
            (0, 0xb7523b87),
            (3, 0x80ec766e),
            (0, 0xd3117846),
            (4, 0x44d9d213),
            (3, 0xf3540f37),
            (0, 0x838a3b64),
            (4, 0xd221d138),
            (3, 0xa96e0947),
            (1, 0xd09222da),
            (1, 0x72071fec),
            (0, 0x5424ae38),
            (4, 0xbd5c3d49),
            (4, 0x2d1be9ef),
            (3, 0x31d8521d),
            (3, 0x5f0ac290),
            (0, 0x27710324),
            (3, 0xc1cc6b58),
            (0, 0xb1256275),
            (0, 0x5473ced1),
            (1, 0x35293898),
            (0, 0x062a003f),
            (3, 0xee177b2e),
            (4, 0xbbb9235a),
            (1, 0x183cebbe),
            (3, 0xced4e55b),
            (2, 0x8050c0fc),
            (7, 0xe46e0207),
            (2, 0xf23c4b96),
            (-2, 0x2d7ec1f1),
            (1, 0x90161c6d),
            (8, 0x62d4b92f),
            (1, 0x20086401),
            (2, 0x2ce864a0),
            (4, 0x317da57e),
            (2, 0x2cc9250b),
            (0, 0xf41ea979),
            (1, 0xa50ca905),
            (0, 0x4c0916bb),
            (6, 0x45becd84),
            (3, 0xdac6c807),
            (0, 0xc88954d5),
            (2, 0xf1ebf2b6),
            (2, 0xa1e8f013),
            (1, 0xb86af5b1),
            (1, 0xc864d9f1),
            (4, 0x5e91821b),
            (5, 0x9b3ae958),
            (0, 0x5c37debb),
            (4, 0xf85e2180),
            (1, 0x9de6eb5c),
            (1, 0x51ec9650),
            (0, 0xf3d31a0d),
            (0, 0x127a4cad),
            (2, 0x7698ee29),
            (1, 0x63297ce6),
            (1, 0xf9952a56),
            (0, 0xb2bcdb59),
            (2, 0xd904198f),
            (1, 0xe0ceed57),
            (2, 0xe883801f),
            (0, 0x9c48eff1),
            (2, 0x69bd1c00),
            (0, 0xefb5c46c),
            (1, 0x0ee6d904),
            (0, 0xa01e4f15),
            (0, 0xe50170fc),
            (3, 0x1a057766),
            (2, 0xffddd03e),
            (1, 0x9842404d),
            (0, 0xff3c892c),
            (3, 0x468f2c36),
            (2, 0xef3c2e4e),
            (0, 0x72c0ea16),
            (4, 0x815c722e),
            (1, 0xe77dee42),
            (0, 0xddd8b502),
            (5, 0xf4d60169),
            (0, 0x86b593af),
            (0, 0x08cca2a5),
            (4, 0x07652fb5),
            (2, 0x19ead298),
            (0, 0x94af6d52),
            (2, 0x67955b19),
            (0, 0xf579c469),
            (0, 0x4b010360),
            (0, 0x67bbba31),
            (5, 0x2e47930e),
            (1, 0xbc6872d8),
            (3, 0x645621b8),
            (1, 0xe2c5120b),
            (0, 0xf3c50807),
            (1, 0x6dcf4d07),
            (1, 0xaeb4237d),
            (1, 0x2a5f46a0),
            (2, 0x4e8d3883),
            (0, 0x48268869),
            (0, 0x3bd2401a),
            (6, 0x0bec238c),
            (0, 0x262c5697),
            (1, 0xbbf9572d),
            (2, 0x37df6e6f),
            (3, 0x2ce9e7f3),
            (2, 0x9c0741b1),
            (0, 0x8158c135),
            (2, 0x007c8856),
            (1, 0x6c59cc11),
            (1, 0x2d77e50c),
            (0, 0x43b85637),
            (1, 0x37440748),
            (4, 0x418b2692),
            (4, 0x3bc8200e),
            (3, 0x42e28d55),
            (1, 0xadd84676),
            (0, 0x2f58d608),
            (4, 0xa252bf4e),
            (5, 0x36365c0e),
            (3, 0x22736e12),
            (2, 0xac0e0e83),
            (1, 0x30316f60),
            (4, 0xedb2b98e),
            (1, 0x46cd60ed),
            (3, 0x8404d922),
            (2, 0x0e230e16),
            (1, 0xf2b50134),
            (-1, 0x8e256fff),
            (0, 0x80199c4d),
            (1, 0x56e07a97),
            (1, 0x2f9eed9a),
            (0, 0xfb8a7055),
            (3, 0xe3d02c6b),
            (3, 0xd9b43b13),
            (1, 0xe4faa52a),
            (2, 0x270801f7),
            (0, 0x5fa6a206),
            (4, 0xa151f071),
            (3, 0xd2848896),
            (0, 0x3d5f905f),
            (5, 0x499ae522),
            (1, 0xc61d9839),
            (5, 0xdd2f28b4),
            (0, 0x7dc21c39),
            (0, 0x57e1ab56),
            (0, 0x42027d5a),
            (6, 0x242a8813),
            (4, 0x69fdcc57),
            (3, 0xff7bd13a),
            (2, 0x9a3b2839),
            (5, 0x4af325ee),
            (2, 0x58dea930),
            (2, 0x202b57a4),
            (764, 0xa39c30f0),
            (3, 0x1ac08e2c),
            (7, 0xa9263507),
            (1, 0xb1c5602a),
            (0, 0xf9716695),
            (2, 0x8ce36f1c),
            (1, 0xddf12292),
            (4, 0xa22e830d),
            (1, 0xb84c2e51),
            (2, 0x3f6eb08c),
            (0, 0x185ae643),
            (0, 0x3b3ee340),
            (5, 0x2f0bce41),
            (5, 0x2c915d7c),
            (4, 0xe0169c60),
            (5, 0xc5b08211),
            (0, 0x3f123b19),
            (2, 0x443baa3f),
            (0, 0x86e5bd6b),
            (1, 0x728af7ae),
            (2, 0x34cd4af0),
            (1, 0x773b28fc),
            (4, 0xb42fcf79),
            (2, 0xcf4cddcd),
            (3, 0x472c939d),
            (1, 0xa2f66937),
            (3, 0x9202dd5a),
            (13, 0x87b4cbd0),
            (16, 0x8d74ed44),
            (1, 0xab0ec370),
            (0, 0x4345bc72),
            (3, 0x1663d4e8),
            (54, 0x53304a20),
            (14, 0xf3c7c0b5),
            (1, 0xa755c4d5),
            (0, 0xb4a4246d),
            (3, 0xb55800f7),
            (14, 0x80d85102),
            (0, 0x98d4e5ac),
            (1, 0x6f245269),
            (13, 0x038c57c4),
            (0, 0x86e5ac2e),
            (1, 0x6c1963c6),
            (0, 0x1adc14a1),
            (3, 0x8f37ac31),
            (18, 0x16fd4d32),
            (15, 0xee5bbf16),
            (13, 0xfba44c88),
            (13, 0x4f6b4e47),
            (14, 0xf9d7fe91),
            (1, 0xe5e66769),
            (1, 0x7ff9be17),
            (1, 0xd53b2c20),
            (3, 0xa48129e8),
            (1, 0xca7692d9),
            (1, 0x55067b69),
            (0, 0xbae33993),
            (0, 0x789a395c),
            (0, 0xb2617974),
            (1, 0xa49ae3ae),
            (0, 0x52c934ba),
            (4, 0x6ee4bde6),
            (0, 0x083b4807),
            (4, 0x382b6a26),
            (1, 0x17f2e8d3),
            (4, 0x70d17e03),
            (4, 0x48bb565b),
            (2, 0x437d655f),
            (2, 0xece43c5f),
            (0, 0xc06407f0),
            (4, 0xabc4d27a),
            (4, 0xf7162b9f),
            (5, 0x97dc4313),
            (4, 0x7c9578fa),
            (4, 0xd38229e0),
            (4, 0xc61a6e08),
            (0, 0xc821347c),
            (5, 0xbb37d0ab),
            (4, 0x3e93a911),
            (5, 0x3c03d85e),
            (4, 0xb289102e),
            (5, 0x5e42768e),
            (4, 0x4c574f91),
            (0, 0xc3531db9),
            (5, 0x8ebbfe1b),
            (2, 0x62de7520),
            (4, 0x11def7c6),
            (0, 0xd12a5839),
            (4, 0xd60eb230),
            (0, 0xfb6d0844),
            (2, 0x701a5c56),
            (1, 0x48998570),
            (4, 0xcc786b3e),
            (1, 0x8973807a),
            (4, 0x77151b83),
            (3, 0xb9b223a4),
            (4, 0x7d213a8e),
            (0, 0xe627ba6e),
            (1, 0x2de15b60),
            (0, 0x382c67c4),
            (6, 0x43701b8e),
            (8, 0x5f41b027),
            (1, 0x09c5d515),
            (1, 0x7fdaaf68),
            (4, 0x8bf79290),
            (3, 0x1a7c0271),
            (0, 0x3562b3a1),
            (4, 0x079aa703),
            (1, 0x8fb1aace),
            (4, 0xb02b8935),
            (4, 0x939d1697),
            (0, 0x7b2d7a80),
            (4, 0x351c3288),
            (5, 0x5f3dd388),
            (1, 0xe865101a),
            (0, 0x57871387),
            (0, 0xd4fd6955),
            (4, 0x86fe1cbb),
            (0, 0x21296c24),
            (4, 0x68f6d66d),
            (3, 0x9ac3b10b),
            (8, 0x659ebf23),
            (0, 0x8e483006),
            (5, 0x2821774f),
            (4, 0x3b005030),
            (1, 0x6bb6f09a),
            (3, 0xb918ea6c),
            (5, 0x259aca8a),
            (1, 0x4bdaa577),
            (3, 0x585e295b),
            (2, 0xd7c04cca),
            (6, 0x00a0f04d),
            (3, 0x0cb7eda9),
            (5, 0xb1d83641),
            (4, 0xd1105e7d),
            (2, 0xe8ad8382),
            (3, 0x92df8405),
            (4, 0xffb344bf),
            (0, 0x94471661),
            (-3, 0x0b9714a4),
            (6, 0x87e08f18),
            (6, 0xae594216),
            (5, 0x51acdc5e),
            (4, 0x83664747),
            (0, 0x7b10c195),
            (2, 0x1ef4426a),
            (5, 0x1dbf29d0),
            (2, 0xe9b85e89),
            (3, 0x18611e1a),
            (0, 0xa10966dd),
            (0, 0xe54fad12),
            (5, 0x03e6220d),
            (3, 0x64fa4ada),
            (4, 0x8facb4b4),
            (2, 0xfc0dae5b),
            (4, 0x61a98300),
            (0, 0xd919ee25),
            (3, 0x47d8f268),
            (1, 0xd3d5250f),
            (1, 0xa1b7d150),
            (1, 0x39584b6a),
            (1, 0xb730f059),
            (0, 0x421a930a),
            (0, 0xf4520724),
            (2, 0xf51ac97e),
            (1, 0x3a2e424f),
            (5, 0x4488e824),
            (5, 0x51f37f50),
            (0, 0x2060682b),
            (4, 0x668bcc70),
            (0, 0x87bfad0d),
            (3, 0x87a5e2be),
            (3, 0xdb87b268),
            (0, 0xbdc1bd9f),
            (0, 0x9e97bae4),
            (0, 0x5f8854cc),
            (1, 0x6a54a576),
            (0, 0x6abb7c6e),
            (4, 0x3529e627),
            (0, 0x2b17bf18),
            (6, 0xe718bb6f),
            (0, 0x2f8ca470),
            (5, 0xabf106a3),
            (4, 0x6f80543f),
            (0, 0x7459d412),
        ):
            block.hashPrevBlock = block.sha256
            block.nTime += time_offset
            block.nNonce = nonce
            block.rehash()
            headers_fork2.append(CBlockHeader(block))

        with self.nodes[1].assert_debug_log(['checkpoint-mismatch']):
            peer_before_checkpoint.send_message(msg_headers(headers_fork2))
            peer_before_checkpoint.wait_for_disconnect()
        assert {
            "height": 545,
            "hash":
            "000000008ce04625549eb92726e39fe6de52cd44df861bbd477f9ada8bc30efc",
            "branchlen": 545,
            "status": "headers-only",
        } in self.nodes[1].getchaintips()
 def build_block_on_tip(self):
     blockhash = self.generate(self.nodes[2], 1)[0]
     block_hex = self.nodes[2].getblock(blockhash=blockhash, verbosity=0)
     block = from_hex(CBlock(), block_hex)
     block.rehash()
     return block
Beispiel #17
0
    def mine_block(self, node, vtx=None, mn_payee=None, mn_amount=None, use_mnmerkleroot_from_tip=False, expected_error=None):
        if vtx is None:
            vtx = []
        bt = node.getblocktemplate({'rules': ['segwit']})
        height = bt['height']
        tip_hash = bt['previousblockhash']

        tip_block = node.getblock(tip_hash, 2)["tx"][0]

        coinbasevalue = 50 * COIN
        halvings = int(height / 150)  # regtest
        coinbasevalue >>= halvings

        miner_script = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())['scriptPubKey']
        if mn_payee is None:
            if isinstance(bt['masternode'], list):
                mn_payee = bt['masternode'][0]['script']
            else:
                mn_payee = bt['masternode']['script']
        # we can't take the masternode payee amount from the template here as we might have additional fees in vtx
        new_fees = 0
        for tx in vtx:
            in_value = 0
            out_value = 0
            for txin in tx.vin:
                txout = node.gettxout("%064x" % txin.prevout.hash, txin.prevout.n, False)
                in_value += int(txout['value'] * COIN)
            for txout in tx.vout:
                out_value += txout.nValue
            new_fees += in_value - out_value


        if mn_amount is None:
            mn_amount = get_masternode_payment(height, coinbasevalue, bt['masternode_collateral_height']) + new_fees/2
        miner_amount = int(coinbasevalue*0.25)
        miner_amount += new_fees/2

        coinbase = CTransaction()
        coinbase.vout.append(CTxOut(int(miner_amount), bytes.fromhex(miner_script)))
        coinbase.vout.append(CTxOut(int(mn_amount), bytes.fromhex(mn_payee)))
        coinbase.vin = create_coinbase(height).vin

        # Recreate mn root as using one in BT would result in invalid merkle roots for masternode lists
        coinbase.nVersion = bt['version_coinbase']
        if len(bt['default_witness_commitment_extra']) != 0:
            if use_mnmerkleroot_from_tip:
                cbtx = from_hex(CCbTx(version=2), bt['default_witness_commitment_extra'])
                if 'cbTx' in tip_block:
                    cbtx.merkleRootMNList = int(tip_block['cbTx']['merkleRootMNList'], 16)
                else:
                    cbtx.merkleRootMNList = 0
                coinbase.extraData = cbtx.serialize()
            else:
                coinbase.extraData = bytes.fromhex(bt['default_witness_commitment_extra'])

        coinbase.calc_sha256(with_witness=True)

        block = create_block(int(tip_hash, 16), coinbase)
        block.nVersion = 4
        block.vtx += vtx
        block.hashMerkleRoot = block.calc_merkle_root()
        add_witness_commitment(block)
        block.solve()
        result = node.submitblock(block.serialize().hex())
        if expected_error is not None and result != expected_error:
            raise AssertionError('mining the block should have failed with error %s, but submitblock returned %s' % (expected_error, result))
        elif expected_error is None and result is not None:
            raise AssertionError('submitblock returned %s' % (result))
Beispiel #18
0
    def run_test(self):
        miniwallet = MiniWallet(self.nodes[0])
        # Add enough mature utxos to the wallet, so that all txs spend confirmed coins
        self.generate(miniwallet, 5)
        self.generate(self.nodes[0], COINBASE_MATURITY)
        self.sync_all()

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

        txid1 = miniwallet.send_self_transfer(from_node=self.nodes[0])['txid']
        txid2 = miniwallet.send_self_transfer(from_node=self.nodes[0])['txid']
        # This will raise an exception because the transaction is not yet in a block
        assert_raises_rpc_error(-5, "Transaction not yet in block",
                                self.nodes[0].gettxoutproof, [txid1])

        self.generate(self.nodes[0], 1)
        blockhash = self.nodes[0].getblockhash(chain_height + 1)

        txlist = []
        blocktxn = self.nodes[0].getblock(blockhash, True)["tx"]
        txlist.append(blocktxn[1])
        txlist.append(blocktxn[2])

        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof([txid1
                                                                        ])),
            [txid1])
        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid1, txid2])), txlist)
        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid1, txid2], blockhash)), txlist)

        txin_spent = miniwallet.get_utxo()  # Get the change from txid2
        tx3 = miniwallet.send_self_transfer(from_node=self.nodes[0],
                                            utxo_to_spend=txin_spent)
        txid3 = tx3['txid']
        self.generate(self.nodes[0], 1)
        self.sync_all()

        txid_spent = txin_spent["txid"]
        txid_unspent = txid1  # Input was change from txid2, so txid1 should be unspent

        # Invalid txids
        assert_raises_rpc_error(
            -8,
            "txid must be of length 64 (not 32, for '00000000000000000000000000000000')",
            self.nodes[0].gettxoutproof, ["00000000000000000000000000000000"],
            blockhash)
        assert_raises_rpc_error(
            -8,
            "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')",
            self.nodes[0].gettxoutproof, [
                "ZZZ0000000000000000000000000000000000000000000000000000000000000"
            ], blockhash)
        # Invalid blockhashes
        assert_raises_rpc_error(
            -8,
            "blockhash must be of length 64 (not 32, for '00000000000000000000000000000000')",
            self.nodes[0].gettxoutproof, [txid_spent],
            "00000000000000000000000000000000")
        assert_raises_rpc_error(
            -8,
            "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')",
            self.nodes[0].gettxoutproof, [txid_spent],
            "ZZZ0000000000000000000000000000000000000000000000000000000000000")
        # We can't find the block from a fully-spent tx
        assert_raises_rpc_error(-5, "Transaction not yet in block",
                                self.nodes[0].gettxoutproof, [txid_spent])
        # We can get the proof if we specify the block
        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid_spent], blockhash)), [txid_spent])
        # We can't get the proof if we specify a non-existent block
        assert_raises_rpc_error(
            -5, "Block not found", self.nodes[0].gettxoutproof, [txid_spent],
            "0000000000000000000000000000000000000000000000000000000000000000")
        # We can get the proof if the transaction is unspent
        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid_unspent])), [txid_unspent])
        # We can get the proof if we provide a list of transactions and one of them is unspent. The ordering of the list should not matter.
        assert_equal(
            sorted(self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid1, txid2]))), sorted(txlist))
        assert_equal(
            sorted(self.nodes[0].verifytxoutproof(self.nodes[0].gettxoutproof(
                [txid2, txid1]))), sorted(txlist))
        # We can always get a proof if we have a -txindex
        assert_equal(
            self.nodes[0].verifytxoutproof(self.nodes[1].gettxoutproof(
                [txid_spent])), [txid_spent])
        # We can't get a proof if we specify transactions from different blocks
        assert_raises_rpc_error(
            -5, "Not all transactions found in specified or retrieved block",
            self.nodes[0].gettxoutproof, [txid1, txid3])
        # Test empty list
        assert_raises_rpc_error(-8, "Parameter 'txids' cannot be empty",
                                self.nodes[0].gettxoutproof, [])
        # Test duplicate txid
        assert_raises_rpc_error(-8, 'Invalid parameter, duplicated txid',
                                self.nodes[0].gettxoutproof, [txid1, txid1])

        # Now we'll try tweaking a proof.
        proof = self.nodes[1].gettxoutproof([txid1, txid2])
        assert txid1 in self.nodes[0].verifytxoutproof(proof)
        assert txid2 in self.nodes[1].verifytxoutproof(proof)

        tweaked_proof = from_hex(CMerkleBlock(), proof)

        # Make sure that our serialization/deserialization is working
        assert txid1 in self.nodes[0].verifytxoutproof(
            tweaked_proof.serialize().hex())

        # Check to see if we can go up the merkle tree and pass this off as a
        # single-transaction block
        tweaked_proof.txn.nTransactions = 1
        tweaked_proof.txn.vHash = [tweaked_proof.header.hashMerkleRoot]
        tweaked_proof.txn.vBits = [True] + [False] * 7

        for n in self.nodes:
            assert not n.verifytxoutproof(tweaked_proof.serialize().hex())
Beispiel #19
0
    def test_getblocktxn_handler(self, test_node):
        node = self.nodes[0]
        # bitcoind will not send blocktxn responses for blocks whose height is
        # more than 10 blocks deep.
        MAX_GETBLOCKTXN_DEPTH = 10
        chain_height = node.getblockcount()
        current_height = chain_height
        while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH):
            block_hash = node.getblockhash(current_height)
            block = from_hex(CBlock(), node.getblock(block_hash, False))

            msg = msg_getblocktxn()
            msg.block_txn_request = BlockTransactionsRequest(
                int(block_hash, 16), [])
            num_to_request = random.randint(1, len(block.vtx))
            msg.block_txn_request.from_absolute(
                sorted(random.sample(range(len(block.vtx)), num_to_request)))
            test_node.send_message(msg)
            test_node.wait_until(lambda: "blocktxn" in test_node.last_message,
                                 timeout=10)

            [tx.calc_sha256() for tx in block.vtx]
            with p2p_lock:
                assert_equal(
                    test_node.last_message["blocktxn"].block_transactions.
                    blockhash, int(block_hash, 16))
                all_indices = msg.block_txn_request.to_absolute()
                for index in all_indices:
                    tx = test_node.last_message[
                        "blocktxn"].block_transactions.transactions.pop(0)
                    tx.calc_sha256()
                    assert_equal(tx.sha256, block.vtx[index].sha256)
                    # Check that the witness matches
                    assert_equal(tx.calc_sha256(True),
                                 block.vtx[index].calc_sha256(True))
                test_node.last_message.pop("blocktxn", None)
            current_height -= 1

        # Next request should send a full block response, as we're past the
        # allowed depth for a blocktxn response.
        block_hash = node.getblockhash(current_height)
        msg.block_txn_request = BlockTransactionsRequest(
            int(block_hash, 16), [0])
        with p2p_lock:
            test_node.last_message.pop("block", None)
            test_node.last_message.pop("blocktxn", None)
        test_node.send_and_ping(msg)
        with p2p_lock:
            test_node.last_message["block"].block.calc_sha256()
            assert_equal(test_node.last_message["block"].block.sha256,
                         int(block_hash, 16))
            assert "blocktxn" not in test_node.last_message

        # Request with out-of-bounds tx index results in disconnect
        bad_peer = self.nodes[0].add_p2p_connection(TestP2PConn())
        block_hash = node.getblockhash(chain_height)
        block = from_hex(CBlock(), node.getblock(block_hash, False))
        msg.block_txn_request = BlockTransactionsRequest(
            int(block_hash, 16), [len(block.vtx)])
        with node.assert_debug_log(
            ['getblocktxn with out-of-bounds tx indices']):
            bad_peer.send_message(msg)
        bad_peer.wait_for_disconnect()