Esempio n. 1
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises_jsonrpc(-5, "Block not found",
                              node.getblockheader, "nonsense")

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)
        header = node.getblockheader(besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_is_hex_string(header['chainwork'])
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonceUint32'], int)
        assert_is_hash_string(header['nonce'], length=None)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)
Esempio n. 2
0
    def _test_getblockheader(self):
        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(199)
        header = node.getblockheader(blockhash=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)
Esempio n. 3
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises(
            JSONRPCException, lambda: node.getblockheader('nonsense'))

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(COINBASE_MATURITY+100-1)
        header = node.getblockheader(besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], COINBASE_MATURITY+100)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_is_hex_string(header['chainwork'])
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)
Esempio n. 4
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "nonsense")

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)
        header = node.getblockheader(besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_is_hex_string(header['chainwork'])
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)
Esempio n. 5
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises(JSONRPCException,
                      lambda: node.getblockheader('nonsense'))

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)
        header = node.getblockheader(besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_is_hex_string(header['chainwork'])
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(header['difficulty'], Decimal)
Esempio n. 6
0
    def _test_getblockheader(self):
        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(199)
        header = node.getblockheader(blockhash=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        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 isinstance(header['time'], int)
        assert isinstance(header['mediantime'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)

        # 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 = FromHex(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())
Esempio n. 7
0
    def generate_block_with_parent(self,
                                   parent_hash: str,
                                   referee: list = [],
                                   num_txs: int = 0,
                                   adaptive: bool = False,
                                   difficulty=None,
                                   pos_reference=None) -> str:
        assert_is_hash_string(parent_hash)

        for r in referee:
            assert_is_hash_string(r)

        assert_greater_than_or_equal(num_txs, 0)
        # print(parent_hash)
        block_hash = self.node.generatefixedblock(parent_hash, referee,
                                                  num_txs, adaptive,
                                                  difficulty, pos_reference)
        assert_is_hash_string(block_hash)
        return block_hash
Esempio n. 8
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises_rpc_error(-5, "Block not found", node.getblockheader,
                                "nonsense")

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(99)
        header = node.getblockheader(besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 100)
        assert_equal(header['confirmations'], 1)
        assert_equal(header['previousblockhash'], secondbesthash)
        assert_equal(header['nTx'], 1)
        assert_is_hash_string(header['hash'])
        assert_is_hash_string(header['previousblockhash'])
        assert_is_hash_string(header['merkleroot'])
        assert isinstance(header['time'], int)
        assert isinstance(header['mediantime'], int)
        assert isinstance(header['features'], int)
        assert isinstance(int(header['featuresHex'], 16), int)
Esempio n. 9
0
    def _test_getblockheader(self):
        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(199)
        header = node.getblockheader(blockhash=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        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 isinstance(header['time'], int)
        assert isinstance(header['mediantime'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
Esempio n. 10
0
 def generate_block(self, num_txs: int = 0,
                    block_size_limit_bytes: int = default_config["MAX_BLOCK_SIZE_IN_BYTES"]) -> str:
     assert_greater_than_or_equal(num_txs, 0)
     block_hash = self.node.generateoneblock(num_txs, block_size_limit_bytes)
     assert_is_hash_string(block_hash)
     return block_hash
Esempio n. 11
0
    def run_test(self):
        self.nodes[0].importaddress(ADDRESS_WATCHONLY)
        # Check that nodes don't own any UTXOs
        assert_equal(len(self.nodes[0].listunspent()), 0)
        assert_equal(len(self.nodes[1].listunspent()), 0)

        self.log.info("Check that only node 0 is watching an address")
        assert 'watchonly' in self.nodes[0].getbalances()
        assert 'watchonly' not in self.nodes[1].getbalances()

        self.log.info("Mining blocks ...")
        self.nodes[0].generate(1)
        self.sync_all()
        self.nodes[1].generate(1)
        self.nodes[1].generatetoaddress(101, ADDRESS_WATCHONLY)
        self.sync_all()

        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], 50)
        assert_equal(self.nodes[0].getwalletinfo()['balance'], 50)
        assert_equal(self.nodes[1].getbalances()['mine']['trusted'], 50)

        assert_equal(self.nodes[0].getbalances()['watchonly']['immature'], 5000)
        assert 'watchonly' not in self.nodes[1].getbalances()

        assert_equal(self.nodes[0].getbalance(), 50)
        assert_equal(self.nodes[1].getbalance(), 50)

        self.log.info("Test getbalance with different arguments")
        assert_equal(self.nodes[0].getbalance("*"), 50)
        assert_equal(self.nodes[0].getbalance("*", 1), 50)
        assert_equal(self.nodes[0].getbalance("*", 1, True), 100)
        assert_raises_rpc_error(-8, "getbalance minconf option is only currently supported if dummy is set to \"*\"", self.nodes[0].getbalance, minconf=1)
        assert_raises_rpc_error(-8, "getbalance minconf option is only currently supported if dummy is set to \"*\"", self.nodes[0].getbalance, minconf=0, include_watchonly=True)
        assert_raises_rpc_error(-8, "getbalance minconf option is only currently supported if dummy is set to \"*\"", self.nodes[1].getbalance, minconf=0, include_watchonly=True)

        # Send 40 BTC from 0 to 1 and 60 BTC from 1 to 0.
        txs = create_transactions(self.nodes[0], self.nodes[1].getnewaddress(), 40, [Decimal('0.01')])
        self.nodes[0].sendrawtransaction(txs[0]['hex'])
        self.nodes[1].sendrawtransaction(txs[0]['hex'])  # sending on both nodes is faster than waiting for propagation

        self.sync_all()
        txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress(), 60, [Decimal('0.01'), Decimal('0.02')])
        self.nodes[1].sendrawtransaction(txs[0]['hex'])
        self.nodes[0].sendrawtransaction(txs[0]['hex'])  # sending on both nodes is faster than waiting for propagation
        self.sync_all()

        # First argument of getbalance must be set to "*"
        assert_raises_rpc_error(-32, "dummy first argument must be excluded or set to \"*\"", self.nodes[1].getbalance, "")

        self.log.info("Test getbalance and getunconfirmedbalance with unconfirmed inputs")

        # Before `test_balance()`, we have had two nodes with a balance of 50
        # each and then we:
        #
        # 1) Sent 40 from node A to node B with fee 0.01
        # 2) Sent 60 from node B to node A with fee 0.01
        #
        # Then we check the balances:
        #
        # 1) As is
        # 2) With transaction 2 from above with 2x the fee
        #
        # Prior to #16766, in this situation, the node would immediately report
        # a balance of 30 on node B as unconfirmed and trusted.
        #
        # After #16766, we show that balance as unconfirmed.
        #
        # The balance is indeed "trusted" and "confirmed" insofar as removing
        # the mempool transactions would return at least that much money. But
        # the algorithm after #16766 marks it as unconfirmed because the 'taint'
        # tracking of transaction trust for summing balances doesn't consider
        # which inputs belong to a user. In this case, the change output in
        # question could be "destroyed" by replace the 1st transaction above.
        #
        # The post #16766 behavior is correct; we shouldn't be treating those
        # funds as confirmed. If you want to rely on that specific UTXO existing
        # which has given you that balance, you cannot, as a third party
        # spending the other input would destroy that unconfirmed.
        #
        # For example, if the test transactions were:
        #
        # 1) Sent 40 from node A to node B with fee 0.01
        # 2) Sent 10 from node B to node A with fee 0.01
        #
        # Then our node would report a confirmed balance of 40 + 50 - 10 = 80
        # BTC, which is more than would be available if transaction 1 were
        # replaced.


        def test_balances(*, fee_node_1=0):
            # getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions
            assert_equal(self.nodes[0].getbalance(), Decimal('9.99'))  # change from node 0's send
            assert_equal(self.nodes[1].getbalance(), Decimal('0'))  # node 1's send had an unsafe input
            # getbalance with '*' and minconf=0 includes unconfirmed transactions, AND untrusted transactions
            assert_equal(self.nodes[0].getbalance('*', 0), Decimal('69.99'))
            assert_equal(self.nodes[1].getbalance('*', 0), Decimal('30') - fee_node_1)
            # getbalance with '*' and minconf=1 includes only confirmed and sent transactions
            assert_equal(self.nodes[0].getbalance('*', 1), Decimal('9.99'))
            assert_equal(self.nodes[1].getbalance('*', 1), Decimal('-10') - fee_node_1)
            # getunconfirmedbalance
            assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('60'))  # output of node 1's spend
            assert_equal(self.nodes[0].getbalances()['mine']['untrusted_pending'], Decimal('60'))
            assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], Decimal('60'))

            assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('30') - fee_node_1)  # Doesn't include output of node 0's send since it was spent
            assert_equal(self.nodes[1].getbalances()['mine']['untrusted_pending'], Decimal('30') - fee_node_1)
            assert_equal(self.nodes[1].getwalletinfo()["unconfirmed_balance"], Decimal('30') - fee_node_1)

        test_balances(fee_node_1=Decimal('0.01'))

        # Node 1 bumps the transaction fee and resends
        self.nodes[1].sendrawtransaction(txs[1]['hex'])
        self.nodes[0].sendrawtransaction(txs[1]['hex'])  # sending on both nodes is faster than waiting for propagation
        self.sync_all()

        self.log.info("Test getbalance and getunconfirmedbalance with conflicted unconfirmed inputs")
        test_balances(fee_node_1=Decimal('0.02'))

        self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
        self.sync_all()

        # balances are correct after the transactions are confirmed
        assert_equal(self.nodes[0].getbalance(), Decimal('69.99'))  # node 1's send plus change from node 0's send
        assert_equal(self.nodes[1].getbalance(), Decimal('29.98'))  # change from node 0's send

        # Send total balance away from node 1
        txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress(), Decimal('29.97'), [Decimal('0.01')])
        self.nodes[1].sendrawtransaction(txs[0]['hex'])
        self.nodes[1].generatetoaddress(2, ADDRESS_WATCHONLY)
        self.sync_all()

        # check mempool transactions count for wallet unconfirmed balance after
        # dynamically loading the wallet.
        before = self.nodes[1].getunconfirmedbalance()
        dst = self.nodes[1].getnewaddress()
        self.nodes[1].unloadwallet('')
        self.nodes[0].sendtoaddress(dst, 0.1)
        self.sync_all()
        self.nodes[1].loadwallet('')
        after = self.nodes[1].getunconfirmedbalance()
        assert_equal(before + Decimal('0.1'), after)

        # Create 3 more wallet txs, where the last is not accepted to the
        # mempool because it is the third descendant of the tx above
        for _ in range(3):
            # Set amount high enough such that all coins are spent by each tx
            txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 99)

        self.log.info('Check that wallet txs not in the mempool are untrusted')
        assert txid not in self.nodes[0].getrawmempool()
        assert_equal(self.nodes[0].gettransaction(txid)['trusted'], False)
        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], 0)

        self.log.info("Test replacement and reorg of non-mempool tx")
        tx_orig = self.nodes[0].gettransaction(txid)['hex']
        # Increase fee by 1 coin
        tx_replace = tx_orig.replace(
            struct.pack("<q", 99 * 10**8).hex(),
            struct.pack("<q", 98 * 10**8).hex(),
        )
        tx_replace = self.nodes[0].signrawtransactionwithwallet(tx_replace)['hex']
        # Total balance is given by the sum of outputs of the tx
        total_amount = sum([o['value'] for o in self.nodes[0].decoderawtransaction(tx_replace)['vout']])
        self.sync_all()
        self.nodes[1].sendrawtransaction(hexstring=tx_replace, maxfeerate=0)

        # Now confirm tx_replace
        block_reorg = self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)[0]
        self.sync_all()
        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], total_amount)

        self.log.info('Put txs back into mempool of node 1 (not node 0)')
        self.nodes[0].invalidateblock(block_reorg)
        self.nodes[1].invalidateblock(block_reorg)
        self.sync_blocks()
        self.nodes[0].syncwithvalidationinterfacequeue()
        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], 0)  # wallet txs not in the mempool are untrusted
        self.nodes[0].generatetoaddress(1, ADDRESS_WATCHONLY)
        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], 0)  # wallet txs not in the mempool are untrusted

        # Now confirm tx_orig
        self.restart_node(1, ['-persistmempool=0'])
        connect_nodes(self.nodes[0], 1)
        sync_blocks(self.nodes)
        self.nodes[1].sendrawtransaction(tx_orig)
        self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
        self.sync_all()
        assert_equal(self.nodes[0].getbalances()['mine']['trusted'], total_amount + 1)  # The reorg recovered our fee of 1 coin


        #Tests the lastprocessedblock JSON object in getbalances, getwalletinfo
        #and gettransaction by checking for valid hex strings and by comparing
        #the hashes & heights between generated blocks.
        self.log.info("Test getbalances returns expected lastprocessedblock json object")
        self.nodes[0].generatetoaddress(2, self.nodes[0].get_deterministic_priv_key().address)
        balances = self.nodes[0].getbalances()
        assert_greater_than(balances['mine']['immature'], 0)

        prev_hash = self.nodes[0].getbestblockhash()
        prev_height = self.nodes[0].getblock(prev_hash)['height']
        self.nodes[0].generatetoaddress(5, self.nodes[0].get_deterministic_priv_key().address)
        lastblock = self.nodes[0].getbalances()['lastprocessedblock']
        assert_is_hash_string(lastblock['hash'])
        assert_equal((prev_hash == lastblock['hash']), False)
        assert_greater_than(lastblock['height'], prev_height)

        self.log.info("Test getwalletinfo returns expected lastprocessedblock json object")
        walletinfo = self.nodes[0].getwalletinfo()
        assert_greater_than(walletinfo['lastprocessedblock']['height'], 0)
        assert_is_hash_string(walletinfo['lastprocessedblock']['hash'])

        self.log.info("Test gettransaction returns expected lastprocessedblock json object")
        txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
        self.nodes[0].generatetoaddress(6, self.nodes[0].get_deterministic_priv_key().address)
        tx_info = self.nodes[0].gettransaction(txid)
        assert_is_hash_string(tx_info['lastprocessedblock']['hash'])
