You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

zmq_test.py 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2015-2016 The Starwels developers
  3. # Distributed under the MIT software license, see the accompanying
  4. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. """Test the ZMQ API."""
  6. import configparser
  7. import os
  8. import struct
  9. from test_framework.test_framework import StarwelsTestFramework, SkipTest
  10. from test_framework.util import (assert_equal,
  11. bytes_to_hex_str,
  12. hash256,
  13. )
  14. class ZMQTest (StarwelsTestFramework):
  15. def set_test_params(self):
  16. self.num_nodes = 2
  17. def setup_nodes(self):
  18. # Try to import python3-zmq. Skip this test if the import fails.
  19. try:
  20. import zmq
  21. except ImportError:
  22. raise SkipTest("python3-zmq module not available.")
  23. # Check that starwels has been built with ZMQ enabled
  24. config = configparser.ConfigParser()
  25. if not self.options.configfile:
  26. self.options.configfile = os.path.dirname(__file__) + "/../config.ini"
  27. config.read_file(open(self.options.configfile))
  28. if not config["components"].getboolean("ENABLE_ZMQ"):
  29. raise SkipTest("starwelsd has not been built with zmq enabled.")
  30. self.zmqContext = zmq.Context()
  31. self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
  32. self.zmqSubSocket.set(zmq.RCVTIMEO, 60000)
  33. self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock")
  34. self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx")
  35. self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawblock")
  36. self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtx")
  37. ip_address = "tcp://127.0.0.1:28352"
  38. self.zmqSubSocket.connect(ip_address)
  39. self.extra_args = [['-zmqpubhashblock=%s' % ip_address, '-zmqpubhashtx=%s' % ip_address,
  40. '-zmqpubrawblock=%s' % ip_address, '-zmqpubrawtx=%s' % ip_address], []]
  41. self.add_nodes(self.num_nodes, self.extra_args)
  42. self.start_nodes()
  43. def run_test(self):
  44. try:
  45. self._zmq_test()
  46. finally:
  47. # Destroy the zmq context
  48. self.log.debug("Destroying zmq context")
  49. self.zmqContext.destroy(linger=None)
  50. def _zmq_test(self):
  51. genhashes = self.nodes[0].generate(1)
  52. self.sync_all()
  53. self.log.info("Wait for tx")
  54. msg = self.zmqSubSocket.recv_multipart()
  55. topic = msg[0]
  56. assert_equal(topic, b"hashtx")
  57. txhash = msg[1]
  58. msgSequence = struct.unpack('<I', msg[-1])[-1]
  59. assert_equal(msgSequence, 0) # must be sequence 0 on hashtx
  60. # rawtx
  61. msg = self.zmqSubSocket.recv_multipart()
  62. topic = msg[0]
  63. assert_equal(topic, b"rawtx")
  64. body = msg[1]
  65. msgSequence = struct.unpack('<I', msg[-1])[-1]
  66. assert_equal(msgSequence, 0) # must be sequence 0 on rawtx
  67. # Check that the rawtx hashes to the hashtx
  68. assert_equal(hash256(body), txhash)
  69. self.log.info("Wait for block")
  70. msg = self.zmqSubSocket.recv_multipart()
  71. topic = msg[0]
  72. assert_equal(topic, b"hashblock")
  73. body = msg[1]
  74. msgSequence = struct.unpack('<I', msg[-1])[-1]
  75. assert_equal(msgSequence, 0) # must be sequence 0 on hashblock
  76. blkhash = bytes_to_hex_str(body)
  77. assert_equal(genhashes[0], blkhash) # blockhash from generate must be equal to the hash received over zmq
  78. # rawblock
  79. msg = self.zmqSubSocket.recv_multipart()
  80. topic = msg[0]
  81. assert_equal(topic, b"rawblock")
  82. body = msg[1]
  83. msgSequence = struct.unpack('<I', msg[-1])[-1]
  84. assert_equal(msgSequence, 0) #must be sequence 0 on rawblock
  85. # Check the hash of the rawblock's header matches generate
  86. assert_equal(genhashes[0], bytes_to_hex_str(hash256(body[:80])))
  87. self.log.info("Generate 10 blocks (and 10 coinbase txes)")
  88. n = 10
  89. genhashes = self.nodes[1].generate(n)
  90. self.sync_all()
  91. zmqHashes = []
  92. zmqRawHashed = []
  93. blockcount = 0
  94. for x in range(n * 4):
  95. msg = self.zmqSubSocket.recv_multipart()
  96. topic = msg[0]
  97. body = msg[1]
  98. if topic == b"hashblock":
  99. zmqHashes.append(bytes_to_hex_str(body))
  100. msgSequence = struct.unpack('<I', msg[-1])[-1]
  101. assert_equal(msgSequence, blockcount + 1)
  102. blockcount += 1
  103. if topic == b"rawblock":
  104. zmqRawHashed.append(bytes_to_hex_str(hash256(body[:80])))
  105. msgSequence = struct.unpack('<I', msg[-1])[-1]
  106. assert_equal(msgSequence, blockcount)
  107. for x in range(n):
  108. assert_equal(genhashes[x], zmqHashes[x]) # blockhash from generate must be equal to the hash received over zmq
  109. assert_equal(genhashes[x], zmqRawHashed[x])
  110. self.log.info("Wait for tx from second node")
  111. # test tx from a second node
  112. hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0)
  113. self.sync_all()
  114. # now we should receive a zmq msg because the tx was broadcast
  115. msg = self.zmqSubSocket.recv_multipart()
  116. topic = msg[0]
  117. assert_equal(topic, b"hashtx")
  118. body = msg[1]
  119. hashZMQ = bytes_to_hex_str(body)
  120. msgSequence = struct.unpack('<I', msg[-1])[-1]
  121. assert_equal(msgSequence, blockcount + 1)
  122. msg = self.zmqSubSocket.recv_multipart()
  123. topic = msg[0]
  124. assert_equal(topic, b"rawtx")
  125. body = msg[1]
  126. hashedZMQ = bytes_to_hex_str(hash256(body))
  127. msgSequence = struct.unpack('<I', msg[-1])[-1]
  128. assert_equal(msgSequence, blockcount+1)
  129. assert_equal(hashRPC, hashZMQ) # txid from sendtoaddress must be equal to the hash received over zmq
  130. assert_equal(hashRPC, hashedZMQ)
  131. if __name__ == '__main__':
  132. ZMQTest().main()