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.

bipdersig-p2p.py 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2015-2016 The Bitcoin Core 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 BIP66 (DER SIG).
  6. Connect to a single node.
  7. Mine 2 (version 2) blocks (save the coinbases for later).
  8. Generate 98 more version 2 blocks, verify the node accepts.
  9. Mine 749 version 3 blocks, verify the node accepts.
  10. Check that the new DERSIG rules are not enforced on the 750th version 3 block.
  11. Check that the new DERSIG rules are enforced on the 751st version 3 block.
  12. Mine 199 new version blocks.
  13. Mine 1 old-version block.
  14. Mine 1 new version block.
  15. Mine 1 old version block, see that the node rejects.
  16. """
  17. from test_framework.test_framework import ComparisonTestFramework
  18. from test_framework.util import *
  19. from test_framework.mininode import CTransaction, NetworkThread
  20. from test_framework.blocktools import create_coinbase, create_block
  21. from test_framework.comptool import TestInstance, TestManager
  22. from test_framework.script import CScript
  23. from io import BytesIO
  24. import time
  25. # A canonical signature consists of:
  26. # <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
  27. def unDERify(tx):
  28. """
  29. Make the signature in vin 0 of a tx non-DER-compliant,
  30. by adding padding after the S-value.
  31. """
  32. scriptSig = CScript(tx.vin[0].scriptSig)
  33. newscript = []
  34. for i in scriptSig:
  35. if (len(newscript) == 0):
  36. newscript.append(i[0:-1] + b'\0' + i[-1:])
  37. else:
  38. newscript.append(i)
  39. tx.vin[0].scriptSig = CScript(newscript)
  40. class BIP66Test(ComparisonTestFramework):
  41. def __init__(self):
  42. super().__init__()
  43. self.num_nodes = 1
  44. def setup_network(self):
  45. # Must set the blockversion for this test
  46. self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
  47. extra_args=[['-whitelist=127.0.0.1', '-blockversion=2']],
  48. binary=[self.options.testbinary])
  49. def run_test(self):
  50. test = TestManager(self, self.options.tmpdir)
  51. test.add_all_connections(self.nodes)
  52. NetworkThread().start() # Start up network handling in another thread
  53. test.run()
  54. def create_transaction(self, node, coinbase, to_address, amount):
  55. from_txid = node.getblock(coinbase)['tx'][0]
  56. inputs = [{ "txid" : from_txid, "vout" : 0}]
  57. outputs = { to_address : amount }
  58. rawtx = node.createrawtransaction(inputs, outputs)
  59. signresult = node.signrawtransaction(rawtx)
  60. tx = CTransaction()
  61. f = BytesIO(hex_str_to_bytes(signresult['hex']))
  62. tx.deserialize(f)
  63. return tx
  64. def get_tests(self):
  65. self.coinbase_blocks = self.nodes[0].generate(2)
  66. height = 3 # height of the next block to build
  67. self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
  68. self.nodeaddress = self.nodes[0].getnewaddress()
  69. self.last_block_time = int(time.time())
  70. ''' 298 more version 2 blocks '''
  71. test_blocks = []
  72. for i in range(298):
  73. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  74. block.nVersion = 2
  75. block.rehash()
  76. block.solve()
  77. test_blocks.append([block, True])
  78. self.last_block_time += 1
  79. self.tip = block.sha256
  80. height += 1
  81. yield TestInstance(test_blocks, sync_every_block=False)
  82. ''' Mine 749 version 3 blocks '''
  83. test_blocks = []
  84. for i in range(749):
  85. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  86. block.nVersion = 3
  87. block.rehash()
  88. block.solve()
  89. test_blocks.append([block, True])
  90. self.last_block_time += 1
  91. self.tip = block.sha256
  92. height += 1
  93. yield TestInstance(test_blocks, sync_every_block=False)
  94. '''
  95. Check that the new DERSIG rules are not enforced in the 750th
  96. version 3 block.
  97. '''
  98. spendtx = self.create_transaction(self.nodes[0],
  99. self.coinbase_blocks[0], self.nodeaddress, 1.0)
  100. unDERify(spendtx)
  101. spendtx.rehash()
  102. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  103. block.nVersion = 3
  104. block.vtx.append(spendtx)
  105. block.hashMerkleRoot = block.calc_merkle_root()
  106. block.rehash()
  107. block.solve()
  108. self.last_block_time += 1
  109. self.tip = block.sha256
  110. height += 1
  111. yield TestInstance([[block, True]])
  112. ''' Mine 199 new version blocks on last valid tip '''
  113. test_blocks = []
  114. for i in range(199):
  115. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  116. block.nVersion = 3
  117. block.rehash()
  118. block.solve()
  119. test_blocks.append([block, True])
  120. self.last_block_time += 1
  121. self.tip = block.sha256
  122. height += 1
  123. yield TestInstance(test_blocks, sync_every_block=False)
  124. ''' Mine 1 old version block '''
  125. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  126. block.nVersion = 2
  127. block.rehash()
  128. block.solve()
  129. self.last_block_time += 1
  130. self.tip = block.sha256
  131. height += 1
  132. yield TestInstance([[block, True]])
  133. ''' Mine 1 new version block '''
  134. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  135. block.nVersion = 3
  136. block.rehash()
  137. block.solve()
  138. self.last_block_time += 1
  139. self.tip = block.sha256
  140. height += 1
  141. yield TestInstance([[block, True]])
  142. '''
  143. Check that the new DERSIG rules are enforced in the 951st version 3
  144. block.
  145. '''
  146. spendtx = self.create_transaction(self.nodes[0],
  147. self.coinbase_blocks[1], self.nodeaddress, 1.0)
  148. unDERify(spendtx)
  149. spendtx.rehash()
  150. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  151. block.nVersion = 3
  152. block.vtx.append(spendtx)
  153. block.hashMerkleRoot = block.calc_merkle_root()
  154. block.rehash()
  155. block.solve()
  156. self.last_block_time += 1
  157. yield TestInstance([[block, False]])
  158. ''' Mine 1 old version block, should be invalid '''
  159. block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
  160. block.nVersion = 2
  161. block.rehash()
  162. block.solve()
  163. self.last_block_time += 1
  164. yield TestInstance([[block, False]])
  165. if __name__ == '__main__':
  166. BIP66Test().main()