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)
def test_basic(self): # All messages are received in the same socket which means # that this test fails if the publishing order changes. # Note that the publishing order is not defined in the documentation and # is subject to change. import zmq # Invalid zmq arguments don't take down the node, see #17185. self.restart_node(0, ["-zmqpubrawtx=foo", "-zmqpubhashtx=bar"]) address = 'tcp://127.0.0.1:28332' socket = self.ctx.socket(zmq.SUB) socket.set(zmq.RCVTIMEO, 60000) # Subscribe to all available topics. hashblock = ZMQSubscriber(socket, b"hashblock") hashtx = ZMQSubscriber(socket, b"hashtx") rawblock = ZMQSubscriber(socket, b"rawblock") rawtx = ZMQSubscriber(socket, b"rawtx") self.restart_node(0, ["-zmqpub%s=%s" % (sub.topic.decode(), address) for sub in [hashblock, hashtx, rawblock, rawtx]]) connect_nodes(self.nodes[0], 1) socket.connect(address) # Relax so that the subscriber is ready before publishing zmq messages sleep(0.2) num_blocks = 5 self.log.info("Generate %(n)d blocks (and %(n)d coinbase txes)" % {"n": num_blocks}) genhashes = self.nodes[0].generatetoaddress(num_blocks, ADDRESS_BCRT1_UNSPENDABLE) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = hashtx.receive() # Should receive the coinbase raw transaction. hex = rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, txid.hex()) # Should receive the generated block hash. hash = hashblock.receive().hex() assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([txid.hex()], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = rawblock.receive() f = BytesIO(block) header = CBlockHeader() header.deserialize(f) header.rehash() assert_equal(genhashes[x], header.hash) if self.is_wallet_compiled(): self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = hashtx.receive() assert_equal(payment_txid, txid.hex()) # Should receive the broadcasted raw transaction. hex = rawtx.receive() assert_equal(payment_txid, hash256_reversed(hex).hex()) self.log.info("Test the getzmqnotifications RPC") assert_equal(self.nodes[0].getzmqnotifications(), [ {"type": "pubhashblock", "address": address, "hwm": 1000}, {"type": "pubhashtx", "address": address, "hwm": 1000}, {"type": "pubrawblock", "address": address, "hwm": 1000}, {"type": "pubrawtx", "address": address, "hwm": 1000}, ]) assert_equal(self.nodes[1].getzmqnotifications(), [])
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)