2016-01-02 06:18:34 +01:00
#!/usr/bin/env python3
2020-04-16 19:14:08 +02:00
# Copyright (c) 2016-2020 The Bitcoin Core developers
2016-01-02 06:18:34 +01:00
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
2017-01-18 00:34:40 +01:00
""" Test the SegWit changeover logic. """
2016-01-02 06:18:34 +01:00
2018-07-07 00:10:35 +02:00
from decimal import Decimal
2017-09-14 17:41:30 +02:00
from test_framework . address import (
2018-07-07 00:10:35 +02:00
key_to_p2pkh ,
2017-09-14 17:41:30 +02:00
program_to_witness ,
2018-07-07 00:10:35 +02:00
script_to_p2sh ,
2017-09-14 17:41:30 +02:00
script_to_p2sh_p2wsh ,
script_to_p2wsh ,
)
2021-06-15 23:02:28 +02:00
from test_framework . blocktools import (
send_to_witness ,
witness_script ,
)
from test_framework . messages import (
COIN ,
COutPoint ,
CTransaction ,
CTxIn ,
CTxOut ,
tx_from_hex ,
)
from test_framework . script import (
CScript ,
OP_0 ,
OP_1 ,
OP_2 ,
OP_CHECKMULTISIG ,
OP_CHECKSIG ,
OP_DROP ,
OP_TRUE ,
)
2021-06-27 23:03:40 +02:00
from test_framework . script_util import (
key_to_p2pkh_script ,
2021-06-28 20:45:04 +02:00
key_to_p2wpkh_script ,
2021-06-27 23:52:38 +02:00
script_to_p2sh_script ,
2021-06-28 20:45:04 +02:00
script_to_p2wsh_script ,
2021-06-27 23:03:40 +02:00
)
2018-07-07 00:10:35 +02:00
from test_framework . test_framework import BitcoinTestFramework
2019-04-07 00:38:51 +02:00
from test_framework . util import (
assert_equal ,
2020-05-02 13:13:58 +02:00
assert_is_hex_string ,
2019-04-07 00:38:51 +02:00
assert_raises_rpc_error ,
hex_str_to_bytes ,
try_rpc ,
)
2018-07-07 00:10:35 +02:00
2016-01-02 06:18:34 +01:00
NODE_0 = 0
NODE_2 = 2
2020-03-19 18:52:13 +01:00
P2WPKH = 0
P2WSH = 1
2016-01-02 06:18:34 +01:00
def getutxo ( txid ) :
utxo = { }
utxo [ " vout " ] = 0
utxo [ " txid " ] = txid
return utxo
2017-09-01 01:57:45 +02:00
def find_spendable_utxo ( node , min_value ) :
for utxo in node . listunspent ( query_options = { ' minimumAmount ' : min_value } ) :
if utxo [ ' spendable ' ] :
2016-08-08 23:58:36 +02:00
return utxo
2017-09-01 01:57:45 +02:00
raise AssertionError ( " Unspent output equal or higher than %s not found " % min_value )
2019-02-14 04:22:40 +01:00
txs_mined = { } # txindex from txid to blockhash
2016-01-02 06:18:34 +01:00
class SegWitTest ( BitcoinTestFramework ) :
2017-06-10 00:21:21 +02:00
def set_test_params ( self ) :
2016-06-30 14:49:59 +02:00
self . setup_clean_chain = True
self . num_nodes = 3
2017-10-12 05:25:18 +02:00
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
2018-09-09 19:32:37 +02:00
self . extra_args = [
[
2019-04-24 23:55:58 +02:00
" -acceptnonstdtxn=1 " ,
2018-09-09 19:32:37 +02:00
" -rpcserialversion=0 " ,
2019-05-20 20:59:07 +02:00
" -segwitheight=432 " ,
2018-09-09 19:32:37 +02:00
" -addresstype=legacy " ,
] ,
[
2019-04-24 23:55:58 +02:00
" -acceptnonstdtxn=1 " ,
2018-09-09 19:32:37 +02:00
" -rpcserialversion=1 " ,
2019-05-20 20:59:07 +02:00
" -segwitheight=432 " ,
2018-09-09 19:32:37 +02:00
" -addresstype=legacy " ,
] ,
[
2019-04-24 23:55:58 +02:00
" -acceptnonstdtxn=1 " ,
2019-05-20 20:59:07 +02:00
" -segwitheight=432 " ,
2018-09-09 19:32:37 +02:00
" -addresstype=legacy " ,
] ,
]
2020-03-09 19:39:10 +01:00
self . rpc_timeout = 120
2018-09-09 19:32:37 +02:00
def skip_test_if_missing_module ( self ) :
self . skip_if_no_wallet ( )
2016-01-02 06:18:34 +01:00
def setup_network ( self ) :
2017-04-03 15:34:04 +02:00
super ( ) . setup_network ( )
2020-09-17 09:46:07 +02:00
self . connect_nodes ( 0 , 2 )
2016-01-02 06:18:34 +01:00
self . sync_all ( )
def success_mine ( self , node , txid , sign , redeem_script = " " ) :
send_to_witness ( 1 , node , getutxo ( txid ) , self . pubkey [ 0 ] , False , Decimal ( " 49.998 " ) , sign , redeem_script )
block = node . generate ( 1 )
assert_equal ( len ( node . getblock ( block [ 0 ] ) [ " tx " ] ) , 2 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-01-02 06:18:34 +01:00
def skip_mine ( self , node , txid , sign , redeem_script = " " ) :
send_to_witness ( 1 , node , getutxo ( txid ) , self . pubkey [ 0 ] , False , Decimal ( " 49.998 " ) , sign , redeem_script )
block = node . generate ( 1 )
assert_equal ( len ( node . getblock ( block [ 0 ] ) [ " tx " ] ) , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-01-02 06:18:34 +01:00
2017-03-07 20:08:59 +01:00
def fail_accept ( self , node , error_msg , txid , sign , redeem_script = " " ) :
2018-06-23 22:16:54 +02:00
assert_raises_rpc_error ( - 26 , error_msg , send_to_witness , use_p2wsh = 1 , node = node , utxo = getutxo ( txid ) , pubkey = self . pubkey [ 0 ] , encode_p2sh = False , amount = Decimal ( " 49.998 " ) , sign = sign , insert_redeem_script = redeem_script )
2016-01-02 06:18:34 +01:00
def run_test ( self ) :
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . generate ( 161 ) # block 161
2016-08-08 23:58:36 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify sigops are counted in GBT with pre-BIP141 rules before the fork " )
2016-08-08 23:58:36 +02:00
txid = self . nodes [ 0 ] . sendtoaddress ( self . nodes [ 0 ] . getnewaddress ( ) , 1 )
2018-11-26 17:17:38 +01:00
tmpl = self . nodes [ 0 ] . getblocktemplate ( { ' rules ' : [ ' segwit ' ] } )
2019-02-19 23:43:44 +01:00
assert tmpl [ ' sizelimit ' ] == 1000000
assert ' weightlimit ' not in tmpl
assert tmpl [ ' sigoplimit ' ] == 20000
assert tmpl [ ' transactions ' ] [ 0 ] [ ' hash ' ] == txid
assert tmpl [ ' transactions ' ] [ 0 ] [ ' sigops ' ] == 2
2020-01-17 06:27:56 +01:00
assert ' !segwit ' not in tmpl [ ' rules ' ]
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . generate ( 1 ) # block 162
2016-08-08 23:58:36 +02:00
balance_presetup = self . nodes [ 0 ] . getbalance ( )
2016-01-02 06:18:34 +01:00
self . pubkey = [ ]
2020-03-19 18:52:13 +01:00
p2sh_ids = [ ] # p2sh_ids[NODE][TYPE] is an array of txids that spend to P2WPKH (TYPE=0) or P2WSH (TYPE=1) scripts to an address for NODE embedded in p2sh
wit_ids = [ ] # wit_ids[NODE][TYPE] is an array of txids that spend to P2WPKH (TYPE=0) or P2WSH (TYPE=1) scripts to an address for NODE via bare witness
2016-01-02 06:18:34 +01:00
for i in range ( 3 ) :
newaddress = self . nodes [ i ] . getnewaddress ( )
2018-02-09 17:12:27 +01:00
self . pubkey . append ( self . nodes [ i ] . getaddressinfo ( newaddress ) [ " pubkey " ] )
2017-08-27 09:41:46 +02:00
multiscript = CScript ( [ OP_1 , hex_str_to_bytes ( self . pubkey [ - 1 ] ) , OP_1 , OP_CHECKMULTISIG ] )
2018-01-18 00:30:56 +01:00
p2sh_ms_addr = self . nodes [ i ] . addmultisigaddress ( 1 , [ self . pubkey [ - 1 ] ] , ' ' , ' p2sh-segwit ' ) [ ' address ' ]
bip173_ms_addr = self . nodes [ i ] . addmultisigaddress ( 1 , [ self . pubkey [ - 1 ] ] , ' ' , ' bech32 ' ) [ ' address ' ]
2017-08-27 09:41:46 +02:00
assert_equal ( p2sh_ms_addr , script_to_p2sh_p2wsh ( multiscript ) )
assert_equal ( bip173_ms_addr , script_to_p2wsh ( multiscript ) )
2016-01-02 06:18:34 +01:00
p2sh_ids . append ( [ ] )
wit_ids . append ( [ ] )
2020-08-03 01:10:56 +02:00
for _ in range ( 2 ) :
2016-01-02 06:18:34 +01:00
p2sh_ids [ i ] . append ( [ ] )
wit_ids [ i ] . append ( [ ] )
2020-08-03 01:10:56 +02:00
for _ in range ( 5 ) :
2016-01-02 06:18:34 +01:00
for n in range ( 3 ) :
for v in range ( 2 ) :
2017-09-01 01:57:45 +02:00
wit_ids [ n ] [ v ] . append ( send_to_witness ( v , self . nodes [ 0 ] , find_spendable_utxo ( self . nodes [ 0 ] , 50 ) , self . pubkey [ n ] , False , Decimal ( " 49.999 " ) ) )
p2sh_ids [ n ] [ v ] . append ( send_to_witness ( v , self . nodes [ 0 ] , find_spendable_utxo ( self . nodes [ 0 ] , 50 ) , self . pubkey [ n ] , True , Decimal ( " 49.999 " ) ) )
2016-01-02 06:18:34 +01:00
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . generate ( 1 ) # block 163
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-01-02 06:18:34 +01:00
# Make sure all nodes recognize the transactions as theirs
2018-09-23 14:50:47 +02:00
assert_equal ( self . nodes [ 0 ] . getbalance ( ) , balance_presetup - 60 * 50 + 20 * Decimal ( " 49.999 " ) + 50 )
assert_equal ( self . nodes [ 1 ] . getbalance ( ) , 20 * Decimal ( " 49.999 " ) )
assert_equal ( self . nodes [ 2 ] . getbalance ( ) , 20 * Decimal ( " 49.999 " ) )
2016-01-02 06:18:34 +01:00
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . generate ( 260 ) # block 423
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-01-02 06:18:34 +01:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify witness txs are skipped for mining before the fork " )
2020-03-19 18:52:13 +01:00
self . skip_mine ( self . nodes [ 2 ] , wit_ids [ NODE_2 ] [ P2WPKH ] [ 0 ] , True ) # block 424
self . skip_mine ( self . nodes [ 2 ] , wit_ids [ NODE_2 ] [ P2WSH ] [ 0 ] , True ) # block 425
self . skip_mine ( self . nodes [ 2 ] , p2sh_ids [ NODE_2 ] [ P2WPKH ] [ 0 ] , True ) # block 426
self . skip_mine ( self . nodes [ 2 ] , p2sh_ids [ NODE_2 ] [ P2WSH ] [ 0 ] , True ) # block 427
2016-01-02 06:18:34 +01:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify unsigned p2sh witness txs without a redeem script are invalid " )
2020-03-19 18:52:13 +01:00
self . fail_accept ( self . nodes [ 2 ] , " mandatory-script-verify-flag-failed (Operation not valid with the current stack size) " , p2sh_ids [ NODE_2 ] [ P2WPKH ] [ 1 ] , sign = False )
self . fail_accept ( self . nodes [ 2 ] , " mandatory-script-verify-flag-failed (Operation not valid with the current stack size) " , p2sh_ids [ NODE_2 ] [ P2WSH ] [ 1 ] , sign = False )
2016-01-02 06:18:34 +01:00
2018-09-23 14:50:47 +02:00
self . nodes [ 2 ] . generate ( 4 ) # blocks 428-431
2016-01-02 06:18:34 +01:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify previous witness txs skipped for mining can now be mined " )
2016-01-02 06:18:34 +01:00
assert_equal ( len ( self . nodes [ 2 ] . getrawmempool ( ) ) , 4 )
2019-02-14 04:22:40 +01:00
blockhash = self . nodes [ 2 ] . generate ( 1 ) [ 0 ] # block 432 (first block with new rules; 432 = 144 * 3)
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-01-02 06:18:34 +01:00
assert_equal ( len ( self . nodes [ 2 ] . getrawmempool ( ) ) , 0 )
2019-02-14 04:22:40 +01:00
segwit_tx_list = self . nodes [ 2 ] . getblock ( blockhash ) [ " tx " ]
2016-11-20 15:54:51 +01:00
assert_equal ( len ( segwit_tx_list ) , 5 )
2018-04-30 01:34:57 +02:00
self . log . info ( " Verify default node can ' t accept txs with missing witness " )
# unsigned, no scriptsig
2020-03-19 18:52:13 +01:00
self . fail_accept ( self . nodes [ 0 ] , " non-mandatory-script-verify-flag (Witness program hash mismatch) " , wit_ids [ NODE_0 ] [ P2WPKH ] [ 0 ] , sign = False )
self . fail_accept ( self . nodes [ 0 ] , " non-mandatory-script-verify-flag (Witness program was passed an empty witness) " , wit_ids [ NODE_0 ] [ P2WSH ] [ 0 ] , sign = False )
self . fail_accept ( self . nodes [ 0 ] , " mandatory-script-verify-flag-failed (Operation not valid with the current stack size) " , p2sh_ids [ NODE_0 ] [ P2WPKH ] [ 0 ] , sign = False )
self . fail_accept ( self . nodes [ 0 ] , " mandatory-script-verify-flag-failed (Operation not valid with the current stack size) " , p2sh_ids [ NODE_0 ] [ P2WSH ] [ 0 ] , sign = False )
2018-04-30 01:34:57 +02:00
# unsigned with redeem script
2020-03-19 18:52:13 +01:00
self . fail_accept ( self . nodes [ 0 ] , " non-mandatory-script-verify-flag (Witness program hash mismatch) " , p2sh_ids [ NODE_0 ] [ P2WPKH ] [ 0 ] , sign = False , redeem_script = witness_script ( False , self . pubkey [ 0 ] ) )
self . fail_accept ( self . nodes [ 0 ] , " non-mandatory-script-verify-flag (Witness program was passed an empty witness) " , p2sh_ids [ NODE_0 ] [ P2WSH ] [ 0 ] , sign = False , redeem_script = witness_script ( True , self . pubkey [ 0 ] ) )
2018-04-30 01:34:57 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag " )
2019-02-19 23:43:44 +01:00
assert self . nodes [ 2 ] . getblock ( blockhash , False ) != self . nodes [ 0 ] . getblock ( blockhash , False )
assert self . nodes [ 1 ] . getblock ( blockhash , False ) == self . nodes [ 2 ] . getblock ( blockhash , False )
2019-02-14 04:22:40 +01:00
for tx_id in segwit_tx_list :
2021-06-15 23:02:28 +02:00
tx = tx_from_hex ( self . nodes [ 2 ] . gettransaction ( tx_id ) [ " hex " ] )
2019-02-19 23:43:44 +01:00
assert self . nodes [ 2 ] . getrawtransaction ( tx_id , False , blockhash ) != self . nodes [ 0 ] . getrawtransaction ( tx_id , False , blockhash )
assert self . nodes [ 1 ] . getrawtransaction ( tx_id , False , blockhash ) == self . nodes [ 2 ] . getrawtransaction ( tx_id , False , blockhash )
assert self . nodes [ 0 ] . getrawtransaction ( tx_id , False , blockhash ) != self . nodes [ 2 ] . gettransaction ( tx_id ) [ " hex " ]
assert self . nodes [ 1 ] . getrawtransaction ( tx_id , False , blockhash ) == self . nodes [ 2 ] . gettransaction ( tx_id ) [ " hex " ]
assert self . nodes [ 0 ] . getrawtransaction ( tx_id , False , blockhash ) == tx . serialize_without_witness ( ) . hex ( )
2016-01-02 06:18:34 +01:00
2020-05-02 13:13:58 +02:00
# Coinbase contains the witness commitment nonce, check that RPC shows us
coinbase_txid = self . nodes [ 2 ] . getblock ( blockhash ) [ ' tx ' ] [ 0 ]
coinbase_tx = self . nodes [ 2 ] . gettransaction ( txid = coinbase_txid , verbose = True )
witnesses = coinbase_tx [ " decoded " ] [ " vin " ] [ 0 ] [ " txinwitness " ]
assert_equal ( len ( witnesses ) , 1 )
assert_is_hex_string ( witnesses [ 0 ] )
assert_equal ( witnesses [ 0 ] , ' 00 ' * 32 )
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify witness txs without witness data are invalid after the fork " )
2020-03-19 18:52:13 +01:00
self . fail_accept ( self . nodes [ 2 ] , ' non-mandatory-script-verify-flag (Witness program hash mismatch) ' , wit_ids [ NODE_2 ] [ P2WPKH ] [ 2 ] , sign = False )
self . fail_accept ( self . nodes [ 2 ] , ' non-mandatory-script-verify-flag (Witness program was passed an empty witness) ' , wit_ids [ NODE_2 ] [ P2WSH ] [ 2 ] , sign = False )
self . fail_accept ( self . nodes [ 2 ] , ' non-mandatory-script-verify-flag (Witness program hash mismatch) ' , p2sh_ids [ NODE_2 ] [ P2WPKH ] [ 2 ] , sign = False , redeem_script = witness_script ( False , self . pubkey [ 2 ] ) )
self . fail_accept ( self . nodes [ 2 ] , ' non-mandatory-script-verify-flag (Witness program was passed an empty witness) ' , p2sh_ids [ NODE_2 ] [ P2WSH ] [ 2 ] , sign = False , redeem_script = witness_script ( True , self . pubkey [ 2 ] ) )
2016-01-02 06:18:34 +01:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify default node can now use witness txs " )
2020-03-19 18:52:13 +01:00
self . success_mine ( self . nodes [ 0 ] , wit_ids [ NODE_0 ] [ P2WPKH ] [ 0 ] , True ) # block 432
self . success_mine ( self . nodes [ 0 ] , wit_ids [ NODE_0 ] [ P2WSH ] [ 0 ] , True ) # block 433
self . success_mine ( self . nodes [ 0 ] , p2sh_ids [ NODE_0 ] [ P2WPKH ] [ 0 ] , True ) # block 434
self . success_mine ( self . nodes [ 0 ] , p2sh_ids [ NODE_0 ] [ P2WSH ] [ 0 ] , True ) # block 435
2016-01-02 06:18:34 +01:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Verify sigops are counted in GBT with BIP141 rules after the fork " )
2016-08-08 23:58:36 +02:00
txid = self . nodes [ 0 ] . sendtoaddress ( self . nodes [ 0 ] . getnewaddress ( ) , 1 )
2018-09-23 14:50:47 +02:00
tmpl = self . nodes [ 0 ] . getblocktemplate ( { ' rules ' : [ ' segwit ' ] } )
2019-02-19 23:43:44 +01:00
assert tmpl [ ' sizelimit ' ] > = 3999577 # actual maximum size is lower due to minimum mandatory non-witness data
assert tmpl [ ' weightlimit ' ] == 4000000
assert tmpl [ ' sigoplimit ' ] == 80000
assert tmpl [ ' transactions ' ] [ 0 ] [ ' txid ' ] == txid
assert tmpl [ ' transactions ' ] [ 0 ] [ ' sigops ' ] == 8
2020-01-17 06:27:56 +01:00
assert ' !segwit ' in tmpl [ ' rules ' ]
2016-08-08 23:58:36 +02:00
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . generate ( 1 ) # Mine a block to clear the gbt cache
2017-03-09 19:49:50 +01:00
2017-03-08 21:56:59 +01:00
self . log . info ( " Non-segwit miners are able to use GBT response after activation. " )
2017-03-09 19:49:50 +01:00
# Create a 3-tx chain: tx1 (non-segwit input, paying to a segwit output) ->
# tx2 (segwit input, paying to a non-segwit output) ->
# tx3 (non-segwit input, paying to a non-segwit output).
# tx1 is allowed to appear in the block, but no others.
2017-09-01 01:57:45 +02:00
txid1 = send_to_witness ( 1 , self . nodes [ 0 ] , find_spendable_utxo ( self . nodes [ 0 ] , 50 ) , self . pubkey [ 0 ] , False , Decimal ( " 49.996 " ) )
2017-03-09 19:49:50 +01:00
hex_tx = self . nodes [ 0 ] . gettransaction ( txid ) [ ' hex ' ]
2021-06-15 23:02:28 +02:00
tx = tx_from_hex ( hex_tx )
2019-02-19 23:43:44 +01:00
assert tx . wit . is_null ( ) # This should not be a segwit input
assert txid1 in self . nodes [ 0 ] . getrawmempool ( )
2017-03-09 19:49:50 +01:00
2017-09-08 21:20:00 +02:00
tx1_hex = self . nodes [ 0 ] . gettransaction ( txid1 ) [ ' hex ' ]
2021-06-15 23:02:28 +02:00
tx1 = tx_from_hex ( tx1_hex )
2017-09-08 21:20:00 +02:00
# Check that wtxid is properly reported in mempool entry (txid1)
assert_equal ( int ( self . nodes [ 0 ] . getmempoolentry ( txid1 ) [ " wtxid " ] , 16 ) , tx1 . calc_sha256 ( True ) )
# Check that weight and vsize are properly reported in mempool entry (txid1)
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid1 ) [ " vsize " ] , ( self . nodes [ 0 ] . getmempoolentry ( txid1 ) [ " weight " ] + 3 ) / / 4 )
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid1 ) [ " weight " ] , len ( tx1 . serialize_without_witness ( ) ) * 3 + len ( tx1 . serialize_with_witness ( ) ) )
2017-03-09 19:49:50 +01:00
# Now create tx2, which will spend from txid1.
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( int ( txid1 , 16 ) , 0 ) , b ' ' ) )
2018-05-03 22:50:25 +02:00
tx . vout . append ( CTxOut ( int ( 49.99 * COIN ) , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) )
2021-06-16 00:32:18 +02:00
tx2_hex = self . nodes [ 0 ] . signrawtransactionwithwallet ( tx . serialize ( ) . hex ( ) ) [ ' hex ' ]
2017-03-09 19:49:50 +01:00
txid2 = self . nodes [ 0 ] . sendrawtransaction ( tx2_hex )
2021-06-15 23:02:28 +02:00
tx = tx_from_hex ( tx2_hex )
2019-02-19 23:43:44 +01:00
assert not tx . wit . is_null ( )
2017-03-09 19:49:50 +01:00
2017-09-08 21:20:00 +02:00
# Check that wtxid is properly reported in mempool entry (txid2)
assert_equal ( int ( self . nodes [ 0 ] . getmempoolentry ( txid2 ) [ " wtxid " ] , 16 ) , tx . calc_sha256 ( True ) )
# Check that weight and vsize are properly reported in mempool entry (txid2)
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid2 ) [ " vsize " ] , ( self . nodes [ 0 ] . getmempoolentry ( txid2 ) [ " weight " ] + 3 ) / / 4 )
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid2 ) [ " weight " ] , len ( tx . serialize_without_witness ( ) ) * 3 + len ( tx . serialize_with_witness ( ) ) )
2017-03-09 19:49:50 +01:00
# Now create tx3, which will spend from txid2
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( int ( txid2 , 16 ) , 0 ) , b " " ) )
2018-05-03 22:50:25 +02:00
tx . vout . append ( CTxOut ( int ( 49.95 * COIN ) , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) ) # Huge fee
2017-03-09 19:49:50 +01:00
tx . calc_sha256 ( )
2021-06-16 00:32:18 +02:00
txid3 = self . nodes [ 0 ] . sendrawtransaction ( hexstring = tx . serialize ( ) . hex ( ) , maxfeerate = 0 )
2019-02-19 23:43:44 +01:00
assert tx . wit . is_null ( )
assert txid3 in self . nodes [ 0 ] . getrawmempool ( )
2017-03-09 19:49:50 +01:00
2018-11-26 17:17:38 +01:00
# Check that getblocktemplate includes all transactions.
2017-03-09 19:49:50 +01:00
template = self . nodes [ 0 ] . getblocktemplate ( { " rules " : [ " segwit " ] } )
2018-09-23 14:50:47 +02:00
template_txids = [ t [ ' txid ' ] for t in template [ ' transactions ' ] ]
2019-02-19 23:43:44 +01:00
assert txid1 in template_txids
assert txid2 in template_txids
assert txid3 in template_txids
2017-03-09 19:49:50 +01:00
2017-09-08 21:20:00 +02:00
# Check that wtxid is properly reported in mempool entry (txid3)
2017-08-31 19:18:35 +02:00
assert_equal ( int ( self . nodes [ 0 ] . getmempoolentry ( txid3 ) [ " wtxid " ] , 16 ) , tx . calc_sha256 ( True ) )
2017-09-08 21:20:00 +02:00
# Check that weight and vsize are properly reported in mempool entry (txid3)
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid3 ) [ " vsize " ] , ( self . nodes [ 0 ] . getmempoolentry ( txid3 ) [ " weight " ] + 3 ) / / 4 )
assert_equal ( self . nodes [ 0 ] . getmempoolentry ( txid3 ) [ " weight " ] , len ( tx . serialize_without_witness ( ) ) * 3 + len ( tx . serialize_with_witness ( ) ) )
2017-03-09 19:49:50 +01:00
# Mine a block to clear the gbt cache again.
self . nodes [ 0 ] . generate ( 1 )
2016-08-08 23:58:36 +02:00
2018-09-23 05:15:49 +02:00
self . log . info ( " Verify behaviour of importaddress and listunspent " )
2016-10-14 20:29:39 +02:00
# Some public keys to be used later
pubkeys = [
2018-09-23 14:50:47 +02:00
" 0363D44AABD0F1699138239DF2F042C3282C0671CC7A76826A55C8203D90E39242 " , # cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb
" 02D3E626B3E616FC8662B489C123349FECBFC611E778E5BE739B257EAE4721E5BF " , # cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97
" 04A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538A62F5BD8EC85C2477F39650BD391EA6250207065B2A81DA8B009FC891E898F0E " , # 91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV
" 02A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538 " , # cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd
" 036722F784214129FEB9E8129D626324F3F6716555B603FFE8300BBCB882151228 " , # cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66
" 0266A8396EE936BF6D99D17920DB21C6C7B1AB14C639D5CD72B300297E416FD2EC " , # cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K
" 0450A38BD7F0AC212FEBA77354A9B036A32E0F7C81FC4E0C5ADCA7C549C4505D2522458C2D9AE3CEFD684E039194B72C8A10F9CB9D4764AB26FCC2718D421D3B84 " , # 92h2XPssjBpsJN5CqSP7v9a7cf2kgDunBC6PDFwJHMACM1rrVBJ
2016-10-14 20:29:39 +02:00
]
# Import a compressed key and an uncompressed key, generate some multisig addresses
self . nodes [ 0 ] . importprivkey ( " 92e6XLo5jVAVwrQKPNTs93oQco8f8sDNBcpv73Dsrs397fQtFQn " )
uncompressed_spendable_address = [ " mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu " ]
self . nodes [ 0 ] . importprivkey ( " cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR " )
compressed_spendable_address = [ " mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe " ]
2018-09-23 14:50:47 +02:00
assert not self . nodes [ 0 ] . getaddressinfo ( uncompressed_spendable_address [ 0 ] ) [ ' iscompressed ' ]
assert self . nodes [ 0 ] . getaddressinfo ( compressed_spendable_address [ 0 ] ) [ ' iscompressed ' ]
2016-10-14 20:29:39 +02:00
self . nodes [ 0 ] . importpubkey ( pubkeys [ 0 ] )
compressed_solvable_address = [ key_to_p2pkh ( pubkeys [ 0 ] ) ]
self . nodes [ 0 ] . importpubkey ( pubkeys [ 1 ] )
compressed_solvable_address . append ( key_to_p2pkh ( pubkeys [ 1 ] ) )
self . nodes [ 0 ] . importpubkey ( pubkeys [ 2 ] )
uncompressed_solvable_address = [ key_to_p2pkh ( pubkeys [ 2 ] ) ]
spendable_anytime = [ ] # These outputs should be seen anytime after importprivkey and addmultisigaddress
spendable_after_importaddress = [ ] # These outputs should be seen after importaddress
solvable_after_importaddress = [ ] # These outputs should be seen after importaddress but not spendable
unsolvable_after_importaddress = [ ] # These outputs should be unsolvable after importaddress
solvable_anytime = [ ] # These outputs should be solvable after importpubkey
unseen_anytime = [ ] # These outputs should never be seen
2017-09-29 06:21:28 +02:00
uncompressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ uncompressed_spendable_address [ 0 ] , compressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
uncompressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ uncompressed_spendable_address [ 0 ] , uncompressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
compressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_spendable_address [ 0 ] , compressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
uncompressed_solvable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_spendable_address [ 0 ] , uncompressed_solvable_address [ 0 ] ] ) [ ' address ' ] )
compressed_solvable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_spendable_address [ 0 ] , compressed_solvable_address [ 0 ] ] ) [ ' address ' ] )
compressed_solvable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_solvable_address [ 0 ] , compressed_solvable_address [ 1 ] ] ) [ ' address ' ] )
2016-10-14 20:29:39 +02:00
# Test multisig_without_privkey
# We have 2 public keys without private keys, use addmultisigaddress to add to wallet.
# Money sent to P2SH of multisig of this should only be seen after importaddress with the BASE58 P2SH address.
2017-09-29 06:21:28 +02:00
multisig_without_privkey_address = self . nodes [ 0 ] . addmultisigaddress ( 2 , [ pubkeys [ 3 ] , pubkeys [ 4 ] ] ) [ ' address ' ]
2016-10-14 20:29:39 +02:00
script = CScript ( [ OP_2 , hex_str_to_bytes ( pubkeys [ 3 ] ) , hex_str_to_bytes ( pubkeys [ 4 ] ) , OP_2 , OP_CHECKMULTISIG ] )
2021-06-27 23:52:38 +02:00
solvable_after_importaddress . append ( script_to_p2sh_script ( script ) )
2016-10-14 20:29:39 +02:00
for i in compressed_spendable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
2018-04-17 02:18:34 +02:00
# p2sh multisig with compressed keys should always be spendable
spendable_anytime . extend ( [ p2sh ] )
# bare multisig can be watched and signed, but is not treated as ours
solvable_after_importaddress . extend ( [ bare ] )
2016-10-14 20:29:39 +02:00
# P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after direct importaddress
spendable_after_importaddress . extend ( [ p2wsh , p2sh_p2wsh ] )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
# normal P2PKH and P2PK with compressed keys should always be spendable
spendable_anytime . extend ( [ p2pkh , p2pk ] )
2017-12-01 01:49:04 +01:00
# P2SH_P2PK, P2SH_P2PKH with compressed keys are spendable after direct importaddress
spendable_after_importaddress . extend ( [ p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] )
# P2WPKH and P2SH_P2WPKH with compressed keys should always be spendable
spendable_anytime . extend ( [ p2wpkh , p2sh_p2wpkh ] )
2016-10-14 20:29:39 +02:00
for i in uncompressed_spendable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
2018-04-17 02:18:34 +02:00
# p2sh multisig with uncompressed keys should always be spendable
spendable_anytime . extend ( [ p2sh ] )
# bare multisig can be watched and signed, but is not treated as ours
solvable_after_importaddress . extend ( [ bare ] )
2016-10-14 20:29:39 +02:00
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
unseen_anytime . extend ( [ p2wsh , p2sh_p2wsh ] )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
# normal P2PKH and P2PK with uncompressed keys should always be spendable
spendable_anytime . extend ( [ p2pkh , p2pk ] )
# P2SH_P2PK and P2SH_P2PKH are spendable after direct importaddress
spendable_after_importaddress . extend ( [ p2sh_p2pk , p2sh_p2pkh ] )
2017-12-01 01:49:04 +01:00
# Witness output types with uncompressed keys are never seen
2016-10-14 20:29:39 +02:00
unseen_anytime . extend ( [ p2wpkh , p2sh_p2wpkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] )
for i in compressed_solvable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
# Multisig without private is not seen after addmultisigaddress, but seen after importaddress
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
solvable_after_importaddress . extend ( [ bare , p2sh , p2wsh , p2sh_p2wsh ] )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
2017-12-01 01:49:04 +01:00
# normal P2PKH, P2PK, P2WPKH and P2SH_P2WPKH with compressed keys should always be seen
solvable_anytime . extend ( [ p2pkh , p2pk , p2wpkh , p2sh_p2wpkh ] )
# P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after direct importaddress
solvable_after_importaddress . extend ( [ p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] )
2016-10-14 20:29:39 +02:00
for i in uncompressed_solvable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
# Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress
solvable_after_importaddress . extend ( [ bare , p2sh ] )
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
unseen_anytime . extend ( [ p2wsh , p2sh_p2wsh ] )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
# normal P2PKH and P2PK with uncompressed keys should always be seen
solvable_anytime . extend ( [ p2pkh , p2pk ] )
# P2SH_P2PK, P2SH_P2PKH with uncompressed keys are seen after direct importaddress
solvable_after_importaddress . extend ( [ p2sh_p2pk , p2sh_p2pkh ] )
2017-12-01 01:49:04 +01:00
# Witness output types with uncompressed keys are never seen
2016-10-14 20:29:39 +02:00
unseen_anytime . extend ( [ p2wpkh , p2sh_p2wpkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] )
op1 = CScript ( [ OP_1 ] )
op0 = CScript ( [ OP_0 ] )
# 2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe is the P2SH(P2PKH) version of mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V
unsolvable_address_key = hex_str_to_bytes ( " 02341AEC7587A51CDE5279E0630A531AEA2615A9F80B17E8D9376327BAEAA59E3D " )
2021-06-27 23:03:40 +02:00
unsolvablep2pkh = key_to_p2pkh_script ( unsolvable_address_key )
2021-06-28 20:45:04 +02:00
unsolvablep2wshp2pkh = script_to_p2wsh_script ( unsolvablep2pkh )
2021-06-27 23:52:38 +02:00
p2shop0 = script_to_p2sh_script ( op0 )
2021-06-28 20:45:04 +02:00
p2wshop1 = script_to_p2wsh_script ( op1 )
2016-10-14 20:29:39 +02:00
unsolvable_after_importaddress . append ( unsolvablep2pkh )
unsolvable_after_importaddress . append ( unsolvablep2wshp2pkh )
2018-09-23 14:50:47 +02:00
unsolvable_after_importaddress . append ( op1 ) # OP_1 will be imported as script
2016-10-14 20:29:39 +02:00
unsolvable_after_importaddress . append ( p2wshop1 )
2018-09-23 14:50:47 +02:00
unseen_anytime . append ( op0 ) # OP_0 will be imported as P2SH address with no script provided
2016-10-14 20:29:39 +02:00
unsolvable_after_importaddress . append ( p2shop0 )
spendable_txid = [ ]
solvable_txid = [ ]
spendable_txid . append ( self . mine_and_test_listunspent ( spendable_anytime , 2 ) )
solvable_txid . append ( self . mine_and_test_listunspent ( solvable_anytime , 1 ) )
self . mine_and_test_listunspent ( spendable_after_importaddress + solvable_after_importaddress + unseen_anytime + unsolvable_after_importaddress , 0 )
importlist = [ ]
for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
bare = hex_str_to_bytes ( v [ ' hex ' ] )
2019-02-18 16:35:48 +01:00
importlist . append ( bare . hex ( ) )
2021-06-28 20:45:04 +02:00
importlist . append ( script_to_p2wsh_script ( bare ) . hex ( ) )
2016-10-14 20:29:39 +02:00
else :
pubkey = hex_str_to_bytes ( v [ ' pubkey ' ] )
p2pk = CScript ( [ pubkey , OP_CHECKSIG ] )
2021-06-27 23:03:40 +02:00
p2pkh = key_to_p2pkh_script ( pubkey )
2019-02-18 16:35:48 +01:00
importlist . append ( p2pk . hex ( ) )
importlist . append ( p2pkh . hex ( ) )
2021-06-28 20:45:04 +02:00
importlist . append ( key_to_p2wpkh_script ( pubkey ) . hex ( ) )
importlist . append ( script_to_p2wsh_script ( p2pk ) . hex ( ) )
importlist . append ( script_to_p2wsh_script ( p2pkh ) . hex ( ) )
2016-10-14 20:29:39 +02:00
2019-02-18 16:35:48 +01:00
importlist . append ( unsolvablep2pkh . hex ( ) )
importlist . append ( unsolvablep2wshp2pkh . hex ( ) )
importlist . append ( op1 . hex ( ) )
importlist . append ( p2wshop1 . hex ( ) )
2016-10-14 20:29:39 +02:00
for i in importlist :
2017-03-07 20:08:59 +01:00
# import all generated addresses. The wallet already has the private keys for some of these, so catch JSON RPC
# exceptions and continue.
2017-07-12 16:29:02 +02:00
try_rpc ( - 4 , " The wallet already contains the private key for this address or script " , self . nodes [ 0 ] . importaddress , i , " " , False , True )
2016-10-14 20:29:39 +02:00
2018-09-23 14:50:47 +02:00
self . nodes [ 0 ] . importaddress ( script_to_p2sh ( op0 ) ) # import OP_0 as address only
self . nodes [ 0 ] . importaddress ( multisig_without_privkey_address ) # Test multisig_without_privkey
2016-10-14 20:29:39 +02:00
spendable_txid . append ( self . mine_and_test_listunspent ( spendable_anytime + spendable_after_importaddress , 2 ) )
solvable_txid . append ( self . mine_and_test_listunspent ( solvable_anytime + solvable_after_importaddress , 1 ) )
self . mine_and_test_listunspent ( unsolvable_after_importaddress , 1 )
self . mine_and_test_listunspent ( unseen_anytime , 0 )
spendable_txid . append ( self . mine_and_test_listunspent ( spendable_anytime + spendable_after_importaddress , 2 ) )
solvable_txid . append ( self . mine_and_test_listunspent ( solvable_anytime + solvable_after_importaddress , 1 ) )
self . mine_and_test_listunspent ( unsolvable_after_importaddress , 1 )
self . mine_and_test_listunspent ( unseen_anytime , 0 )
# Repeat some tests. This time we don't add witness scripts with importaddress
# Import a compressed key and an uncompressed key, generate some multisig addresses
self . nodes [ 0 ] . importprivkey ( " 927pw6RW8ZekycnXqBQ2JS5nPyo1yRfGNN8oq74HeddWSpafDJH " )
uncompressed_spendable_address = [ " mguN2vNSCEUh6rJaXoAVwY3YZwZvEmf5xi " ]
self . nodes [ 0 ] . importprivkey ( " cMcrXaaUC48ZKpcyydfFo8PxHAjpsYLhdsp6nmtB3E2ER9UUHWnw " )
compressed_spendable_address = [ " n1UNmpmbVUJ9ytXYXiurmGPQ3TRrXqPWKL " ]
self . nodes [ 0 ] . importpubkey ( pubkeys [ 5 ] )
compressed_solvable_address = [ key_to_p2pkh ( pubkeys [ 5 ] ) ]
self . nodes [ 0 ] . importpubkey ( pubkeys [ 6 ] )
uncompressed_solvable_address = [ key_to_p2pkh ( pubkeys [ 6 ] ) ]
unseen_anytime = [ ] # These outputs should never be seen
2017-12-01 01:49:04 +01:00
solvable_anytime = [ ] # These outputs should be solvable after importpubkey
unseen_anytime = [ ] # These outputs should never be seen
2016-10-14 20:29:39 +02:00
2017-09-29 06:21:28 +02:00
uncompressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ uncompressed_spendable_address [ 0 ] , compressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
uncompressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ uncompressed_spendable_address [ 0 ] , uncompressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
compressed_spendable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_spendable_address [ 0 ] , compressed_spendable_address [ 0 ] ] ) [ ' address ' ] )
uncompressed_solvable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_solvable_address [ 0 ] , uncompressed_solvable_address [ 0 ] ] ) [ ' address ' ] )
compressed_solvable_address . append ( self . nodes [ 0 ] . addmultisigaddress ( 2 , [ compressed_spendable_address [ 0 ] , compressed_solvable_address [ 0 ] ] ) [ ' address ' ] )
2016-10-14 20:29:39 +02:00
premature_witaddress = [ ]
for i in compressed_spendable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
premature_witaddress . append ( script_to_p2sh ( p2wsh ) )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
2017-12-01 01:49:04 +01:00
# P2WPKH, P2SH_P2WPKH are always spendable
spendable_anytime . extend ( [ p2wpkh , p2sh_p2wpkh ] )
2016-10-14 20:29:39 +02:00
for i in uncompressed_spendable_address + uncompressed_solvable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
unseen_anytime . extend ( [ p2wsh , p2sh_p2wsh ] )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
# P2WPKH, P2SH_P2WPKH with uncompressed keys are never seen
unseen_anytime . extend ( [ p2wpkh , p2sh_p2wpkh ] )
for i in compressed_solvable_address :
2018-02-09 17:12:27 +01:00
v = self . nodes [ 0 ] . getaddressinfo ( i )
2016-10-14 20:29:39 +02:00
if ( v [ ' isscript ' ] ) :
[ bare , p2sh , p2wsh , p2sh_p2wsh ] = self . p2sh_address_to_script ( v )
premature_witaddress . append ( script_to_p2sh ( p2wsh ) )
else :
[ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ] = self . p2pkh_address_to_script ( v )
2017-12-01 01:49:04 +01:00
# P2SH_P2PK, P2SH_P2PKH with compressed keys are always solvable
solvable_anytime . extend ( [ p2wpkh , p2sh_p2wpkh ] )
2016-10-14 20:29:39 +02:00
2017-12-01 01:49:04 +01:00
self . mine_and_test_listunspent ( spendable_anytime , 2 )
self . mine_and_test_listunspent ( solvable_anytime , 1 )
2016-10-14 20:29:39 +02:00
self . mine_and_test_listunspent ( unseen_anytime , 0 )
2017-08-27 09:41:46 +02:00
# Check that createrawtransaction/decoderawtransaction with non-v0 Bech32 works
2018-09-23 14:50:47 +02:00
v1_addr = program_to_witness ( 1 , [ 3 , 5 ] )
v1_tx = self . nodes [ 0 ] . createrawtransaction ( [ getutxo ( spendable_txid [ 0 ] ) ] , { v1_addr : 1 } )
2017-08-27 09:41:46 +02:00
v1_decoded = self . nodes [ 1 ] . decoderawtransaction ( v1_tx )
2021-02-01 16:52:07 +01:00
assert_equal ( v1_decoded [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' address ' ] , v1_addr )
2017-08-27 09:41:46 +02:00
assert_equal ( v1_decoded [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' hex ' ] , " 51020305 " )
2016-10-14 20:29:39 +02:00
# Check that spendable outputs are really spendable
self . create_and_mine_tx_from_txids ( spendable_txid )
# import all the private keys so solvable addresses become spendable
self . nodes [ 0 ] . importprivkey ( " cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb " )
self . nodes [ 0 ] . importprivkey ( " cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97 " )
self . nodes [ 0 ] . importprivkey ( " 91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV " )
self . nodes [ 0 ] . importprivkey ( " cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd " )
self . nodes [ 0 ] . importprivkey ( " cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66 " )
self . nodes [ 0 ] . importprivkey ( " cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K " )
self . create_and_mine_tx_from_txids ( solvable_txid )
2017-09-10 21:37:38 +02:00
# Test that importing native P2WPKH/P2WSH scripts works
for use_p2wsh in [ False , True ] :
if use_p2wsh :
scriptPubKey = " 00203a59f3f56b713fdcf5d1a57357f02c44342cbf306ffe0c4741046837bf90561a "
transaction = " 01000000000100e1f505000000002200203a59f3f56b713fdcf5d1a57357f02c44342cbf306ffe0c4741046837bf90561a00000000 "
else :
scriptPubKey = " a9142f8c469c2f0084c48e11f998ffbe7efa7549f26d87 "
transaction = " 01000000000100e1f5050000000017a9142f8c469c2f0084c48e11f998ffbe7efa7549f26d8700000000 "
self . nodes [ 1 ] . importaddress ( scriptPubKey , " " , False )
rawtxfund = self . nodes [ 1 ] . fundrawtransaction ( transaction ) [ ' hex ' ]
2017-09-06 01:49:18 +02:00
rawtxfund = self . nodes [ 1 ] . signrawtransactionwithwallet ( rawtxfund ) [ " hex " ]
2017-09-10 21:37:38 +02:00
txid = self . nodes [ 1 ] . sendrawtransaction ( rawtxfund )
assert_equal ( self . nodes [ 1 ] . gettransaction ( txid , True ) [ " txid " ] , txid )
assert_equal ( self . nodes [ 1 ] . listtransactions ( " * " , 1 , 0 , True ) [ 0 ] [ " txid " ] , txid )
# Assert it is properly saved
2020-06-22 00:32:32 +02:00
self . restart_node ( 1 )
2017-09-10 21:37:38 +02:00
assert_equal ( self . nodes [ 1 ] . gettransaction ( txid , True ) [ " txid " ] , txid )
assert_equal ( self . nodes [ 1 ] . listtransactions ( " * " , 1 , 0 , True ) [ 0 ] [ " txid " ] , txid )
2016-10-14 20:29:39 +02:00
def mine_and_test_listunspent ( self , script_list , ismine ) :
2017-09-01 01:57:45 +02:00
utxo = find_spendable_utxo ( self . nodes [ 0 ] , 50 )
2016-10-14 20:29:39 +02:00
tx = CTransaction ( )
2018-09-23 14:50:47 +02:00
tx . vin . append ( CTxIn ( COutPoint ( int ( ' 0x ' + utxo [ ' txid ' ] , 0 ) , utxo [ ' vout ' ] ) ) )
2016-10-14 20:29:39 +02:00
for i in script_list :
tx . vout . append ( CTxOut ( 10000000 , i ) )
tx . rehash ( )
2019-02-18 16:35:48 +01:00
signresults = self . nodes [ 0 ] . signrawtransactionwithwallet ( tx . serialize_without_witness ( ) . hex ( ) ) [ ' hex ' ]
2019-09-21 16:03:28 +02:00
txid = self . nodes [ 0 ] . sendrawtransaction ( hexstring = signresults , maxfeerate = 0 )
2019-02-14 04:22:40 +01:00
txs_mined [ txid ] = self . nodes [ 0 ] . generate ( 1 ) [ 0 ]
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-10-14 20:29:39 +02:00
watchcount = 0
spendcount = 0
for i in self . nodes [ 0 ] . listunspent ( ) :
if ( i [ ' txid ' ] == txid ) :
watchcount + = 1
2018-09-23 14:50:47 +02:00
if i [ ' spendable ' ] :
2016-10-14 20:29:39 +02:00
spendcount + = 1
if ( ismine == 2 ) :
assert_equal ( spendcount , len ( script_list ) )
elif ( ismine == 1 ) :
assert_equal ( watchcount , len ( script_list ) )
assert_equal ( spendcount , 0 )
else :
assert_equal ( watchcount , 0 )
return txid
2018-09-23 14:50:47 +02:00
def p2sh_address_to_script ( self , v ) :
2016-10-14 20:29:39 +02:00
bare = CScript ( hex_str_to_bytes ( v [ ' hex ' ] ) )
p2sh = CScript ( hex_str_to_bytes ( v [ ' scriptPubKey ' ] ) )
2021-06-28 20:45:04 +02:00
p2wsh = script_to_p2wsh_script ( bare )
2021-06-27 23:52:38 +02:00
p2sh_p2wsh = script_to_p2sh_script ( p2wsh )
2016-10-14 20:29:39 +02:00
return ( [ bare , p2sh , p2wsh , p2sh_p2wsh ] )
2018-09-23 14:50:47 +02:00
def p2pkh_address_to_script ( self , v ) :
2016-10-14 20:29:39 +02:00
pubkey = hex_str_to_bytes ( v [ ' pubkey ' ] )
2021-06-28 20:45:04 +02:00
p2wpkh = key_to_p2wpkh_script ( pubkey )
2021-06-27 23:52:38 +02:00
p2sh_p2wpkh = script_to_p2sh_script ( p2wpkh )
2016-10-14 20:29:39 +02:00
p2pk = CScript ( [ pubkey , OP_CHECKSIG ] )
p2pkh = CScript ( hex_str_to_bytes ( v [ ' scriptPubKey ' ] ) )
2021-06-27 23:52:38 +02:00
p2sh_p2pk = script_to_p2sh_script ( p2pk )
p2sh_p2pkh = script_to_p2sh_script ( p2pkh )
2021-06-28 20:45:04 +02:00
p2wsh_p2pk = script_to_p2wsh_script ( p2pk )
p2wsh_p2pkh = script_to_p2wsh_script ( p2pkh )
2021-06-27 23:52:38 +02:00
p2sh_p2wsh_p2pk = script_to_p2sh_script ( p2wsh_p2pk )
p2sh_p2wsh_p2pkh = script_to_p2sh_script ( p2wsh_p2pkh )
2016-10-14 20:29:39 +02:00
return [ p2wpkh , p2sh_p2wpkh , p2pk , p2pkh , p2sh_p2pk , p2sh_p2pkh , p2wsh_p2pk , p2wsh_p2pkh , p2sh_p2wsh_p2pk , p2sh_p2wsh_p2pkh ]
2018-09-23 14:50:47 +02:00
def create_and_mine_tx_from_txids ( self , txids , success = True ) :
2016-10-14 20:29:39 +02:00
tx = CTransaction ( )
for i in txids :
2019-02-14 04:22:40 +01:00
txraw = self . nodes [ 0 ] . getrawtransaction ( i , 0 , txs_mined [ i ] )
2021-06-15 23:02:28 +02:00
txtmp = tx_from_hex ( txraw )
2016-10-14 20:29:39 +02:00
for j in range ( len ( txtmp . vout ) ) :
2018-09-23 14:50:47 +02:00
tx . vin . append ( CTxIn ( COutPoint ( int ( ' 0x ' + i , 0 ) , j ) ) )
2016-10-14 20:29:39 +02:00
tx . vout . append ( CTxOut ( 0 , CScript ( ) ) )
tx . rehash ( )
2019-02-18 16:35:48 +01:00
signresults = self . nodes [ 0 ] . signrawtransactionwithwallet ( tx . serialize_without_witness ( ) . hex ( ) ) [ ' hex ' ]
2019-09-21 16:03:28 +02:00
self . nodes [ 0 ] . sendrawtransaction ( hexstring = signresults , maxfeerate = 0 )
2016-10-14 20:29:39 +02:00
self . nodes [ 0 ] . generate ( 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-10-14 20:29:39 +02:00
2016-01-02 06:18:34 +01:00
if __name__ == ' __main__ ' :
SegWitTest ( ) . main ( )