Skip to content

Commit 47d3243

Browse files
committed
Make raw multisig tests legacy wallet only in rpc_rawtransaction.py
The traditional multisig workflow doesn't work with descriptor wallets so make these tests legacy wallet only.
1 parent 59d3da5 commit 47d3243

File tree

1 file changed

+131
-116
lines changed

1 file changed

+131
-116
lines changed

test/functional/rpc_rawtransaction.py

Lines changed: 131 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from test_framework.util import (
2121
assert_equal,
2222
assert_raises_rpc_error,
23+
find_vout_for_address,
2324
hex_str_to_bytes,
2425
)
2526

@@ -242,121 +243,124 @@ def run_test(self):
242243
self.nodes[0].reconsiderblock(block1)
243244
assert_equal(self.nodes[0].getbestblockhash(), block2)
244245

245-
#########################
246-
# RAW TX MULTISIG TESTS #
247-
#########################
248-
# 2of2 test
249-
addr1 = self.nodes[2].getnewaddress()
250-
addr2 = self.nodes[2].getnewaddress()
251-
252-
addr1Obj = self.nodes[2].getaddressinfo(addr1)
253-
addr2Obj = self.nodes[2].getaddressinfo(addr2)
254-
255-
# Tests for createmultisig and addmultisigaddress
256-
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"])
257-
self.nodes[0].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # createmultisig can only take public keys
258-
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here.
259-
260-
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr1])['address']
261-
262-
#use balance deltas instead of absolute values
263-
bal = self.nodes[2].getbalance()
264-
265-
# send 1.2 BTC to msig adr
266-
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
267-
self.sync_all()
268-
self.nodes[0].generate(1)
269-
self.sync_all()
270-
assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
271-
272-
273-
# 2of3 test from different nodes
274-
bal = self.nodes[2].getbalance()
275-
addr1 = self.nodes[1].getnewaddress()
276-
addr2 = self.nodes[2].getnewaddress()
277-
addr3 = self.nodes[2].getnewaddress()
278-
279-
addr1Obj = self.nodes[1].getaddressinfo(addr1)
280-
addr2Obj = self.nodes[2].getaddressinfo(addr2)
281-
addr3Obj = self.nodes[2].getaddressinfo(addr3)
282-
283-
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']
284-
285-
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
286-
decTx = self.nodes[0].gettransaction(txId)
287-
rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
288-
self.sync_all()
289-
self.nodes[0].generate(1)
290-
self.sync_all()
291-
292-
#THIS IS AN INCOMPLETE FEATURE
293-
#NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
294-
assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable
295-
296-
txDetails = self.nodes[0].gettransaction(txId, True)
297-
rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
298-
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('2.20000000'))
299-
300-
bal = self.nodes[0].getbalance()
301-
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
302-
outputs = { self.nodes[0].getnewaddress() : 2.19 }
303-
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
304-
rawTxPartialSigned = self.nodes[1].signrawtransactionwithwallet(rawTx, inputs)
305-
assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
306-
307-
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx, inputs)
308-
assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys
309-
self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
310-
rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
311-
self.sync_all()
312-
self.nodes[0].generate(1)
313-
self.sync_all()
314-
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
315-
316-
# 2of2 test for combining transactions
317-
bal = self.nodes[2].getbalance()
318-
addr1 = self.nodes[1].getnewaddress()
319-
addr2 = self.nodes[2].getnewaddress()
320-
321-
addr1Obj = self.nodes[1].getaddressinfo(addr1)
322-
addr2Obj = self.nodes[2].getaddressinfo(addr2)
323-
324-
self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
325-
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
326-
mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)
327-
328-
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
329-
decTx = self.nodes[0].gettransaction(txId)
330-
rawTx2 = self.nodes[0].decoderawtransaction(decTx['hex'])
331-
self.sync_all()
332-
self.nodes[0].generate(1)
333-
self.sync_all()
334-
335-
assert_equal(self.nodes[2].getbalance(), bal) # the funds of a 2of2 multisig tx should not be marked as spendable
336-
337-
txDetails = self.nodes[0].gettransaction(txId, True)
338-
rawTx2 = self.nodes[0].decoderawtransaction(txDetails['hex'])
339-
vout = next(o for o in rawTx2['vout'] if o['value'] == Decimal('2.20000000'))
340-
341-
bal = self.nodes[0].getbalance()
342-
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
343-
outputs = { self.nodes[0].getnewaddress() : 2.19 }
344-
rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
345-
rawTxPartialSigned1 = self.nodes[1].signrawtransactionwithwallet(rawTx2, inputs)
346-
self.log.debug(rawTxPartialSigned1)
347-
assert_equal(rawTxPartialSigned1['complete'], False) #node1 only has one key, can't comp. sign the tx
348-
349-
rawTxPartialSigned2 = self.nodes[2].signrawtransactionwithwallet(rawTx2, inputs)
350-
self.log.debug(rawTxPartialSigned2)
351-
assert_equal(rawTxPartialSigned2['complete'], False) #node2 only has one key, can't comp. sign the tx
352-
rawTxComb = self.nodes[2].combinerawtransaction([rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']])
353-
self.log.debug(rawTxComb)
354-
self.nodes[2].sendrawtransaction(rawTxComb)
355-
rawTx2 = self.nodes[0].decoderawtransaction(rawTxComb)
356-
self.sync_all()
357-
self.nodes[0].generate(1)
358-
self.sync_all()
359-
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
246+
if not self.options.descriptors:
247+
# The traditional multisig workflow does not work with descriptor wallets so these are legacy only.
248+
# The multisig workflow with descriptor wallets uses PSBTs and is tested elsewhere, no need to do them here.
249+
#########################
250+
# RAW TX MULTISIG TESTS #
251+
#########################
252+
# 2of2 test
253+
addr1 = self.nodes[2].getnewaddress()
254+
addr2 = self.nodes[2].getnewaddress()
255+
256+
addr1Obj = self.nodes[2].getaddressinfo(addr1)
257+
addr2Obj = self.nodes[2].getaddressinfo(addr2)
258+
259+
# Tests for createmultisig and addmultisigaddress
260+
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"])
261+
self.nodes[0].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # createmultisig can only take public keys
262+
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here.
263+
264+
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr1])['address']
265+
266+
#use balance deltas instead of absolute values
267+
bal = self.nodes[2].getbalance()
268+
269+
# send 1.2 BTC to msig adr
270+
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
271+
self.sync_all()
272+
self.nodes[0].generate(1)
273+
self.sync_all()
274+
assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
275+
276+
277+
# 2of3 test from different nodes
278+
bal = self.nodes[2].getbalance()
279+
addr1 = self.nodes[1].getnewaddress()
280+
addr2 = self.nodes[2].getnewaddress()
281+
addr3 = self.nodes[2].getnewaddress()
282+
283+
addr1Obj = self.nodes[1].getaddressinfo(addr1)
284+
addr2Obj = self.nodes[2].getaddressinfo(addr2)
285+
addr3Obj = self.nodes[2].getaddressinfo(addr3)
286+
287+
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']
288+
289+
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
290+
decTx = self.nodes[0].gettransaction(txId)
291+
rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
292+
self.sync_all()
293+
self.nodes[0].generate(1)
294+
self.sync_all()
295+
296+
#THIS IS AN INCOMPLETE FEATURE
297+
#NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
298+
assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable
299+
300+
txDetails = self.nodes[0].gettransaction(txId, True)
301+
rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
302+
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('2.20000000'))
303+
304+
bal = self.nodes[0].getbalance()
305+
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
306+
outputs = { self.nodes[0].getnewaddress() : 2.19 }
307+
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
308+
rawTxPartialSigned = self.nodes[1].signrawtransactionwithwallet(rawTx, inputs)
309+
assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
310+
311+
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx, inputs)
312+
assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys
313+
self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
314+
rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
315+
self.sync_all()
316+
self.nodes[0].generate(1)
317+
self.sync_all()
318+
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
319+
320+
# 2of2 test for combining transactions
321+
bal = self.nodes[2].getbalance()
322+
addr1 = self.nodes[1].getnewaddress()
323+
addr2 = self.nodes[2].getnewaddress()
324+
325+
addr1Obj = self.nodes[1].getaddressinfo(addr1)
326+
addr2Obj = self.nodes[2].getaddressinfo(addr2)
327+
328+
self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
329+
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
330+
mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)
331+
332+
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
333+
decTx = self.nodes[0].gettransaction(txId)
334+
rawTx2 = self.nodes[0].decoderawtransaction(decTx['hex'])
335+
self.sync_all()
336+
self.nodes[0].generate(1)
337+
self.sync_all()
338+
339+
assert_equal(self.nodes[2].getbalance(), bal) # the funds of a 2of2 multisig tx should not be marked as spendable
340+
341+
txDetails = self.nodes[0].gettransaction(txId, True)
342+
rawTx2 = self.nodes[0].decoderawtransaction(txDetails['hex'])
343+
vout = next(o for o in rawTx2['vout'] if o['value'] == Decimal('2.20000000'))
344+
345+
bal = self.nodes[0].getbalance()
346+
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
347+
outputs = { self.nodes[0].getnewaddress() : 2.19 }
348+
rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
349+
rawTxPartialSigned1 = self.nodes[1].signrawtransactionwithwallet(rawTx2, inputs)
350+
self.log.debug(rawTxPartialSigned1)
351+
assert_equal(rawTxPartialSigned1['complete'], False) #node1 only has one key, can't comp. sign the tx
352+
353+
rawTxPartialSigned2 = self.nodes[2].signrawtransactionwithwallet(rawTx2, inputs)
354+
self.log.debug(rawTxPartialSigned2)
355+
assert_equal(rawTxPartialSigned2['complete'], False) #node2 only has one key, can't comp. sign the tx
356+
rawTxComb = self.nodes[2].combinerawtransaction([rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']])
357+
self.log.debug(rawTxComb)
358+
self.nodes[2].sendrawtransaction(rawTxComb)
359+
rawTx2 = self.nodes[0].decoderawtransaction(rawTxComb)
360+
self.sync_all()
361+
self.nodes[0].generate(1)
362+
self.sync_all()
363+
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
360364

361365
# decoderawtransaction tests
362366
# witness transaction
@@ -369,9 +373,20 @@ def run_test(self):
369373
decrawtx = self.nodes[0].decoderawtransaction(encrawtx, False) # decode as non-witness transaction
370374
assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000'))
371375

376+
# Basic signrawtransaction test
377+
addr = self.nodes[1].getnewaddress()
378+
txid = self.nodes[0].sendtoaddress(addr, 10)
379+
self.nodes[0].generate(1)
380+
self.sync_all()
381+
vout = find_vout_for_address(self.nodes[1], txid, addr)
382+
rawTx = self.nodes[1].createrawtransaction([{'txid': txid, 'vout': vout}], {self.nodes[1].getnewaddress(): 9.999})
383+
rawTxSigned = self.nodes[1].signrawtransactionwithwallet(rawTx)
384+
txId = self.nodes[1].sendrawtransaction(rawTxSigned['hex'])
385+
self.nodes[0].generate(1)
386+
self.sync_all()
387+
372388
# getrawtransaction tests
373389
# 1. valid parameters - only supply txid
374-
txId = rawTx["txid"]
375390
assert_equal(self.nodes[0].getrawtransaction(txId), rawTxSigned['hex'])
376391

377392
# 2. valid parameters - supply txid and 0 for non-verbose

0 commit comments

Comments
 (0)