Esempio n. 12
0
 def ensure_generate_block(node, txs):
     block_hash = RpcClient(node).generate_block(txs)
     assert_is_hash_string(block_hash)
Esempio n. 13
0
    def big_test(self):
        self.log.info("Running big test!")
        n0, n1 = self.nodes[0], self.nodes[1]

        self.log.info("Calling issue()...")
        address0 = n0.getnewaddress()
        ipfs_hash = "QmcvyefkqQX3PpjpY5L8B2yMd47XrVwAipr6cxUt2zvYU8"
        n0.issue(asset_name="MY_ASSET", qty=1000, to_address=address0, change_address="",
                 units=4, reissuable=True, has_ipfs=True, ipfs_hash=ipfs_hash)

        self.log.info("Waiting for ten confirmations after issue...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checkout getassetdata()...")
        assetdata = n0.getassetdata("MY_ASSET")
        assert_equal(assetdata["name"], "MY_ASSET")
        assert_equal(assetdata["amount"], 1000)
        assert_equal(assetdata["units"], 4)
        assert_equal(assetdata["reissuable"], 1)
        assert_equal(assetdata["has_ipfs"], 1)
        assert_equal(assetdata["ipfs_hash"], ipfs_hash)

        self.log.info("Checking listmyassets()...")
        myassets = n0.listmyassets(asset="MY_ASSET*", verbose=True)
        assert_equal(len(myassets), 2)
        asset_names = list(myassets.keys())
        assert_equal(asset_names.count("MY_ASSET"), 1)
        assert_equal(asset_names.count("MY_ASSET!"), 1)
        assert_equal(myassets["MY_ASSET"]["balance"], 1000)
        assert_equal(myassets["MY_ASSET!"]["balance"], 1)
        assert_equal(len(myassets["MY_ASSET"]["outpoints"]), 1)
        assert_equal(len(myassets["MY_ASSET!"]["outpoints"]), 1)
        assert_is_hash_string(myassets["MY_ASSET"]["outpoints"][0]["txid"])
        assert_equal(myassets["MY_ASSET"]["outpoints"][0]["txid"], myassets["MY_ASSET!"]["outpoints"][0]["txid"])
        assert (int(myassets["MY_ASSET"]["outpoints"][0]["vout"]) >= 0)
        assert (int(myassets["MY_ASSET!"]["outpoints"][0]["vout"]) >= 0)
        assert_equal(myassets["MY_ASSET"]["outpoints"][0]["amount"], 1000)
        assert_equal(myassets["MY_ASSET!"]["outpoints"][0]["amount"], 1)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET"], 1000)
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET!"], 1)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n0.listaddressesbyasset("MY_ASSET"), n1.listaddressesbyasset("MY_ASSET"))

        self.log.info("Calling transfer()...")
        address1 = n1.getnewaddress()
        n0.transfer(asset_name="MY_ASSET", qty=200, to_address=address1)

        self.log.info("Waiting for ten confirmations after transfer...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checking listmyassets()...")
        myassets = n1.listmyassets(asset="MY_ASSET*", verbose=True)
        assert_equal(len(myassets), 1)
        asset_names = list(myassets.keys())
        assert_equal(asset_names.count("MY_ASSET"), 1)
        assert_equal(asset_names.count("MY_ASSET!"), 0)
        assert_equal(myassets["MY_ASSET"]["balance"], 200)
        assert_equal(len(myassets["MY_ASSET"]["outpoints"]), 1)
        assert_is_hash_string(myassets["MY_ASSET"]["outpoints"][0]["txid"])
        assert (int(myassets["MY_ASSET"]["outpoints"][0]["vout"]) >= 0)
        assert_equal(n0.listmyassets(asset="MY_ASSET")["MY_ASSET"], 800)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n1.listassetbalancesbyaddress(address1)["MY_ASSET"], 200)
        changeaddress = None
        assert_equal(n0.listaddressesbyasset("MY_ASSET"), n1.listaddressesbyasset("MY_ASSET"))
        assert_equal(sum(n0.listaddressesbyasset("MY_ASSET").values()), 1000)
        assert_equal(sum(n1.listaddressesbyasset("MY_ASSET").values()), 1000)
        for assaddr in n0.listaddressesbyasset("MY_ASSET").keys():
            if n0.validateaddress(assaddr)["ismine"]:
                changeaddress = assaddr
                assert_equal(n0.listassetbalancesbyaddress(changeaddress)["MY_ASSET"], 800)
        assert (changeaddress is not None)
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET!"], 1)

        self.log.info("Burning all units to test reissue on zero units...")
        n0.transfer(asset_name="MY_ASSET", qty=800, to_address="n1BurnXXXXXXXXXXXXXXXXXXXXXXU1qejP")
        n0.generate(1)
        assert_does_not_contain_key("MY_ASSET", n0.listmyassets(asset="MY_ASSET", verbose=True))

        self.log.info("Calling reissue()...")
        address1 = n0.getnewaddress()
        ipfs_hash2 = "QmcvyefkqQX3PpjpY5L8B2yMd47XrVwAipr6cxUt2zvYU8"
        n0.reissue(asset_name="MY_ASSET", qty=2000, to_address=address0, change_address=address1, reissuable=False, new_units=-1, new_ipfs=ipfs_hash2)

        self.log.info("Waiting for ten confirmations after reissue...")
        self.sync_all()
        n0.generate(10)
        self.sync_all()

        self.log.info("Checkout getassetdata()...")
        assetdata = n0.getassetdata("MY_ASSET")
        assert_equal(assetdata["name"], "MY_ASSET")
        assert_equal(assetdata["amount"], 3000)
        assert_equal(assetdata["units"], 4)
        assert_equal(assetdata["reissuable"], 0)
        assert_equal(assetdata["has_ipfs"], 1)
        assert_equal(assetdata["ipfs_hash"], ipfs_hash2)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET"], 2000)

        self.log.info("Checking listassets()...")
        n0.issue("RAVEN1", 1000)
        n0.issue("RAVEN2", 1000)
        n0.issue("RAVEN3", 1000)
        n0.generate(1)
        self.sync_all()

        n0.listassets(asset="RAVEN*", verbose=False, count=2, start=-2)

        self.log.info("Creating some sub-assets...")
        n0.issue(asset_name="MY_ASSET/SUB1", qty=1000, to_address=address0, change_address=address0, units=4, reissuable=True, has_ipfs=True, ipfs_hash=ipfs_hash)

        self.sync_all()
        self.log.info("Waiting for ten confirmations after issuesubasset...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checkout getassetdata()...")
        assetdata = n0.getassetdata("MY_ASSET/SUB1")
        assert_equal(assetdata["name"], "MY_ASSET/SUB1")
        assert_equal(assetdata["amount"], 1000)
        assert_equal(assetdata["units"], 4)
        assert_equal(assetdata["reissuable"], 1)
        assert_equal(assetdata["has_ipfs"], 1)
        assert_equal(assetdata["ipfs_hash"], ipfs_hash)

        splendid_assets = n0.listassets(asset="RAVEN*", verbose=False, count=2, start=-2)
        assert_equal(len(splendid_assets), 2)
        assert_equal(splendid_assets[0], "RAVEN2")
        assert_equal(splendid_assets[1], "RAVEN3")
        self.sync_all()
