Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

bip68-sequence.py 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2014-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 BIP68 implementation."""
  6. from test_framework.test_framework import BitcoinTestFramework
  7. from test_framework.util import *
  8. from test_framework.blocktools import *
  9. SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31)
  10. SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height)
  11. SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift
  12. SEQUENCE_LOCKTIME_MASK = 0x0000ffff
  13. # RPC error for non-BIP68 final transactions
  14. NOT_FINAL_ERROR = "64: non-BIP68-final"
  15. class BIP68Test(BitcoinTestFramework):
  16. def set_test_params(self):
  17. self.num_nodes = 2
  18. self.extra_args = [[], ["-acceptnonstdtxn=0"]]
  19. def run_test(self):
  20. self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
  21. # Generate some coins
  22. self.nodes[0].generate(110)
  23. self.log.info("Running test disable flag")
  24. self.test_disable_flag()
  25. self.log.info("Running test sequence-lock-confirmed-inputs")
  26. self.test_sequence_lock_confirmed_inputs()
  27. self.log.info("Running test sequence-lock-unconfirmed-inputs")
  28. self.test_sequence_lock_unconfirmed_inputs()
  29. self.log.info("Running test BIP68 not consensus before versionbits activation")
  30. self.test_bip68_not_consensus()
  31. self.log.info("Activating BIP68 (and 112/113)")
  32. self.activateCSV()
  33. self.log.info("Verifying nVersion=2 transactions are standard.")
  34. self.log.info("Note that nVersion=2 transactions are always standard (independent of BIP68 activation status).")
  35. self.test_version2_relay()
  36. self.log.info("Passed")
  37. # Test that BIP68 is not in effect if tx version is 1, or if
  38. # the first sequence bit is set.
  39. def test_disable_flag(self):
  40. # Create some unconfirmed inputs
  41. new_addr = self.nodes[0].getnewaddress()
  42. self.nodes[0].sendtoaddress(new_addr, 2) # send 2 BTC
  43. utxos = self.nodes[0].listunspent(0, 0)
  44. assert(len(utxos) > 0)
  45. utxo = utxos[0]
  46. tx1 = CTransaction()
  47. value = int(satoshi_round(utxo["amount"] - self.relayfee)*COIN)
  48. # Check that the disable flag disables relative locktime.
  49. # If sequence locks were used, this would require 1 block for the
  50. # input to mature.
  51. sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1
  52. tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)]
  53. tx1.vout = [CTxOut(value, CScript([b'a']))]
  54. tx1_signed = self.nodes[0].signrawtransaction(ToHex(tx1))["hex"]
  55. tx1_id = self.nodes[0].sendrawtransaction(tx1_signed)
  56. tx1_id = int(tx1_id, 16)
  57. # This transaction will enable sequence-locks, so this transaction should
  58. # fail
  59. tx2 = CTransaction()
  60. tx2.nVersion = 2
  61. sequence_value = sequence_value & 0x7fffffff
  62. tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)]
  63. tx2.vout = [CTxOut(int(value-self.relayfee*COIN), CScript([b'a']))]
  64. tx2.rehash()
  65. assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2))
  66. # Setting the version back down to 1 should disable the sequence lock,
  67. # so this should be accepted.
  68. tx2.nVersion = 1
  69. self.nodes[0].sendrawtransaction(ToHex(tx2))
  70. # Calculate the median time past of a prior block ("confirmations" before
  71. # the current tip).
  72. def get_median_time_past(self, confirmations):
  73. block_hash = self.nodes[0].getblockhash(self.nodes[0].getblockcount()-confirmations)
  74. return self.nodes[0].getblockheader(block_hash)["mediantime"]
  75. # Test that sequence locks are respected for transactions spending confirmed inputs.
  76. def test_sequence_lock_confirmed_inputs(self):
  77. # Create lots of confirmed utxos, and use them to generate lots of random
  78. # transactions.
  79. max_outputs = 50
  80. addresses = []
  81. while len(addresses) < max_outputs:
  82. addresses.append(self.nodes[0].getnewaddress())
  83. while len(self.nodes[0].listunspent()) < 200:
  84. import random
  85. random.shuffle(addresses)
  86. num_outputs = random.randint(1, max_outputs)
  87. outputs = {}
  88. for i in range(num_outputs):
  89. outputs[addresses[i]] = random.randint(1, 20)*0.01
  90. self.nodes[0].sendmany("", outputs)
  91. self.nodes[0].generate(1)
  92. utxos = self.nodes[0].listunspent()
  93. # Try creating a lot of random transactions.
  94. # Each time, choose a random number of inputs, and randomly set
  95. # some of those inputs to be sequence locked (and randomly choose
  96. # between height/time locking). Small random chance of making the locks
  97. # all pass.
  98. for i in range(400):
  99. # Randomly choose up to 10 inputs
  100. num_inputs = random.randint(1, 10)
  101. random.shuffle(utxos)
  102. # Track whether any sequence locks used should fail
  103. should_pass = True
  104. # Track whether this transaction was built with sequence locks
  105. using_sequence_locks = False
  106. tx = CTransaction()
  107. tx.nVersion = 2
  108. value = 0
  109. for j in range(num_inputs):
  110. sequence_value = 0xfffffffe # this disables sequence locks
  111. # 50% chance we enable sequence locks
  112. if random.randint(0,1):
  113. using_sequence_locks = True
  114. # 10% of the time, make the input sequence value pass
  115. input_will_pass = (random.randint(1,10) == 1)
  116. sequence_value = utxos[j]["confirmations"]
  117. if not input_will_pass:
  118. sequence_value += 1
  119. should_pass = False
  120. # Figure out what the median-time-past was for the confirmed input
  121. # Note that if an input has N confirmations, we're going back N blocks
  122. # from the tip so that we're looking up MTP of the block
  123. # PRIOR to the one the input appears in, as per the BIP68 spec.
  124. orig_time = self.get_median_time_past(utxos[j]["confirmations"])
  125. cur_time = self.get_median_time_past(0) # MTP of the tip
  126. # can only timelock this input if it's not too old -- otherwise use height
  127. can_time_lock = True
  128. if ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) >= SEQUENCE_LOCKTIME_MASK:
  129. can_time_lock = False
  130. # if time-lockable, then 50% chance we make this a time lock
  131. if random.randint(0,1) and can_time_lock:
  132. # Find first time-lock value that fails, or latest one that succeeds
  133. time_delta = sequence_value << SEQUENCE_LOCKTIME_GRANULARITY
  134. if input_will_pass and time_delta > cur_time - orig_time:
  135. sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)
  136. elif (not input_will_pass and time_delta <= cur_time - orig_time):
  137. sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)+1
  138. sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG
  139. tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value))
  140. value += utxos[j]["amount"]*COIN
  141. # Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output
  142. tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50
  143. tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a'])))
  144. rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"]
  145. if (using_sequence_locks and not should_pass):
  146. # This transaction should be rejected
  147. assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, rawtx)
  148. else:
  149. # This raw transaction should be accepted
  150. self.nodes[0].sendrawtransaction(rawtx)
  151. utxos = self.nodes[0].listunspent()
  152. # Test that sequence locks on unconfirmed inputs must have nSequence
  153. # height or time of 0 to be accepted.
  154. # Then test that BIP68-invalid transactions are removed from the mempool
  155. # after a reorg.
  156. def test_sequence_lock_unconfirmed_inputs(self):
  157. # Store height so we can easily reset the chain at the end of the test
  158. cur_height = self.nodes[0].getblockcount()
  159. # Create a mempool tx.
  160. txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2)
  161. tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid))
  162. tx1.rehash()
  163. # Anyone-can-spend mempool tx.
  164. # Sequence lock of 0 should pass.
  165. tx2 = CTransaction()
  166. tx2.nVersion = 2
  167. tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
  168. tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
  169. tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
  170. tx2 = FromHex(tx2, tx2_raw)
  171. tx2.rehash()
  172. self.nodes[0].sendrawtransaction(tx2_raw)
  173. # Create a spend of the 0th output of orig_tx with a sequence lock
  174. # of 1, and test what happens when submitting.
  175. # orig_tx.vout[0] must be an anyone-can-spend output
  176. def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock):
  177. sequence_value = 1
  178. if not use_height_lock:
  179. sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG
  180. tx = CTransaction()
  181. tx.nVersion = 2
  182. tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)]
  183. tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee*COIN), CScript([b'a']))]
  184. tx.rehash()
  185. if (orig_tx.hash in node.getrawmempool()):
  186. # sendrawtransaction should fail if the tx is in the mempool
  187. assert_raises_rpc_error(-26, NOT_FINAL_ERROR, node.sendrawtransaction, ToHex(tx))
  188. else:
  189. # sendrawtransaction should succeed if the tx is not in the mempool
  190. node.sendrawtransaction(ToHex(tx))
  191. return tx
  192. test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True)
  193. test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
  194. # Now mine some blocks, but make sure tx2 doesn't get mined.
  195. # Use prioritisetransaction to lower the effective feerate to 0
  196. self.nodes[0].prioritisetransaction(txid=tx2.hash, fee_delta=int(-self.relayfee*COIN))
  197. cur_time = int(time.time())
  198. for i in range(10):
  199. self.nodes[0].setmocktime(cur_time + 600)
  200. self.nodes[0].generate(1)
  201. cur_time += 600
  202. assert(tx2.hash in self.nodes[0].getrawmempool())
  203. test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True)
  204. test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
  205. # Mine tx2, and then try again
  206. self.nodes[0].prioritisetransaction(txid=tx2.hash, fee_delta=int(self.relayfee*COIN))
  207. # Advance the time on the node so that we can test timelocks
  208. self.nodes[0].setmocktime(cur_time+600)
  209. self.nodes[0].generate(1)
  210. assert(tx2.hash not in self.nodes[0].getrawmempool())
  211. # Now that tx2 is not in the mempool, a sequence locked spend should
  212. # succeed
  213. tx3 = test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
  214. assert(tx3.hash in self.nodes[0].getrawmempool())
  215. self.nodes[0].generate(1)
  216. assert(tx3.hash not in self.nodes[0].getrawmempool())
  217. # One more test, this time using height locks
  218. tx4 = test_nonzero_locks(tx3, self.nodes[0], self.relayfee, use_height_lock=True)
  219. assert(tx4.hash in self.nodes[0].getrawmempool())
  220. # Now try combining confirmed and unconfirmed inputs
  221. tx5 = test_nonzero_locks(tx4, self.nodes[0], self.relayfee, use_height_lock=True)
  222. assert(tx5.hash not in self.nodes[0].getrawmempool())
  223. utxos = self.nodes[0].listunspent()
  224. tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1))
  225. tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN)
  226. raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"]
  227. assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, raw_tx5)
  228. # Test mempool-BIP68 consistency after reorg
  229. #
  230. # State of the transactions in the last blocks:
  231. # ... -> [ tx2 ] -> [ tx3 ]
  232. # tip-1 tip
  233. # And currently tx4 is in the mempool.
  234. #
  235. # If we invalidate the tip, tx3 should get added to the mempool, causing
  236. # tx4 to be removed (fails sequence-lock).
  237. self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
  238. assert(tx4.hash not in self.nodes[0].getrawmempool())
  239. assert(tx3.hash in self.nodes[0].getrawmempool())
  240. # Now mine 2 empty blocks to reorg out the current tip (labeled tip-1 in
  241. # diagram above).
  242. # This would cause tx2 to be added back to the mempool, which in turn causes
  243. # tx3 to be removed.
  244. tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16)
  245. height = self.nodes[0].getblockcount()
  246. for i in range(2):
  247. block = create_block(tip, create_coinbase(height), cur_time)
  248. block.nVersion = 3
  249. block.rehash()
  250. block.solve()
  251. tip = block.sha256
  252. height += 1
  253. self.nodes[0].submitblock(ToHex(block))
  254. cur_time += 1
  255. mempool = self.nodes[0].getrawmempool()
  256. assert(tx3.hash not in mempool)
  257. assert(tx2.hash in mempool)
  258. # Reset the chain and get rid of the mocktimed-blocks
  259. self.nodes[0].setmocktime(0)
  260. self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1))
  261. self.nodes[0].generate(10)
  262. # Make sure that BIP68 isn't being used to validate blocks, prior to
  263. # versionbits activation. If more blocks are mined prior to this test
  264. # being run, then it's possible the test has activated the soft fork, and
  265. # this test should be moved to run earlier, or deleted.
  266. def test_bip68_not_consensus(self):
  267. assert(get_bip9_status(self.nodes[0], 'csv')['status'] != 'active')
  268. txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2)
  269. tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid))
  270. tx1.rehash()
  271. # Make an anyone-can-spend transaction
  272. tx2 = CTransaction()
  273. tx2.nVersion = 1
  274. tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
  275. tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
  276. # sign tx2
  277. tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
  278. tx2 = FromHex(tx2, tx2_raw)
  279. tx2.rehash()
  280. self.nodes[0].sendrawtransaction(ToHex(tx2))
  281. # Now make an invalid spend of tx2 according to BIP68
  282. sequence_value = 100 # 100 block relative locktime
  283. tx3 = CTransaction()
  284. tx3.nVersion = 2
  285. tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)]
  286. tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
  287. tx3.rehash()
  288. assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx3))
  289. # make a block that violates bip68; ensure that the tip updates
  290. tip = int(self.nodes[0].getbestblockhash(), 16)
  291. block = create_block(tip, create_coinbase(self.nodes[0].getblockcount()+1))
  292. block.nVersion = 3
  293. block.vtx.extend([tx1, tx2, tx3])
  294. block.hashMerkleRoot = block.calc_merkle_root()
  295. block.rehash()
  296. block.solve()
  297. self.nodes[0].submitblock(ToHex(block))
  298. assert_equal(self.nodes[0].getbestblockhash(), block.hash)
  299. def activateCSV(self):
  300. # activation should happen at block height 432 (3 periods)
  301. # getblockchaininfo will show CSV as active at block 431 (144 * 3 -1) since it's returning whether CSV is active for the next block.
  302. min_activation_height = 432
  303. height = self.nodes[0].getblockcount()
  304. assert_greater_than(min_activation_height - height, 2)
  305. self.nodes[0].generate(min_activation_height - height - 2)
  306. assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], "locked_in")
  307. self.nodes[0].generate(1)
  308. assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], "active")
  309. sync_blocks(self.nodes)
  310. # Use self.nodes[1] to test that version 2 transactions are standard.
  311. def test_version2_relay(self):
  312. inputs = [ ]
  313. outputs = { self.nodes[1].getnewaddress() : 1.0 }
  314. rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
  315. rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex']
  316. tx = FromHex(CTransaction(), rawtxfund)
  317. tx.nVersion = 2
  318. tx_signed = self.nodes[1].signrawtransaction(ToHex(tx))["hex"]
  319. tx_id = self.nodes[1].sendrawtransaction(tx_signed)
  320. if __name__ == '__main__':
  321. BIP68Test().main()