Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

txn_doublespend.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/env python2
  2. # Copyright (c) 2014 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. #
  6. # Test proper accounting with malleable transactions
  7. #
  8. from test_framework import BitcoinTestFramework
  9. from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
  10. from decimal import Decimal
  11. from util import *
  12. import os
  13. import shutil
  14. class TxnMallTest(BitcoinTestFramework):
  15. def add_options(self, parser):
  16. parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true",
  17. help="Test double-spend of 1-confirmed transaction")
  18. def setup_network(self):
  19. # Start with split network:
  20. return super(TxnMallTest, self).setup_network(True)
  21. def run_test(self):
  22. # All nodes should start with 1,250 BTC:
  23. starting_balance = 1250
  24. for i in range(4):
  25. assert_equal(self.nodes[i].getbalance(), starting_balance)
  26. self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
  27. # Assign coins to foo and bar accounts:
  28. self.nodes[0].move("", "foo", 1220)
  29. self.nodes[0].move("", "bar", 30)
  30. assert_equal(self.nodes[0].getbalance(""), 0)
  31. # Coins are sent to node1_address
  32. node1_address = self.nodes[1].getnewaddress("from0")
  33. # First: use raw transaction API to send 1210 BTC to node1_address,
  34. # but don't broadcast:
  35. (total_in, inputs) = gather_inputs(self.nodes[0], 1210)
  36. change_address = self.nodes[0].getnewaddress("foo")
  37. outputs = {}
  38. outputs[change_address] = 40
  39. outputs[node1_address] = 1210
  40. rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
  41. doublespend = self.nodes[0].signrawtransaction(rawtx)
  42. assert_equal(doublespend["complete"], True)
  43. # Create two transaction from node[0] to node[1]; the
  44. # second must spend change from the first because the first
  45. # spends all mature inputs:
  46. txid1 = self.nodes[0].sendfrom("foo", node1_address, 1210, 0)
  47. txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0)
  48. # Have node0 mine a block:
  49. if (self.options.mine_block):
  50. self.nodes[0].setgenerate(True, 1)
  51. sync_blocks(self.nodes[0:2])
  52. tx1 = self.nodes[0].gettransaction(txid1)
  53. tx2 = self.nodes[0].gettransaction(txid2)
  54. # Node0's balance should be starting balance, plus 50BTC for another
  55. # matured block, minus 1210, minus 20, and minus transaction fees:
  56. expected = starting_balance
  57. if self.options.mine_block: expected += 50
  58. expected += tx1["amount"] + tx1["fee"]
  59. expected += tx2["amount"] + tx2["fee"]
  60. assert_equal(self.nodes[0].getbalance(), expected)
  61. # foo and bar accounts should be debited:
  62. assert_equal(self.nodes[0].getbalance("foo"), 1220+tx1["amount"]+tx1["fee"])
  63. assert_equal(self.nodes[0].getbalance("bar"), 30+tx2["amount"]+tx2["fee"])
  64. if self.options.mine_block:
  65. assert_equal(tx1["confirmations"], 1)
  66. assert_equal(tx2["confirmations"], 1)
  67. # Node1's "from0" balance should be both transaction amounts:
  68. assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"]))
  69. else:
  70. assert_equal(tx1["confirmations"], 0)
  71. assert_equal(tx2["confirmations"], 0)
  72. # Now give doublespend to miner:
  73. mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"])
  74. # ... mine a block...
  75. self.nodes[2].setgenerate(True, 1)
  76. # Reconnect the split network, and sync chain:
  77. connect_nodes(self.nodes[1], 2)
  78. self.nodes[2].setgenerate(True, 1) # Mine another block to make sure we sync
  79. sync_blocks(self.nodes)
  80. # Re-fetch transaction info:
  81. tx1 = self.nodes[0].gettransaction(txid1)
  82. tx2 = self.nodes[0].gettransaction(txid2)
  83. # Both transactions should be conflicted
  84. assert_equal(tx1["confirmations"], -1)
  85. assert_equal(tx2["confirmations"], -1)
  86. # Node0's total balance should be starting balance, plus 100BTC for
  87. # two more matured blocks, minus 1210 for the double-spend:
  88. expected = starting_balance + 100 - 1210
  89. assert_equal(self.nodes[0].getbalance(), expected)
  90. assert_equal(self.nodes[0].getbalance("*"), expected)
  91. # foo account should be debited, but bar account should not:
  92. assert_equal(self.nodes[0].getbalance("foo"), 1220-1210)
  93. assert_equal(self.nodes[0].getbalance("bar"), 30)
  94. # Node1's "from" account balance should be just the mutated send:
  95. assert_equal(self.nodes[1].getbalance("from0"), 1210)
  96. if __name__ == '__main__':
  97. TxnMallTest().main()