Esempio n. 14
0
 def get_transaction_receipt(self, tx_hash: str) -> dict:
     assert_is_hash_string(tx_hash)
     return self.node.cfx_getTransactionReceipt(tx_hash)
Esempio n. 15
0
 def block_hashes_by_epoch(self, epoch: str) -> list:
     blocks = self.node.cfx_getBlocksByEpoch(epoch)
     for b in blocks:
         assert_is_hash_string(b)
     return blocks
Esempio n. 16
0
    def run_test(self):
        self.log.info("Running test!")

        n0, n1, n2 = self.nodes[0], self.nodes[1], self.nodes[2]

        self.log.info("Generating XSR for node[0] and activating assets...")
        n0.generate(1)
        self.sync_all()
        n2.generate(431)
        self.sync_all()
        assert_equal(n0.getbalance(), 5000)

        self.log.info("Calling issue()...")
        address0 = n0.getnewaddress()
        ipfs_hash = "QmacSRmrkVmvJfbCpmU6pK72furJ8E8fbKHindrLxmYMQo"
        n0.issue(asset_name="MY_ASSET", qty=1000, to_address=address0, change_address="",\
                 units=4, reissuable=True, has_ipfs=True, ipfs_hash=ipfs_hash)

        self.log.info("Waiting for ten confirmations after issue...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checkout getassetdata()...")
        assetdata = n0.getassetdata("MY_ASSET")
        assert_equal(assetdata["name"], "MY_ASSET")
        assert_equal(assetdata["amount"], 1000)
        assert_equal(assetdata["units"], 4)
        assert_equal(assetdata["reissuable"], 1)
        assert_equal(assetdata["has_ipfs"], 1)
        assert_equal(assetdata["ipfs_hash"], ipfs_hash)

        self.log.info("Checking listmyassets()...")
        myassets = n0.listmyassets(asset="MY_ASSET*", verbose=True)
        assert_equal(len(myassets), 2)
        asset_names = list(myassets.keys())
        assert_equal(asset_names.count("MY_ASSET"), 1)
        assert_equal(asset_names.count("MY_ASSET!"), 1)
        assert_equal(myassets["MY_ASSET"]["balance"], 1000)
        assert_equal(myassets["MY_ASSET!"]["balance"], 1)
        assert_equal(len(myassets["MY_ASSET"]["outpoints"]), 1)
        assert_equal(len(myassets["MY_ASSET!"]["outpoints"]), 1)
        assert_is_hash_string(myassets["MY_ASSET"]["outpoints"][0]["txid"])
        assert_equal(myassets["MY_ASSET"]["outpoints"][0]["txid"], \
                     myassets["MY_ASSET!"]["outpoints"][0]["txid"])
        assert (int(myassets["MY_ASSET"]["outpoints"][0]["vout"]) >= 0)
        assert (int(myassets["MY_ASSET!"]["outpoints"][0]["vout"]) >= 0)
        assert_equal(myassets["MY_ASSET"]["outpoints"][0]["amount"], 1000)
        assert_equal(myassets["MY_ASSET!"]["outpoints"][0]["amount"], 1)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET"], 1000)
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET!"], 1)

        self.log.info("Calling transfer()...")
        address1 = n1.getnewaddress()
        n0.transfer(asset_name="MY_ASSET", qty=200, to_address=address1)

        self.log.info("Waiting for ten confirmations after transfer...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checking listmyassets()...")
        myassets = n1.listmyassets(asset="MY_ASSET*", verbose=True)
        assert_equal(len(myassets), 1)
        asset_names = list(myassets.keys())
        assert_equal(asset_names.count("MY_ASSET"), 1)
        assert_equal(asset_names.count("MY_ASSET!"), 0)
        assert_equal(myassets["MY_ASSET"]["balance"], 200)
        assert_equal(len(myassets["MY_ASSET"]["outpoints"]), 1)
        assert_is_hash_string(myassets["MY_ASSET"]["outpoints"][0]["txid"])
        assert (int(myassets["MY_ASSET"]["outpoints"][0]["vout"]) >= 0)
        assert_equal(n0.listmyassets(asset="MY_ASSET")["MY_ASSET"], 800)

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n1.listassetbalancesbyaddress(address1)["MY_ASSET"], 200)
        changeaddress = None
        for assaddr in n0.listaddressesbyasset("MY_ASSET").keys():
            if n0.validateaddress(assaddr)["ismine"] == True:
                changeaddress = assaddr
                assert_equal(
                    n0.listassetbalancesbyaddress(changeaddress)["MY_ASSET"],
                    800)
        assert (changeaddress != None)
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET!"], 1)

        self.log.info("Calling reissue()...")
        n0.reissue(asset_name="MY_ASSET", qty=2000, to_address=address0, change_address="",\
                   reissuable=False, new_ipfs=ipfs_hash[::-1])

        self.log.info("Waiting for ten confirmations after reissue...")
        n0.generate(10)
        self.sync_all()

        self.log.info("Checkout getassetdata()...")
        assetdata = n0.getassetdata("MY_ASSET")
        assert_equal(assetdata["name"], "MY_ASSET")
        assert_equal(assetdata["amount"], 3000)
        assert_equal(assetdata["units"], 4)
        assert_equal(assetdata["reissuable"], 0)
        assert_equal(assetdata["has_ipfs"], 1)
        assert_equal(assetdata["ipfs_hash"], ipfs_hash[::-1])

        self.log.info("Checking listassetbalancesbyaddress()...")
        assert_equal(n0.listassetbalancesbyaddress(address0)["MY_ASSET"], 2000)

        self.log.info("Checking listassets()...")
        n0.issue("SUCRECOIN1", 1000)
        n0.issue("SUCRECOIN2", 1000)
        n0.issue("SUCRECOIN3", 1000)
        n0.generate(10)
        self.sync_all()

        sucrecoin_assets = n0.listassets(asset="SUCRECOIN*",
                                         verbose=False,
                                         count=2,
                                         start=-2)
        assert_equal(len(sucrecoin_assets), 2)
        assert_equal(sucrecoin_assets[0], "SUCRECOIN2")
        assert_equal(sucrecoin_assets[1], "SUCRECOIN3")
