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.

fundrawtransaction.py 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  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 the fundrawtransaction RPC."""
  6. from test_framework.test_framework import BitcoinTestFramework
  7. from test_framework.util import *
  8. def get_unspent(listunspent, amount):
  9. for utx in listunspent:
  10. if utx['amount'] == amount:
  11. return utx
  12. raise AssertionError('Could not find unspent with amount={}'.format(amount))
  13. class RawTransactionsTest(BitcoinTestFramework):
  14. def __init__(self):
  15. super().__init__()
  16. self.setup_clean_chain = True
  17. self.num_nodes = 4
  18. def setup_network(self, split=False):
  19. self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
  20. connect_nodes_bi(self.nodes,0,1)
  21. connect_nodes_bi(self.nodes,1,2)
  22. connect_nodes_bi(self.nodes,0,2)
  23. connect_nodes_bi(self.nodes,0,3)
  24. self.is_network_split=False
  25. self.sync_all()
  26. def run_test(self):
  27. min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
  28. # This test is not meant to test fee estimation and we'd like
  29. # to be sure all txs are sent at a consistent desired feerate
  30. for node in self.nodes:
  31. node.settxfee(min_relay_tx_fee)
  32. # if the fee's positive delta is higher than this value tests will fail,
  33. # neg. delta always fail the tests.
  34. # The size of the signature of every input may be at most 2 bytes larger
  35. # than a minimum sized signature.
  36. # = 2 bytes * minRelayTxFeePerByte
  37. feeTolerance = 2 * min_relay_tx_fee/1000
  38. self.nodes[2].generate(1)
  39. self.sync_all()
  40. self.nodes[0].generate(121)
  41. self.sync_all()
  42. watchonly_address = self.nodes[0].getnewaddress()
  43. watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
  44. watchonly_amount = Decimal(200)
  45. self.nodes[3].importpubkey(watchonly_pubkey, "", True)
  46. watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
  47. self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
  48. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5)
  49. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
  50. self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0)
  51. self.nodes[0].generate(1)
  52. self.sync_all()
  53. ###############
  54. # simple test #
  55. ###############
  56. inputs = [ ]
  57. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  58. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  59. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  60. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  61. fee = rawtxfund['fee']
  62. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  63. assert(len(dec_tx['vin']) > 0) #test that we have enough inputs
  64. ##############################
  65. # simple test with two coins #
  66. ##############################
  67. inputs = [ ]
  68. outputs = { self.nodes[0].getnewaddress() : 2.2 }
  69. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  70. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  71. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  72. fee = rawtxfund['fee']
  73. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  74. assert(len(dec_tx['vin']) > 0) #test if we have enough inputs
  75. ##############################
  76. # simple test with two coins #
  77. ##############################
  78. inputs = [ ]
  79. outputs = { self.nodes[0].getnewaddress() : 2.6 }
  80. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  81. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  82. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  83. fee = rawtxfund['fee']
  84. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  85. assert(len(dec_tx['vin']) > 0)
  86. assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
  87. ################################
  88. # simple test with two outputs #
  89. ################################
  90. inputs = [ ]
  91. outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 }
  92. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  93. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  94. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  95. fee = rawtxfund['fee']
  96. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  97. totalOut = 0
  98. for out in dec_tx['vout']:
  99. totalOut += out['value']
  100. assert(len(dec_tx['vin']) > 0)
  101. assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
  102. #########################################################################
  103. # test a fundrawtransaction with a VIN greater than the required amount #
  104. #########################################################################
  105. utx = get_unspent(self.nodes[2].listunspent(), 5)
  106. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  107. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  108. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  109. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  110. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  111. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  112. fee = rawtxfund['fee']
  113. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  114. totalOut = 0
  115. for out in dec_tx['vout']:
  116. totalOut += out['value']
  117. assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
  118. #####################################################################
  119. # test a fundrawtransaction with which will not get a change output #
  120. #####################################################################
  121. utx = get_unspent(self.nodes[2].listunspent(), 5)
  122. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  123. outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
  124. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  125. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  126. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  127. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  128. fee = rawtxfund['fee']
  129. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  130. totalOut = 0
  131. for out in dec_tx['vout']:
  132. totalOut += out['value']
  133. assert_equal(rawtxfund['changepos'], -1)
  134. assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
  135. ####################################################
  136. # test a fundrawtransaction with an invalid option #
  137. ####################################################
  138. utx = get_unspent(self.nodes[2].listunspent(), 5)
  139. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
  140. outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
  141. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  142. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  143. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  144. assert_raises_jsonrpc(-3, "Unexpected key foo", self.nodes[2].fundrawtransaction, rawtx, {'foo':'bar'})
  145. ############################################################
  146. # test a fundrawtransaction with an invalid change address #
  147. ############################################################
  148. utx = get_unspent(self.nodes[2].listunspent(), 5)
  149. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
  150. outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
  151. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  152. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  153. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  154. assert_raises_jsonrpc(-5, "changeAddress must be a valid bitcoin address", self.nodes[2].fundrawtransaction, rawtx, {'changeAddress':'foobar'})
  155. ############################################################
  156. # test a fundrawtransaction with a provided change address #
  157. ############################################################
  158. utx = get_unspent(self.nodes[2].listunspent(), 5)
  159. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
  160. outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
  161. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  162. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  163. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  164. change = self.nodes[2].getnewaddress()
  165. assert_raises_jsonrpc(-8, "changePosition out of bounds", self.nodes[2].fundrawtransaction, rawtx, {'changeAddress':change, 'changePosition':2})
  166. rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0})
  167. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  168. out = dec_tx['vout'][0]
  169. assert_equal(change, out['scriptPubKey']['addresses'][0])
  170. #########################################################################
  171. # test a fundrawtransaction with a VIN smaller than the required amount #
  172. #########################################################################
  173. utx = get_unspent(self.nodes[2].listunspent(), 1)
  174. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
  175. outputs = { self.nodes[0].getnewaddress() : 1.0 }
  176. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  177. # 4-byte version + 1-byte vin count + 36-byte prevout then script_len
  178. rawtx = rawtx[:82] + "0100" + rawtx[84:]
  179. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  180. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  181. assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
  182. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  183. fee = rawtxfund['fee']
  184. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  185. totalOut = 0
  186. matchingOuts = 0
  187. for i, out in enumerate(dec_tx['vout']):
  188. totalOut += out['value']
  189. if out['scriptPubKey']['addresses'][0] in outputs:
  190. matchingOuts+=1
  191. else:
  192. assert_equal(i, rawtxfund['changepos'])
  193. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  194. assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
  195. assert_equal(matchingOuts, 1)
  196. assert_equal(len(dec_tx['vout']), 2)
  197. ###########################################
  198. # test a fundrawtransaction with two VINs #
  199. ###########################################
  200. utx = get_unspent(self.nodes[2].listunspent(), 1)
  201. utx2 = get_unspent(self.nodes[2].listunspent(), 5)
  202. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
  203. outputs = { self.nodes[0].getnewaddress() : 6.0 }
  204. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  205. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  206. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  207. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  208. fee = rawtxfund['fee']
  209. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  210. totalOut = 0
  211. matchingOuts = 0
  212. for out in dec_tx['vout']:
  213. totalOut += out['value']
  214. if out['scriptPubKey']['addresses'][0] in outputs:
  215. matchingOuts+=1
  216. assert_equal(matchingOuts, 1)
  217. assert_equal(len(dec_tx['vout']), 2)
  218. matchingIns = 0
  219. for vinOut in dec_tx['vin']:
  220. for vinIn in inputs:
  221. if vinIn['txid'] == vinOut['txid']:
  222. matchingIns+=1
  223. assert_equal(matchingIns, 2) #we now must see two vins identical to vins given as params
  224. #########################################################
  225. # test a fundrawtransaction with two VINs and two vOUTs #
  226. #########################################################
  227. utx = get_unspent(self.nodes[2].listunspent(), 1)
  228. utx2 = get_unspent(self.nodes[2].listunspent(), 5)
  229. inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
  230. outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
  231. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  232. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  233. assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
  234. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  235. fee = rawtxfund['fee']
  236. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  237. totalOut = 0
  238. matchingOuts = 0
  239. for out in dec_tx['vout']:
  240. totalOut += out['value']
  241. if out['scriptPubKey']['addresses'][0] in outputs:
  242. matchingOuts+=1
  243. assert_equal(matchingOuts, 2)
  244. assert_equal(len(dec_tx['vout']), 3)
  245. ##############################################
  246. # test a fundrawtransaction with invalid vin #
  247. ##############################################
  248. listunspent = self.nodes[2].listunspent()
  249. inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin!
  250. outputs = { self.nodes[0].getnewaddress() : 1.0}
  251. rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
  252. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  253. assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx)
  254. ############################################################
  255. #compare fee of a standard pubkeyhash transaction
  256. inputs = []
  257. outputs = {self.nodes[1].getnewaddress():1.1}
  258. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  259. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  260. #create same transaction over sendtoaddress
  261. txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1)
  262. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  263. #compare fee
  264. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
  265. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  266. ############################################################
  267. ############################################################
  268. #compare fee of a standard pubkeyhash transaction with multiple outputs
  269. inputs = []
  270. outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3}
  271. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  272. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  273. #create same transaction over sendtoaddress
  274. txId = self.nodes[0].sendmany("", outputs)
  275. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  276. #compare fee
  277. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
  278. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  279. ############################################################
  280. ############################################################
  281. #compare fee of a 2of2 multisig p2sh transaction
  282. # create 2of2 addr
  283. addr1 = self.nodes[1].getnewaddress()
  284. addr2 = self.nodes[1].getnewaddress()
  285. addr1Obj = self.nodes[1].validateaddress(addr1)
  286. addr2Obj = self.nodes[1].validateaddress(addr2)
  287. mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
  288. inputs = []
  289. outputs = {mSigObj:1.1}
  290. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  291. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  292. #create same transaction over sendtoaddress
  293. txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
  294. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  295. #compare fee
  296. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
  297. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  298. ############################################################
  299. ############################################################
  300. #compare fee of a standard pubkeyhash transaction
  301. # create 4of5 addr
  302. addr1 = self.nodes[1].getnewaddress()
  303. addr2 = self.nodes[1].getnewaddress()
  304. addr3 = self.nodes[1].getnewaddress()
  305. addr4 = self.nodes[1].getnewaddress()
  306. addr5 = self.nodes[1].getnewaddress()
  307. addr1Obj = self.nodes[1].validateaddress(addr1)
  308. addr2Obj = self.nodes[1].validateaddress(addr2)
  309. addr3Obj = self.nodes[1].validateaddress(addr3)
  310. addr4Obj = self.nodes[1].validateaddress(addr4)
  311. addr5Obj = self.nodes[1].validateaddress(addr5)
  312. mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])
  313. inputs = []
  314. outputs = {mSigObj:1.1}
  315. rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
  316. fundedTx = self.nodes[0].fundrawtransaction(rawTx)
  317. #create same transaction over sendtoaddress
  318. txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
  319. signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
  320. #compare fee
  321. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
  322. assert(feeDelta >= 0 and feeDelta <= feeTolerance)
  323. ############################################################
  324. ############################################################
  325. # spend a 2of2 multisig transaction over fundraw
  326. # create 2of2 addr
  327. addr1 = self.nodes[2].getnewaddress()
  328. addr2 = self.nodes[2].getnewaddress()
  329. addr1Obj = self.nodes[2].validateaddress(addr1)
  330. addr2Obj = self.nodes[2].validateaddress(addr2)
  331. mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
  332. # send 1.2 BTC to msig addr
  333. txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
  334. self.sync_all()
  335. self.nodes[1].generate(1)
  336. self.sync_all()
  337. oldBalance = self.nodes[1].getbalance()
  338. inputs = []
  339. outputs = {self.nodes[1].getnewaddress():1.1}
  340. rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
  341. fundedTx = self.nodes[2].fundrawtransaction(rawTx)
  342. signedTx = self.nodes[2].signrawtransaction(fundedTx['hex'])
  343. txId = self.nodes[2].sendrawtransaction(signedTx['hex'])
  344. self.sync_all()
  345. self.nodes[1].generate(1)
  346. self.sync_all()
  347. # make sure funds are received at node1
  348. assert_equal(oldBalance+Decimal('1.10000000'), self.nodes[1].getbalance())
  349. ############################################################
  350. # locked wallet test
  351. self.nodes[1].encryptwallet("test")
  352. self.nodes.pop(1)
  353. stop_node(self.nodes[0], 0)
  354. stop_node(self.nodes[1], 2)
  355. stop_node(self.nodes[2], 3)
  356. self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
  357. # This test is not meant to test fee estimation and we'd like
  358. # to be sure all txs are sent at a consistent desired feerate
  359. for node in self.nodes:
  360. node.settxfee(min_relay_tx_fee)
  361. connect_nodes_bi(self.nodes,0,1)
  362. connect_nodes_bi(self.nodes,1,2)
  363. connect_nodes_bi(self.nodes,0,2)
  364. connect_nodes_bi(self.nodes,0,3)
  365. self.is_network_split=False
  366. self.sync_all()
  367. # drain the keypool
  368. self.nodes[1].getnewaddress()
  369. inputs = []
  370. outputs = {self.nodes[0].getnewaddress():1.1}
  371. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  372. # fund a transaction that requires a new key for the change output
  373. # creating the key must be impossible because the wallet is locked
  374. assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[1].fundrawtransaction, rawtx)
  375. #refill the keypool
  376. self.nodes[1].walletpassphrase("test", 100)
  377. self.nodes[1].walletlock()
  378. assert_raises_jsonrpc(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
  379. oldBalance = self.nodes[0].getbalance()
  380. inputs = []
  381. outputs = {self.nodes[0].getnewaddress():1.1}
  382. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  383. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  384. #now we need to unlock
  385. self.nodes[1].walletpassphrase("test", 600)
  386. signedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
  387. txId = self.nodes[1].sendrawtransaction(signedTx['hex'])
  388. self.nodes[1].generate(1)
  389. self.sync_all()
  390. # make sure funds are received at node1
  391. assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
  392. ###############################################
  393. # multiple (~19) inputs tx test | Compare fee #
  394. ###############################################
  395. #empty node1, send some small coins from node0 to node1
  396. self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True)
  397. self.sync_all()
  398. self.nodes[0].generate(1)
  399. self.sync_all()
  400. for i in range(0,20):
  401. self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
  402. self.nodes[0].generate(1)
  403. self.sync_all()
  404. #fund a tx with ~20 small inputs
  405. inputs = []
  406. outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
  407. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  408. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  409. #create same transaction over sendtoaddress
  410. txId = self.nodes[1].sendmany("", outputs)
  411. signedFee = self.nodes[1].getrawmempool(True)[txId]['fee']
  412. #compare fee
  413. feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
  414. assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs
  415. #############################################
  416. # multiple (~19) inputs tx test | sign/send #
  417. #############################################
  418. #again, empty node1, send some small coins from node0 to node1
  419. self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True)
  420. self.sync_all()
  421. self.nodes[0].generate(1)
  422. self.sync_all()
  423. for i in range(0,20):
  424. self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
  425. self.nodes[0].generate(1)
  426. self.sync_all()
  427. #fund a tx with ~20 small inputs
  428. oldBalance = self.nodes[0].getbalance()
  429. inputs = []
  430. outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
  431. rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
  432. fundedTx = self.nodes[1].fundrawtransaction(rawTx)
  433. fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
  434. txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
  435. self.sync_all()
  436. self.nodes[0].generate(1)
  437. self.sync_all()
  438. assert_equal(oldBalance+Decimal('50.19000000'), self.nodes[0].getbalance()) #0.19+block reward
  439. #####################################################
  440. # test fundrawtransaction with OP_RETURN and no vin #
  441. #####################################################
  442. rawtx = "0100000000010000000000000000066a047465737400000000"
  443. dec_tx = self.nodes[2].decoderawtransaction(rawtx)
  444. assert_equal(len(dec_tx['vin']), 0)
  445. assert_equal(len(dec_tx['vout']), 1)
  446. rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
  447. dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
  448. assert_greater_than(len(dec_tx['vin']), 0) # at least one vin
  449. assert_equal(len(dec_tx['vout']), 2) # one change output added
  450. ##################################################
  451. # test a fundrawtransaction using only watchonly #
  452. ##################################################
  453. inputs = []
  454. outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2}
  455. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  456. result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True })
  457. res_dec = self.nodes[0].decoderawtransaction(result["hex"])
  458. assert_equal(len(res_dec["vin"]), 1)
  459. assert_equal(res_dec["vin"][0]["txid"], watchonly_txid)
  460. assert("fee" in result.keys())
  461. assert_greater_than(result["changepos"], -1)
  462. ###############################################################
  463. # test fundrawtransaction using the entirety of watched funds #
  464. ###############################################################
  465. inputs = []
  466. outputs = {self.nodes[2].getnewaddress() : watchonly_amount}
  467. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  468. # Backward compatibility test (2nd param is includeWatching)
  469. result = self.nodes[3].fundrawtransaction(rawtx, True)
  470. res_dec = self.nodes[0].decoderawtransaction(result["hex"])
  471. assert_equal(len(res_dec["vin"]), 2)
  472. assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid)
  473. assert_greater_than(result["fee"], 0)
  474. assert_greater_than(result["changepos"], -1)
  475. assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10)
  476. signedtx = self.nodes[3].signrawtransaction(result["hex"])
  477. assert(not signedtx["complete"])
  478. signedtx = self.nodes[0].signrawtransaction(signedtx["hex"])
  479. assert(signedtx["complete"])
  480. self.nodes[0].sendrawtransaction(signedtx["hex"])
  481. self.nodes[0].generate(1)
  482. self.sync_all()
  483. #######################
  484. # Test feeRate option #
  485. #######################
  486. # Make sure there is exactly one input so coin selection can't skew the result
  487. assert_equal(len(self.nodes[3].listunspent(1)), 1)
  488. inputs = []
  489. outputs = {self.nodes[3].getnewaddress() : 1}
  490. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  491. result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
  492. result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
  493. result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee})
  494. result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex'])
  495. assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate)
  496. assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate)
  497. #############################
  498. # Test address reuse option #
  499. #############################
  500. result3 = self.nodes[3].fundrawtransaction(rawtx, {"reserveChangeKey": False})
  501. res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
  502. changeaddress = ""
  503. for out in res_dec['vout']:
  504. if out['value'] > 1.0:
  505. changeaddress += out['scriptPubKey']['addresses'][0]
  506. assert(changeaddress != "")
  507. nextaddr = self.nodes[3].getnewaddress()
  508. # frt should not have removed the key from the keypool
  509. assert(changeaddress == nextaddr)
  510. result3 = self.nodes[3].fundrawtransaction(rawtx)
  511. res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
  512. changeaddress = ""
  513. for out in res_dec['vout']:
  514. if out['value'] > 1.0:
  515. changeaddress += out['scriptPubKey']['addresses'][0]
  516. assert(changeaddress != "")
  517. nextaddr = self.nodes[3].getnewaddress()
  518. # Now the change address key should be removed from the keypool
  519. assert(changeaddress != nextaddr)
  520. ######################################
  521. # Test subtractFeeFromOutputs option #
  522. ######################################
  523. # Make sure there is exactly one input so coin selection can't skew the result
  524. assert_equal(len(self.nodes[3].listunspent(1)), 1)
  525. inputs = []
  526. outputs = {self.nodes[2].getnewaddress(): 1}
  527. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  528. result = [self.nodes[3].fundrawtransaction(rawtx), # uses min_relay_tx_fee (set by settxfee)
  529. self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": []}), # empty subtraction list
  530. self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": [0]}), # uses min_relay_tx_fee (set by settxfee)
  531. self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}),
  532. self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee, "subtractFeeFromOutputs": [0]})]
  533. dec_tx = [self.nodes[3].decoderawtransaction(tx['hex']) for tx in result]
  534. output = [d['vout'][1 - r['changepos']]['value'] for d, r in zip(dec_tx, result)]
  535. change = [d['vout'][r['changepos']]['value'] for d, r in zip(dec_tx, result)]
  536. assert_equal(result[0]['fee'], result[1]['fee'], result[2]['fee'])
  537. assert_equal(result[3]['fee'], result[4]['fee'])
  538. assert_equal(change[0], change[1])
  539. assert_equal(output[0], output[1])
  540. assert_equal(output[0], output[2] + result[2]['fee'])
  541. assert_equal(change[0] + result[0]['fee'], change[2])
  542. assert_equal(output[3], output[4] + result[4]['fee'])
  543. assert_equal(change[3] + result[3]['fee'], change[4])
  544. inputs = []
  545. outputs = {self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)}
  546. keys = list(outputs.keys())
  547. rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
  548. result = [self.nodes[3].fundrawtransaction(rawtx),
  549. # split the fee between outputs 0, 2, and 3, but not output 1
  550. self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": [0, 2, 3]})]
  551. dec_tx = [self.nodes[3].decoderawtransaction(result[0]['hex']),
  552. self.nodes[3].decoderawtransaction(result[1]['hex'])]
  553. # Nested list of non-change output amounts for each transaction
  554. output = [[out['value'] for i, out in enumerate(d['vout']) if i != r['changepos']]
  555. for d, r in zip(dec_tx, result)]
  556. # List of differences in output amounts between normal and subtractFee transactions
  557. share = [o0 - o1 for o0, o1 in zip(output[0], output[1])]
  558. # output 1 is the same in both transactions
  559. assert_equal(share[1], 0)
  560. # the other 3 outputs are smaller as a result of subtractFeeFromOutputs
  561. assert_greater_than(share[0], 0)
  562. assert_greater_than(share[2], 0)
  563. assert_greater_than(share[3], 0)
  564. # outputs 2 and 3 take the same share of the fee
  565. assert_equal(share[2], share[3])
  566. # output 0 takes at least as much share of the fee, and no more than 2 satoshis more, than outputs 2 and 3
  567. assert_greater_than_or_equal(share[0], share[2])
  568. assert_greater_than_or_equal(share[2] + Decimal(2e-8), share[0])
  569. # the fee is the same in both transactions
  570. assert_equal(result[0]['fee'], result[1]['fee'])
  571. # the total subtracted from the outputs is equal to the fee
  572. assert_equal(share[0] + share[2] + share[3], result[0]['fee'])
  573. if __name__ == '__main__':
  574. RawTransactionsTest().main()