Esempio n. 17
0
    def _test_getblockbyheight(self):
        node = self.nodes[0]
        assert_raises_rpc_error(-5, "Block not found", node.getblockheader,
                                "nonsense")

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)

        self.log.info("Test getblockbyheight with verbosity=0")
        blockhex = node.getblockbyheight(1, 0)
        assert_is_hex_string(blockhex)
        self.log.info("Test getblockbyheight with verbosity=RAW_BLOCK")
        blockhex = node.getblockbyheight(1, "RAW_BLOCK")
        assert_is_hex_string(blockhex)
        self.log.info("Test getblockbyheight with verbosity=RaW_BlocK")
        blockhex = node.getblockbyheight(1, "RaW_BlocK")
        assert_is_hex_string(blockhex)

        self.log.info("Test getblockbyheight with verbosity=1")
        blockjson = node.getblockbyheight(200, 1)
        assert_equal(blockjson['hash'], besthash)
        assert_equal(blockjson['height'], 200)
        assert_equal(blockjson['confirmations'], 1)
        assert_equal(blockjson['previousblockhash'], secondbesthash)
        assert_is_hex_string(blockjson['chainwork'])
        assert_is_hash_string(blockjson['hash'])
        assert_is_hash_string(blockjson['previousblockhash'])
        assert_is_hash_string(blockjson['merkleroot'])
        assert_is_hash_string(blockjson['bits'], length=None)
        assert isinstance(blockjson['time'], int)
        assert isinstance(blockjson['mediantime'], int)
        assert isinstance(blockjson['nonce'], int)
        assert isinstance(blockjson['version'], int)
        assert isinstance(int(blockjson['versionHex'], 16), int)
        assert isinstance(blockjson['difficulty'], Decimal)
        assert isinstance(blockjson['tx'], list)
        for tx in blockjson['tx']:
            assert_is_hash_string(tx)

        self.log.info("Test getblockbyheight with verbosity=DECODE_HEADER")
        blockjson = node.getblockbyheight(200, "DECODE_HEADER")
        assert_equal(blockjson['hash'], besthash)
        for tx in blockjson['tx']:
            assert_is_hash_string(tx)

        self.log.info("Test getblockbyheight with verbosity=2")
        blockjson = node.getblockbyheight(200, 2)
        assert_equal(blockjson['hash'], besthash)
        assert_equal(blockjson['height'], 200)
        assert_equal(blockjson['confirmations'], 1)
        assert_equal(blockjson['previousblockhash'], secondbesthash)
        assert_is_hex_string(blockjson['chainwork'])
        assert_is_hash_string(blockjson['hash'])
        assert_is_hash_string(blockjson['previousblockhash'])
        assert_is_hash_string(blockjson['merkleroot'])
        assert_is_hash_string(blockjson['bits'], length=None)
        assert isinstance(blockjson['time'], int)
        assert isinstance(blockjson['mediantime'], int)
        assert isinstance(blockjson['nonce'], int)
        assert isinstance(blockjson['version'], int)
        assert isinstance(int(blockjson['versionHex'], 16), int)
        assert isinstance(blockjson['difficulty'], Decimal)
        for tx in blockjson['tx']:
            assert isinstance(tx, dict)

        self.log.info(
            "Test getblockbyheight with verbosity=DECODE_TRANSACTIONS")
        blockjson = node.getblockbyheight(200, "DECODE_TRANSACTIONS")
        assert_equal(blockjson['hash'], besthash)
        for tx in blockjson['tx']:
            assert isinstance(tx, dict)

        self.log.info("Test getblockbyheight with verbosity=3")
        blockjson = node.getblockbyheight(200, 3)
        assert_equal(blockjson['hash'], besthash)
        assert_equal(blockjson['height'], 200)
        assert_equal(blockjson['confirmations'], 1)
        assert_equal(blockjson['previousblockhash'], secondbesthash)
        assert_is_hex_string(blockjson['chainwork'])
        assert_is_hash_string(blockjson['hash'])
        assert_is_hash_string(blockjson['previousblockhash'])
        assert_is_hash_string(blockjson['merkleroot'])
        assert_is_hash_string(blockjson['bits'], length=None)
        assert isinstance(blockjson['time'], int)
        assert isinstance(blockjson['mediantime'], int)
        assert isinstance(blockjson['nonce'], int)
        assert isinstance(blockjson['version'], int)
        assert isinstance(int(blockjson['versionHex'], 16), int)
        assert isinstance(blockjson['difficulty'], Decimal)
        #only coinbase tx should be in block
        assert_equal(len(blockjson['tx']), 1)
        tx = blockjson['tx'][0]
        assert isinstance(tx, dict)
        assert_is_hash_string(tx['vin'][0]['coinbase'], length=None)

        self.log.info(
            "Test getblockbyheight with verbosity=DECODE_HEADER_AND_COINBASE")
        blockjson = node.getblockbyheight(200, "DECODE_HEADER_AND_COINBASE")
        assert_equal(blockjson['hash'], besthash)
        #only coinbase tx should be in block
        assert_equal(len(blockjson['tx']), 1)
        tx = blockjson['tx'][0]
        assert isinstance(tx, dict)
        assert_is_hash_string(tx['vin'][0]['coinbase'], length=None)

        self.log.info("Test getblock with invalid verbosity fails")
        assert_raises_rpc_error(-8, "Verbosity value out of range",
                                node.getblockbyheight, 200, 4)
        assert_raises_rpc_error(-8, "Verbosity value out of range",
                                node.getblockbyheight, 200, -1)
        assert_raises_rpc_error(-8, "Verbosity value not recognized",
                                node.getblockbyheight, 200, "ASDFG")
        assert_raises_rpc_error(-8, "Block height out of range",
                                node.getblockbyheight, -1)
        assert_raises_rpc_error(-8, "Block height out of range",
                                node.getblockbyheight, 300)
Esempio n. 18
0
 def send_raw_tx(self, raw_tx: str) -> str:
     tx_hash = self.node.cfx_sendRawTransaction(raw_tx)
     assert_is_hash_string(tx_hash)
     return tx_hash
Esempio n. 19
0
 def get_code(self, address: str, epoch: str) -> str:
     assert_is_hash_string(address, length=40)
     code = self.node.cfx_getCode(address, epoch)
     assert_is_hex_string(code)
     return code
Esempio n. 20
0
 def generate_block_with_fake_txs(self, txs: list, adaptive=False, tx_data_len: int = 0) -> str:
     encoded_txs = eth_utils.encode_hex(rlp.encode(txs))
     block_hash = self.node.test_generateblockwithfaketxs(encoded_txs, adaptive, tx_data_len)
     assert_is_hash_string(block_hash)
     return block_hash
Esempio n. 21
0
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises_rpc_error(
            -8, "hash_or_height must be of length 64 (not 8, for 'nonsense')",
            node.getblockheader, "nonsense")
        assert_raises_rpc_error(
            -8,
            "hash_or_height must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')",
            node.getblockheader,
            "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
        assert_raises_rpc_error(
            -5, "Block not found", node.getblockheader,
            "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
        assert_raises_rpc_error(
            -8, "Target block height 201 after current tip 200",
            node.getblockheader, 201)
        assert_raises_rpc_error(-8, "Target block height -10 is negative",
                                node.getblockheader, -10)

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)
        header = node.getblockheader(hash_or_height=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)

        header_by_height = node.getblockheader(hash_or_height=200)
        assert_equal(header, header_by_height)

        # Next, check that the old alias 'blockhash' still works
        # and is interchangeable with hash_or_height
        # First, make sure errors work as expected for unknown named params
        self.log.info(
            "Testing that getblockheader(blockhashhh=\"HEX\") produces the proper error"
        )
        assert_raises_rpc_error(-8,
                                "Unknown named parameter blockhashhh",
                                node.getblockheader,
                                blockhashhh=header['hash'])
        # Next, actually try the old legacy blockhash="xx" style arg
        self.log.info(
            "Testing that legacy getblockheader(blockhash=\"HEX\") still works ok"
        )
        header_by_hash2 = node.getblockheader(blockhash=header['hash'])
        assert_equal(header, header_by_hash2)
        header_by_height2 = node.getblockheader(blockhash=200)
        assert_equal(header, header_by_height2)

        # check that we actually get a hex string back from getblockheader
        # if verbose is set to false.
        header_verbose_false = node.getblockheader(200, False)
        assert not isinstance(header_verbose_false, dict)
        assert isinstance(header_verbose_false, str)
        assert (c in string.hexdigits for c in header_verbose_false)
        assert_is_hex_string(header_verbose_false)

        # check that header_verbose_false is the same header we get via
        # getblockheader(hash_or_height=besthash) just in a different "form"
        h = CBlockHeader()
        h.deserialize(BytesIO(hex_str_to_bytes(header_verbose_false)))
        h.calc_sha256()

        assert_equal(header['version'], h.nVersion)
        assert_equal(header['time'], h.nTime)
        assert_equal(header['previousblockhash'],
                     "{:064x}".format(h.hashPrevBlock))
        assert_equal(header['merkleroot'], "{:064x}".format(h.hashMerkleRoot))
        assert_equal(header['hash'], h.hash)

        # check that we get the same header by hash and by height in
        # the case verbose is set to False
        header_verbose_false_by_hash = node.getblockheader(besthash, False)
        assert_equal(header_verbose_false_by_hash, header_verbose_false)
Esempio n. 22
0
 def generate_block(self, num_txs: int = 0) -> str:
     assert_greater_than_or_equal(num_txs, 0)
     block_hash = self.node.generateoneblock(num_txs)
     assert_is_hash_string(block_hash)
     return block_hash
    def _test_getblockheader(self):
        node = self.nodes[0]

        assert_raises_rpc_error(
            -8, "hash_or_height must be of length 64 (not 8, for 'nonsense')",
            node.getblockheader, "nonsense")
        assert_raises_rpc_error(
            -8,
            "hash_or_height must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')",
            node.getblockheader,
            "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
        assert_raises_rpc_error(
            -5, "Block not found", node.getblockheader,
            "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
        assert_raises_rpc_error(
            -8, "Target block height 201 after current tip 200",
            node.getblockheader, 201)
        assert_raises_rpc_error(-8, "Target block height -10 is negative",
                                node.getblockheader, -10)

        besthash = node.getbestblockhash()
        secondbesthash = node.getblockhash(199)
        header = node.getblockheader(hash_or_height=besthash)

        assert_equal(header['hash'], besthash)
        assert_equal(header['height'], 200)
        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 isinstance(header['mediantime'], int)
        assert isinstance(header['nonce'], int)
        assert isinstance(header['version'], int)
        assert isinstance(int(header['versionHex'], 16), int)
        assert isinstance(header['difficulty'], Decimal)

        header_by_height = node.getblockheader(hash_or_height=200)
        assert_equal(header, header_by_height)

        # check that we actually get a hex string back from getblockheader
        # if verbose is set to false.
        header_verbose_false = node.getblockheader(200, False)
        assert not isinstance(header_verbose_false, dict)
        assert isinstance(header_verbose_false, str)
        assert (c in string.hexdigits for c in header_verbose_false)
        assert_is_hex_string(header_verbose_false)

        # check that header_verbose_false is the same header we get via
        # getblockheader(hash_or_height=besthash) just in a different "form"
        h = CBlockHeader()
        h.deserialize(BytesIO(hex_str_to_bytes(header_verbose_false)))
        h.calc_sha256()

        assert_equal(header['version'], h.nVersion)
        assert_equal(header['time'], h.nTime)
        assert_equal(header['previousblockhash'],
                     "{:064x}".format(h.hashPrevBlock))
        assert_equal(header['merkleroot'], "{:064x}".format(h.hashMerkleRoot))
        assert_equal(header['hash'], h.hash)

        # check that we get the same header by hash and by height in
        # the case verbose is set to False
        header_verbose_false_by_hash = node.getblockheader(besthash, False)
        assert_equal(header_verbose_false_by_hash, header_verbose_false)