2016-04-09 03:02:24 +02:00
#!/usr/bin/env python3
2020-04-16 19:14:08 +02:00
# Copyright (c) 2016-2020 The Bitcoin Core developers
2016-04-09 03:02:24 +02: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 segwit transactions and blocks on P2P network. """
2020-05-24 14:58:56 +02:00
from decimal import Decimal
2018-06-13 17:56:20 +02:00
import random
import struct
import time
2016-04-09 03:02:24 +02:00
2021-02-05 21:10:39 +01:00
from test_framework . blocktools import create_block , create_coinbase , add_witness_commitment , WITNESS_COMMITMENT_HEADER
2019-04-16 01:49:18 +02:00
from test_framework . key import ECKey
2018-06-13 17:56:20 +02:00
from test_framework . messages import (
BIP125_SEQUENCE_NUMBER ,
CBlockHeader ,
CInv ,
COutPoint ,
CTransaction ,
CTxIn ,
CTxInWitness ,
CTxOut ,
CTxWitness ,
2021-07-01 01:43:45 +02:00
MAX_BLOCK_WEIGHT ,
2020-04-25 13:44:44 +02:00
MSG_BLOCK ,
MSG_TX ,
2018-06-13 17:56:20 +02:00
MSG_WITNESS_FLAG ,
2020-08-08 13:22:19 +02:00
MSG_WITNESS_TX ,
2020-03-27 02:13:32 +01:00
MSG_WTX ,
2018-06-13 17:56:20 +02:00
NODE_NETWORK ,
NODE_WITNESS ,
tests: Make msg_block a witness block
This diff has been generated with the following script, but is better
reviewed without looking at the script.
# -BEGIN VERIFY SCRIPT-
echo "Use msg_witness_block everywhere, except for tests that require msg_block"
# This could be a separate commit, but it is combined with the
# following scripts to reduce the overall diff
sed -i -e 's/msg_block/msg_witness_block/g' ./test/functional/{feature_assumevalid,feature_cltv,feature_dersig,feature_versionbits_warning,p2p_fingerprint,p2p_sendheaders,p2p_unrequested_blocks,example_test,rpc_blockchain}.py
echo "Rename msg_block to msg_no_witness_block"
# Rename msg_block to msg_no_witness_block in all tests (not the
# framework)
sed -i -e 's/msg_block/msg_no_witness_block/g' $(git grep -l msg_block ./test/functional/*.py)
# Derive msg_no_witness_block from msg_block
# Make msg_block a witness block in messages.py
patch -p1 --fuzz 0 << EOF
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 00190e4cbd..e454ed5987 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1133 +1133 @@ class msg_block:
- return self.block.serialize(with_witness=False)
+ return self.block.serialize()
@@ -1155 +1155 @@ class msg_generic:
-class msg_witness_block(msg_block):
+class msg_no_witness_block(msg_block):
@@ -1158,2 +1158 @@ class msg_witness_block(msg_block):
- r = self.block.serialize()
- return r
+ return self.block.serialize(with_witness=False)
@@ -1445 +1444 @@ class msg_blocktxn:
- r += self.block_transactions.serialize(with_witness=False)
+ r += self.block_transactions.serialize()
@@ -1452 +1451 @@ class msg_blocktxn:
-class msg_witness_blocktxn(msg_blocktxn):
+class msg_no_witness_blocktxn(msg_blocktxn):
@@ -1456,3 +1455 @@ class msg_witness_blocktxn(msg_blocktxn):
- r = b""
- r += self.block_transactions.serialize()
- return r
+ return self.block_transactions.serialize(with_witness=False)
EOF
# Conclude rename of msg_block to msg_no_witness_block
sed -i -e 's/msg_witness_block/msg_block/g' $(git grep -l msg_witness_block)
# -END VERIFY SCRIPT-
2019-05-08 16:21:25 +02:00
msg_no_witness_block ,
2018-06-13 17:56:20 +02:00
msg_getdata ,
msg_headers ,
msg_inv ,
msg_tx ,
tests: Make msg_block a witness block
This diff has been generated with the following script, but is better
reviewed without looking at the script.
# -BEGIN VERIFY SCRIPT-
echo "Use msg_witness_block everywhere, except for tests that require msg_block"
# This could be a separate commit, but it is combined with the
# following scripts to reduce the overall diff
sed -i -e 's/msg_block/msg_witness_block/g' ./test/functional/{feature_assumevalid,feature_cltv,feature_dersig,feature_versionbits_warning,p2p_fingerprint,p2p_sendheaders,p2p_unrequested_blocks,example_test,rpc_blockchain}.py
echo "Rename msg_block to msg_no_witness_block"
# Rename msg_block to msg_no_witness_block in all tests (not the
# framework)
sed -i -e 's/msg_block/msg_no_witness_block/g' $(git grep -l msg_block ./test/functional/*.py)
# Derive msg_no_witness_block from msg_block
# Make msg_block a witness block in messages.py
patch -p1 --fuzz 0 << EOF
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 00190e4cbd..e454ed5987 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1133 +1133 @@ class msg_block:
- return self.block.serialize(with_witness=False)
+ return self.block.serialize()
@@ -1155 +1155 @@ class msg_generic:
-class msg_witness_block(msg_block):
+class msg_no_witness_block(msg_block):
@@ -1158,2 +1158 @@ class msg_witness_block(msg_block):
- r = self.block.serialize()
- return r
+ return self.block.serialize(with_witness=False)
@@ -1445 +1444 @@ class msg_blocktxn:
- r += self.block_transactions.serialize(with_witness=False)
+ r += self.block_transactions.serialize()
@@ -1452 +1451 @@ class msg_blocktxn:
-class msg_witness_blocktxn(msg_blocktxn):
+class msg_no_witness_blocktxn(msg_blocktxn):
@@ -1456,3 +1455 @@ class msg_witness_blocktxn(msg_blocktxn):
- r = b""
- r += self.block_transactions.serialize()
- return r
+ return self.block_transactions.serialize(with_witness=False)
EOF
# Conclude rename of msg_block to msg_no_witness_block
sed -i -e 's/msg_witness_block/msg_block/g' $(git grep -l msg_witness_block)
# -END VERIFY SCRIPT-
2019-05-08 16:21:25 +02:00
msg_block ,
2020-01-23 15:02:02 +01:00
msg_no_witness_tx ,
2018-06-13 17:56:20 +02:00
ser_uint256 ,
ser_vector ,
sha256 ,
2021-06-15 23:02:28 +02:00
tx_from_hex ,
2018-06-13 17:56:20 +02:00
)
2020-07-19 09:47:05 +02:00
from test_framework . p2p import (
2018-06-13 17:56:20 +02:00
P2PInterface ,
2020-07-19 09:47:05 +02:00
p2p_lock ,
2021-09-19 14:11:09 +02:00
P2P_SERVICES ,
2018-06-13 17:56:20 +02:00
)
from test_framework . script import (
CScript ,
CScriptNum ,
CScriptOp ,
2018-07-11 18:17:08 +02:00
MAX_SCRIPT_ELEMENT_SIZE ,
2018-06-13 17:56:20 +02:00
OP_0 ,
OP_1 ,
2020-09-11 23:34:10 +02:00
OP_2 ,
2018-06-13 17:56:20 +02:00
OP_16 ,
OP_2DROP ,
OP_CHECKMULTISIG ,
OP_CHECKSIG ,
OP_DROP ,
OP_ELSE ,
OP_ENDIF ,
OP_IF ,
OP_RETURN ,
OP_TRUE ,
SIGHASH_ALL ,
SIGHASH_ANYONECANPAY ,
SIGHASH_NONE ,
SIGHASH_SINGLE ,
2019-10-14 23:04:34 +02:00
SegwitV0SignatureHash ,
LegacySignatureHash ,
2018-06-13 17:56:20 +02:00
hash160 ,
)
2021-06-27 23:03:40 +02:00
from test_framework . script_util import (
2021-06-28 20:45:04 +02:00
key_to_p2wpkh_script ,
2021-06-27 23:03:40 +02:00
keyhash_to_p2pkh_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-06-13 17:56:20 +02:00
from test_framework . test_framework import BitcoinTestFramework
from test_framework . util import (
assert_equal ,
2019-05-20 20:59:07 +02:00
softfork_active ,
2019-03-21 18:47:47 +01:00
assert_raises_rpc_error ,
2018-06-13 17:56:20 +02:00
)
2016-04-09 03:02:24 +02:00
MAX_SIGOP_COST = 80000
2019-05-20 20:59:07 +02:00
SEGWIT_HEIGHT = 120
2018-06-13 20:26:25 +02:00
class UTXO ( ) :
""" Used to keep track of anyone-can-spend outputs that we can use in the tests. """
def __init__ ( self , sha256 , n , value ) :
self . sha256 = sha256
self . n = n
self . nValue = value
def sign_p2pk_witness_input ( script , tx_to , in_idx , hashtype , value , key ) :
2021-07-11 15:51:48 +02:00
""" Add signature for a P2PK witness script. """
2019-10-14 23:04:34 +02:00
tx_hash = SegwitV0SignatureHash ( script , tx_to , in_idx , hashtype , value )
2019-04-16 01:49:18 +02:00
signature = key . sign_ecdsa ( tx_hash ) + chr ( hashtype ) . encode ( ' latin-1 ' )
2018-06-13 20:26:25 +02:00
tx_to . wit . vtxinwit [ in_idx ] . scriptWitness . stack = [ signature , script ]
tx_to . rehash ( )
2016-04-09 03:02:24 +02:00
2018-08-29 18:42:46 +02:00
def test_transaction_acceptance ( node , p2p , tx , with_witness , accepted , reason = None ) :
2017-10-17 14:02:15 +02:00
""" Send a transaction to the node and check that it ' s accepted to the mempool
- Submit the transaction over the p2p interface
- use the getrawmempool rpc to check for acceptance . """
2018-08-24 21:26:42 +02:00
reason = [ reason ] if reason else [ ]
with node . assert_debug_log ( expected_msgs = reason ) :
2020-04-03 22:11:08 +02:00
p2p . send_and_ping ( msg_tx ( tx ) if with_witness else msg_no_witness_tx ( tx ) )
2018-08-24 21:26:42 +02:00
assert_equal ( tx . hash in node . getrawmempool ( ) , accepted )
2017-10-17 14:02:15 +02:00
2020-01-23 15:02:02 +01:00
2018-08-29 18:42:46 +02:00
def test_witness_block ( node , p2p , block , accepted , with_witness = True , reason = None ) :
2017-10-17 14:02:15 +02:00
""" Send a block to the node and check that it ' s accepted
- Submit the block over the p2p interface
- use the getbestblockhash rpc to check for acceptance . """
2018-08-24 21:26:42 +02:00
reason = [ reason ] if reason else [ ]
with node . assert_debug_log ( expected_msgs = reason ) :
2020-04-03 22:11:08 +02:00
p2p . send_and_ping ( msg_block ( block ) if with_witness else msg_no_witness_block ( block ) )
2018-08-24 21:26:42 +02:00
assert_equal ( node . getbestblockhash ( ) == block . hash , accepted )
2017-10-17 14:02:15 +02:00
2018-02-07 15:22:58 +01:00
class TestP2PConn ( P2PInterface ) :
2020-03-27 02:13:32 +01:00
def __init__ ( self , wtxidrelay = False ) :
2020-10-17 17:20:43 +02:00
super ( ) . __init__ ( wtxidrelay = wtxidrelay )
2016-04-09 03:02:24 +02:00
self . getdataset = set ( )
2020-03-27 02:13:32 +01:00
self . last_wtxidrelay = [ ]
self . lastgetdata = [ ]
self . wtxidrelay = wtxidrelay
2016-04-09 03:02:24 +02:00
2020-08-17 11:10:44 +02:00
# Don't send getdata message replies to invs automatically.
# We'll send the getdata messages explicitly in the test logic.
2020-02-27 21:25:49 +01:00
def on_inv ( self , message ) :
pass
2017-11-17 21:01:24 +01:00
def on_getdata ( self , message ) :
2020-03-27 02:13:32 +01:00
self . lastgetdata = message . inv
2016-04-09 03:02:24 +02:00
for inv in message . inv :
self . getdataset . add ( inv . hash )
2020-03-27 02:13:32 +01:00
def on_wtxidrelay ( self , message ) :
self . last_wtxidrelay . append ( message )
2021-04-29 10:17:56 +02:00
def announce_tx_and_wait_for_getdata ( self , tx , success = True , use_wtxid = False ) :
2020-08-03 05:29:11 +02:00
if success :
# sanity check
assert ( self . wtxidrelay and use_wtxid ) or ( not self . wtxidrelay and not use_wtxid )
2020-07-19 09:47:05 +02:00
with p2p_lock :
2017-03-30 14:38:46 +02:00
self . last_message . pop ( " getdata " , None )
2020-03-27 02:13:32 +01:00
if use_wtxid :
wtxid = tx . calc_sha256 ( True )
self . send_message ( msg_inv ( inv = [ CInv ( MSG_WTX , wtxid ) ] ) )
else :
self . send_message ( msg_inv ( inv = [ CInv ( MSG_TX , tx . sha256 ) ] ) )
2018-05-09 21:42:41 +02:00
if success :
2020-03-27 02:13:32 +01:00
if use_wtxid :
2021-04-29 10:17:56 +02:00
self . wait_for_getdata ( [ wtxid ] )
2020-03-27 02:13:32 +01:00
else :
2021-04-29 10:17:56 +02:00
self . wait_for_getdata ( [ tx . sha256 ] )
2018-05-09 21:42:41 +02:00
else :
2021-04-29 10:17:56 +02:00
time . sleep ( 5 )
2018-05-09 21:42:41 +02:00
assert not self . last_message . get ( " getdata " )
2016-04-09 03:02:24 +02:00
def announce_block_and_wait_for_getdata ( self , block , use_header , timeout = 60 ) :
2020-07-19 09:47:05 +02:00
with p2p_lock :
2017-03-30 14:38:46 +02:00
self . last_message . pop ( " getdata " , None )
self . last_message . pop ( " getheaders " , None )
2016-10-04 00:30:52 +02:00
msg = msg_headers ( )
2018-06-13 17:56:20 +02:00
msg . headers = [ CBlockHeader ( block ) ]
2016-04-09 03:02:24 +02:00
if use_header :
self . send_message ( msg )
else :
2020-04-25 13:44:44 +02:00
self . send_message ( msg_inv ( inv = [ CInv ( MSG_BLOCK , block . sha256 ) ] ) )
2016-10-04 00:30:52 +02:00
self . wait_for_getheaders ( )
self . send_message ( msg )
2020-04-17 11:23:02 +02:00
self . wait_for_getdata ( [ block . sha256 ] )
2016-04-09 03:02:24 +02:00
def request_block ( self , blockhash , inv_type , timeout = 60 ) :
2020-07-19 09:47:05 +02:00
with p2p_lock :
2017-03-30 14:38:46 +02:00
self . last_message . pop ( " block " , None )
2016-04-09 03:02:24 +02:00
self . send_message ( msg_getdata ( inv = [ CInv ( inv_type , blockhash ) ] ) )
self . wait_for_block ( blockhash , timeout )
2017-03-30 14:38:46 +02:00
return self . last_message [ " block " ] . block
2016-04-09 03:02:24 +02: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
2021-02-05 21:10:39 +01:00
self . num_nodes = 2
2017-10-12 05:25:18 +02:00
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
2019-04-24 23:55:58 +02:00
self . extra_args = [
2021-08-27 12:54:24 +02:00
[ " -acceptnonstdtxn=1 " , f " -testactivationheight=segwit@ { SEGWIT_HEIGHT } " , " -whitelist=noban@127.0.0.1 " ] ,
[ " -acceptnonstdtxn=0 " , f " -testactivationheight=segwit@ { SEGWIT_HEIGHT } " ] ,
2019-04-24 23:55:58 +02:00
]
2019-12-06 15:37:49 +01:00
self . supports_cli = False
2016-04-09 03:02:24 +02:00
2018-09-09 19:32:37 +02:00
def skip_test_if_missing_module ( self ) :
self . skip_if_no_wallet ( )
2018-06-13 20:16:28 +02:00
# Helper functions
2021-08-27 16:36:17 +02:00
def build_next_block ( self ) :
2018-06-13 20:16:28 +02:00
""" Build a block on top of node0 ' s tip. """
2016-04-09 03:02:24 +02:00
tip = self . nodes [ 0 ] . getbestblockhash ( )
height = self . nodes [ 0 ] . getblockcount ( ) + 1
block_time = self . nodes [ 0 ] . getblockheader ( tip ) [ " mediantime " ] + 1
block = create_block ( int ( tip , 16 ) , create_coinbase ( height ) , block_time )
2021-08-27 16:36:17 +02:00
block . nVersion = 4
2016-04-09 03:02:24 +02:00
block . rehash ( )
return block
def update_witness_block_with_transactions ( self , block , tx_list , nonce = 0 ) :
2018-06-13 20:16:28 +02:00
""" Add list of transactions to block, adds witness commitment, then solves. """
2016-04-09 03:02:24 +02:00
block . vtx . extend ( tx_list )
add_witness_commitment ( block , nonce )
block . solve ( )
2018-06-13 20:26:25 +02:00
def run_test ( self ) :
2018-07-10 22:20:24 +02:00
# Setup the p2p connections
2021-09-19 14:11:09 +02:00
# self.test_node sets P2P_SERVICES, i.e. NODE_WITNESS | NODE_NETWORK
self . test_node = self . nodes [ 0 ] . add_p2p_connection ( TestP2PConn ( ) , services = P2P_SERVICES )
2018-06-13 20:26:25 +02:00
# self.old_node sets only NODE_NETWORK
self . old_node = self . nodes [ 0 ] . add_p2p_connection ( TestP2PConn ( ) , services = NODE_NETWORK )
# self.std_node is for testing node1 (fRequireStandard=true)
2021-09-19 14:11:09 +02:00
self . std_node = self . nodes [ 1 ] . add_p2p_connection ( TestP2PConn ( ) , services = P2P_SERVICES )
2020-08-03 05:29:11 +02:00
# self.std_wtx_node is for testing node1 with wtxid relay
2021-09-19 14:11:09 +02:00
self . std_wtx_node = self . nodes [ 1 ] . add_p2p_connection ( TestP2PConn ( wtxidrelay = True ) , services = P2P_SERVICES )
2018-06-13 20:26:25 +02:00
2018-06-13 22:37:10 +02:00
assert self . test_node . nServices & NODE_WITNESS != 0
2018-06-13 20:26:25 +02:00
# Keep a place to store utxo's that can be used in later tests
self . utxo = [ ]
2019-05-20 20:59:07 +02:00
self . log . info ( " Starting tests before segwit activation " )
self . segwit_active = False
2018-06-13 20:26:25 +02:00
2018-06-13 22:37:10 +02:00
self . test_non_witness_transaction ( )
2018-06-13 20:26:25 +02:00
self . test_v0_outputs_arent_spendable ( )
2018-06-13 23:03:40 +02:00
self . test_block_relay ( )
2018-06-13 20:26:25 +02:00
self . test_unnecessary_witness_before_segwit_activation ( )
self . test_witness_tx_relay_before_segwit_activation ( )
2018-06-13 23:03:40 +02:00
self . test_standardness_v0 ( )
2019-05-20 20:59:07 +02:00
self . log . info ( " Advancing to segwit activation " )
2018-06-13 20:26:25 +02:00
self . advance_to_segwit_active ( )
2018-06-13 23:47:43 +02:00
# Segwit status 'active'
2018-06-13 20:26:25 +02:00
2018-06-13 23:03:40 +02:00
self . test_p2sh_witness ( )
2018-06-13 20:26:25 +02:00
self . test_witness_commitments ( )
self . test_block_malleability ( )
self . test_witness_block_size ( )
self . test_submit_block ( )
self . test_extra_witness_data ( )
self . test_max_witness_push_length ( )
2021-07-11 15:51:48 +02:00
self . test_max_witness_script_length ( )
2018-06-13 20:26:25 +02:00
self . test_witness_input_length ( )
2018-06-13 23:03:40 +02:00
self . test_block_relay ( )
2018-06-13 20:26:25 +02:00
self . test_tx_relay_after_segwit_activation ( )
2018-06-13 23:03:40 +02:00
self . test_standardness_v0 ( )
2018-06-13 20:26:25 +02:00
self . test_segwit_versions ( )
self . test_premature_coinbase_witness_spend ( )
self . test_uncompressed_pubkey ( )
self . test_signature_version_1 ( )
self . test_non_standard_witness_blinding ( )
self . test_non_standard_witness ( )
self . test_witness_sigops ( )
2019-03-21 18:47:47 +01:00
self . test_superfluous_witness ( )
2020-03-27 02:13:32 +01:00
self . test_wtxid_relay ( )
2016-04-09 03:02:24 +02:00
2018-06-13 20:16:28 +02:00
# Individual tests
2018-06-13 21:58:59 +02:00
def subtest ( func ) : # noqa: N805
""" Wraps the subtests for logging and state assertions. """
def func_wrapper ( self , * args , * * kwargs ) :
2019-05-20 20:59:07 +02:00
self . log . info ( " Subtest: {} (Segwit active = {} ) " . format ( func . __name__ , self . segwit_active ) )
2018-06-13 22:48:04 +02:00
# Assert segwit status is as expected
2019-05-20 20:59:07 +02:00
assert_equal ( softfork_active ( self . nodes [ 0 ] , ' segwit ' ) , self . segwit_active )
2018-06-13 21:58:59 +02:00
func ( self , * args , * * kwargs )
2018-06-13 22:37:10 +02:00
# Each subtest should leave some utxos for the next subtest
assert self . utxo
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 22:48:04 +02:00
# Assert segwit status is as expected at end of subtest
2019-05-20 20:59:07 +02:00
assert_equal ( softfork_active ( self . nodes [ 0 ] , ' segwit ' ) , self . segwit_active )
2018-06-13 21:58:59 +02:00
return func_wrapper
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_non_witness_transaction ( self ) :
2018-06-13 20:16:28 +02:00
""" See if sending a regular transaction works, and create a utxo to use in later tests. """
2016-04-09 03:02:24 +02:00
# Mine a block with an anyone-can-spend coinbase,
# let it mature, then try to spend it.
2018-06-13 21:58:59 +02:00
2021-08-27 16:36:17 +02:00
block = self . build_next_block ( )
2016-04-09 03:02:24 +02:00
block . solve ( )
2020-04-01 15:37:20 +02:00
self . test_node . send_and_ping ( msg_no_witness_block ( block ) ) # make sure the block was processed
2016-04-09 03:02:24 +02:00
txid = block . vtx [ 0 ] . sha256
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 99 ) # let the block mature
2016-04-09 03:02:24 +02:00
# Create a transaction that spends the coinbase
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( txid , 0 ) , b " " ) )
2018-05-03 22:50:25 +02:00
tx . vout . append ( CTxOut ( 49 * 100000000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) )
2016-04-09 03:02:24 +02:00
tx . calc_sha256 ( )
# Check that serializing it with or without witness is the same
# This is a sanity check of our testing framework.
2020-01-23 15:02:02 +01:00
assert_equal ( msg_no_witness_tx ( tx ) . serialize ( ) , msg_tx ( tx ) . serialize ( ) )
2016-04-09 03:02:24 +02:00
2020-04-01 15:37:20 +02:00
self . test_node . send_and_ping ( msg_tx ( tx ) ) # make sure the block was processed
2019-02-19 23:43:44 +01:00
assert tx . hash in self . nodes [ 0 ] . getrawmempool ( )
2016-04-09 03:02:24 +02:00
# Save this transaction for later
2018-06-13 17:56:20 +02:00
self . utxo . append ( UTXO ( tx . sha256 , 0 , 49 * 100000000 ) )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_unnecessary_witness_before_segwit_activation ( self ) :
2018-06-13 20:16:28 +02:00
""" Verify that blocks with witnesses are rejected before activation. """
2018-06-13 21:58:59 +02:00
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE ] ) ) )
2016-07-07 01:46:46 +02:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-04-09 03:02:24 +02:00
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ CScriptNum ( 1 ) ] ) ]
# Verify the hash with witness differs from the txid
# (otherwise our testing framework must be broken!)
tx . rehash ( )
2019-02-19 23:43:44 +01:00
assert tx . sha256 != tx . calc_sha256 ( with_witness = True )
2016-04-09 03:02:24 +02:00
2021-08-27 16:36:17 +02:00
# Construct a block that includes the transaction.
block = self . build_next_block ( )
2016-04-09 03:02:24 +02:00
self . update_witness_block_with_transactions ( block , [ tx ] )
# Sending witness data before activation is not allowed (anti-spam
# rule).
2018-08-24 21:26:42 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False , reason = ' unexpected-witness ' )
2016-04-09 03:02:24 +02:00
# But it should not be permanently marked bad...
# Resend without witness information.
2020-04-01 15:37:20 +02:00
self . test_node . send_and_ping ( msg_no_witness_block ( block ) ) # make sure the block was processed
2016-04-09 03:02:24 +02:00
assert_equal ( self . nodes [ 0 ] . getbestblockhash ( ) , block . hash )
# Update our utxo list; we spent the first entry.
self . utxo . pop ( 0 )
2018-04-30 01:34:57 +02:00
self . utxo . append ( UTXO ( tx . sha256 , 0 , tx . vout [ 0 ] . nValue ) )
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 23:03:40 +02:00
def test_block_relay ( self ) :
2018-06-13 20:26:25 +02:00
""" Test that block requests to NODE_WITNESS peer are with MSG_WITNESS_FLAG.
This is true regardless of segwit activation .
Also test that we don ' t ask for blocks from unupgraded peers. " " "
blocktype = 2 | MSG_WITNESS_FLAG
# test_node has set NODE_WITNESS, so all getdata requests should be for
# witness blocks.
# Test announcing a block via inv results in a getdata, and that
2021-08-27 16:36:17 +02:00
# announcing a block with a header results in a getdata
2018-06-13 20:26:25 +02:00
block1 = self . build_next_block ( )
block1 . solve ( )
self . test_node . announce_block_and_wait_for_getdata ( block1 , use_header = False )
2019-02-19 23:43:44 +01:00
assert self . test_node . last_message [ " getdata " ] . inv [ 0 ] . type == blocktype
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block1 , True )
2018-06-13 20:26:25 +02:00
2021-08-27 16:36:17 +02:00
block2 = self . build_next_block ( )
2018-06-13 20:26:25 +02:00
block2 . solve ( )
self . test_node . announce_block_and_wait_for_getdata ( block2 , use_header = True )
2019-02-19 23:43:44 +01:00
assert self . test_node . last_message [ " getdata " ] . inv [ 0 ] . type == blocktype
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block2 , True )
2018-06-13 20:26:25 +02:00
# Check that we can getdata for witness blocks or regular blocks,
# and the right thing happens.
2019-05-20 20:59:07 +02:00
if not self . segwit_active :
2018-06-13 20:26:25 +02:00
# Before activation, we should be able to request old blocks with
# or without witness, and they should be the same.
chain_height = self . nodes [ 0 ] . getblockcount ( )
# Pick 10 random blocks on main chain, and verify that getdata's
# for MSG_BLOCK, MSG_WITNESS_BLOCK, and rpc getblock() are equal.
all_heights = list ( range ( chain_height + 1 ) )
random . shuffle ( all_heights )
all_heights = all_heights [ 0 : 10 ]
for height in all_heights :
block_hash = self . nodes [ 0 ] . getblockhash ( height )
rpc_block = self . nodes [ 0 ] . getblock ( block_hash , False )
block_hash = int ( block_hash , 16 )
block = self . test_node . request_block ( block_hash , 2 )
wit_block = self . test_node . request_block ( block_hash , 2 | MSG_WITNESS_FLAG )
2019-05-08 16:03:06 +02:00
assert_equal ( block . serialize ( ) , wit_block . serialize ( ) )
2021-07-31 21:23:16 +02:00
assert_equal ( block . serialize ( ) , bytes . fromhex ( rpc_block ) )
2018-06-13 20:26:25 +02:00
else :
# After activation, witness blocks and non-witness blocks should
# be different. Verify rpc getblock() returns witness blocks, while
# getdata respects the requested type.
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ ] )
# This gives us a witness commitment.
2019-02-19 23:43:44 +01:00
assert len ( block . vtx [ 0 ] . wit . vtxinwit ) == 1
assert len ( block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack ) == 1
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
# Now try to retrieve it...
rpc_block = self . nodes [ 0 ] . getblock ( block . hash , False )
non_wit_block = self . test_node . request_block ( block . sha256 , 2 )
wit_block = self . test_node . request_block ( block . sha256 , 2 | MSG_WITNESS_FLAG )
2021-07-31 21:23:16 +02:00
assert_equal ( wit_block . serialize ( ) , bytes . fromhex ( rpc_block ) )
2018-06-13 20:26:25 +02:00
assert_equal ( wit_block . serialize ( False ) , non_wit_block . serialize ( ) )
2019-05-08 16:03:06 +02:00
assert_equal ( wit_block . serialize ( ) , block . serialize ( ) )
2018-06-13 20:26:25 +02:00
# Test size, vsize, weight
rpc_details = self . nodes [ 0 ] . getblock ( block . hash , True )
2019-05-08 16:03:06 +02:00
assert_equal ( rpc_details [ " size " ] , len ( block . serialize ( ) ) )
2018-06-13 20:26:25 +02:00
assert_equal ( rpc_details [ " strippedsize " ] , len ( block . serialize ( False ) ) )
2021-07-01 00:10:43 +02:00
assert_equal ( rpc_details [ " weight " ] , block . get_weight ( ) )
2018-06-13 20:26:25 +02:00
# Upgraded node should not ask for blocks from unupgraded
2021-08-27 16:36:17 +02:00
block4 = self . build_next_block ( )
2018-06-13 20:26:25 +02:00
block4 . solve ( )
self . old_node . getdataset = set ( )
# Blocks can be requested via direct-fetch (immediately upon processing the announcement)
# or via parallel download (with an indeterminate delay from processing the announcement)
# so to test that a block is NOT requested, we could guess a time period to sleep for,
# and then check. We can avoid the sleep() by taking advantage of transaction getdata's
# being processed after block getdata's, and announce a transaction as well,
# and then check to see if that particular getdata has been received.
# Since 0.14, inv's will only be responded to with a getheaders, so send a header
# to announce this block.
msg = msg_headers ( )
msg . headers = [ CBlockHeader ( block4 ) ]
self . old_node . send_message ( msg )
self . old_node . announce_tx_and_wait_for_getdata ( block4 . vtx [ 0 ] )
2019-02-19 23:43:44 +01:00
assert block4 . sha256 not in self . old_node . getdataset
2018-06-13 20:26:25 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-01-22 20:34:42 +01:00
def test_v0_outputs_arent_spendable ( self ) :
2018-06-13 20:16:28 +02:00
""" Test that v0 outputs aren ' t spendable before segwit activation.
~ 6 months after segwit activation , the SCRIPT_VERIFY_WITNESS flag was
backdated so that it applies to all blocks , going back to the genesis
block .
Consequently , version 0 witness outputs are never spendable without
witness , and so can ' t be spent before segwit activation (the point at which
blocks are permitted to contain witnesses ) . """
2018-01-22 20:34:42 +01:00
# Create two outputs, a p2wsh and p2sh-p2wsh
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2021-06-27 23:52:38 +02:00
p2sh_script_pubkey = script_to_p2sh_script ( script_pubkey )
2018-01-22 20:34:42 +01:00
value = self . utxo [ 0 ] . nValue / / 3
tx = CTransaction ( )
tx . vin = [ CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b ' ' ) ]
2018-06-13 17:56:20 +02:00
tx . vout = [ CTxOut ( value , script_pubkey ) , CTxOut ( value , p2sh_script_pubkey ) ]
2018-01-22 20:34:42 +01:00
tx . vout . append ( CTxOut ( value , CScript ( [ OP_TRUE ] ) ) )
tx . rehash ( )
txid = tx . sha256
# Add it to a block
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
# Verify that segwit isn't activated. A block serialized with witness
# should be rejected prior to activation.
2018-08-24 21:26:42 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False , with_witness = True , reason = ' unexpected-witness ' )
2018-01-22 20:34:42 +01:00
# Now send the block without witness. It should be accepted
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True , with_witness = False )
# Now try to spend the outputs. This should fail since SCRIPT_VERIFY_WITNESS is always enabled.
p2wsh_tx = CTransaction ( )
p2wsh_tx . vin = [ CTxIn ( COutPoint ( txid , 0 ) , b ' ' ) ]
p2wsh_tx . vout = [ CTxOut ( value , CScript ( [ OP_TRUE ] ) ) ]
p2wsh_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
p2wsh_tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ OP_TRUE ] ) ]
p2wsh_tx . rehash ( )
p2sh_p2wsh_tx = CTransaction ( )
2018-06-13 17:56:20 +02:00
p2sh_p2wsh_tx . vin = [ CTxIn ( COutPoint ( txid , 1 ) , CScript ( [ script_pubkey ] ) ) ]
2018-01-22 20:34:42 +01:00
p2sh_p2wsh_tx . vout = [ CTxOut ( value , CScript ( [ OP_TRUE ] ) ) ]
p2sh_p2wsh_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
p2sh_p2wsh_tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ OP_TRUE ] ) ]
p2sh_p2wsh_tx . rehash ( )
for tx in [ p2wsh_tx , p2sh_p2wsh_tx ] :
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
# When the block is serialized with a witness, the block will be rejected because witness
# data isn't allowed in blocks that don't commit to witness data.
2018-08-24 21:26:42 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False , with_witness = True , reason = ' unexpected-witness ' )
2018-01-22 20:34:42 +01:00
# When the block is serialized without witness, validation fails because the transaction is
# invalid (transactions are always validated with SCRIPT_VERIFY_WITNESS so a segwit v0 transaction
# without a witness is invalid).
# Note: The reject reason for this failure could be
# 'block-validation-failed' (if script check threads > 1) or
# 'non-mandatory-script-verify-flag (Witness program was passed an
# empty witness)' (otherwise).
# TODO: support multiple acceptable reject reasons.
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False , with_witness = False )
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( txid , 2 , value ) )
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def test_witness_tx_relay_before_segwit_activation ( self ) :
2018-06-13 21:58:59 +02:00
2018-06-13 20:26:25 +02:00
# Generate a transaction that doesn't require a witness, but send it
# with a witness. Should be rejected for premature-witness, but should
# not be added to recently rejected list.
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) )
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' ]
tx . rehash ( )
tx_hash = tx . sha256
tx_value = tx . vout [ 0 ] . nValue
# Verify that if a peer doesn't set nServices to include NODE_WITNESS,
# the getdata is just for the non-witness portion.
self . old_node . announce_tx_and_wait_for_getdata ( tx )
2020-04-25 13:44:44 +02:00
assert self . old_node . last_message [ " getdata " ] . inv [ 0 ] . type == MSG_TX
2018-06-13 20:26:25 +02:00
# Since we haven't delivered the tx yet, inv'ing the same tx from
# a witness transaction ought not result in a getdata.
2021-04-29 10:17:56 +02:00
self . test_node . announce_tx_and_wait_for_getdata ( tx , success = False )
2018-06-13 20:26:25 +02:00
# Delivering this transaction with witness should fail (no matter who
# its from)
assert_equal ( len ( self . nodes [ 0 ] . getrawmempool ( ) ) , 0 )
assert_equal ( len ( self . nodes [ 1 ] . getrawmempool ( ) ) , 0 )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . old_node , tx , with_witness = True , accepted = False )
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = True , accepted = False )
2018-06-13 20:26:25 +02:00
# But eliminating the witness should fix it
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = False , accepted = True )
2018-06-13 20:26:25 +02:00
# Cleanup: mine the first transaction and update utxo
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2018-06-13 20:26:25 +02:00
assert_equal ( len ( self . nodes [ 0 ] . getrawmempool ( ) ) , 0 )
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx_hash , 0 , tx_value ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 23:03:40 +02:00
def test_standardness_v0 ( self ) :
2018-06-13 20:26:25 +02:00
""" Test V0 txout standardness.
V0 segwit outputs and inputs are always standard .
V0 segwit inputs may only be mined after activation , but not before . """
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
p2sh_script_pubkey = script_to_p2sh_script ( witness_script )
2018-06-13 20:26:25 +02:00
# First prepare a p2sh output (so that spending it will pass standardness)
p2sh_tx = CTransaction ( )
p2sh_tx . vin = [ CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) ]
p2sh_tx . vout = [ CTxOut ( self . utxo [ 0 ] . nValue - 1000 , p2sh_script_pubkey ) ]
p2sh_tx . rehash ( )
# Mine it on test_node to create the confirmed output.
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2sh_tx , with_witness = True , accepted = True )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 20:26:25 +02:00
# Now test standardness of v0 P2WSH outputs.
# Start by creating a transaction with two outputs.
tx = CTransaction ( )
2021-07-11 15:51:48 +02:00
tx . vin = [ CTxIn ( COutPoint ( p2sh_tx . sha256 , 0 ) , CScript ( [ witness_script ] ) ) ]
2018-06-13 20:26:25 +02:00
tx . vout = [ CTxOut ( p2sh_tx . vout [ 0 ] . nValue - 10000 , script_pubkey ) ]
tx . vout . append ( CTxOut ( 8000 , script_pubkey ) ) # Might burn this later
tx . vin [ 0 ] . nSequence = BIP125_SEQUENCE_NUMBER # Just to have the option to bump this tx from the mempool
tx . rehash ( )
# This is always accepted, since the mempool policy is to consider segwit as always active
# and thus allow segwit outputs
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx , with_witness = True , accepted = True )
2018-06-13 20:26:25 +02:00
# Now create something that looks like a P2PKH output. This won't be spendable.
2021-07-11 15:51:48 +02:00
witness_hash = sha256 ( witness_script )
2018-06-13 20:26:25 +02:00
script_pubkey = CScript ( [ OP_0 , hash160 ( witness_hash ) ] )
tx2 = CTransaction ( )
# tx was accepted, so we spend the second output.
tx2 . vin = [ CTxIn ( COutPoint ( tx . sha256 , 1 ) , b " " ) ]
tx2 . vout = [ CTxOut ( 7000 , script_pubkey ) ]
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2018-06-13 20:26:25 +02:00
tx2 . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx2 , with_witness = True , accepted = True )
2018-06-13 20:26:25 +02:00
# Now update self.utxo for later tests.
tx3 = CTransaction ( )
# tx and tx2 were both accepted. Don't bother trying to reclaim the
# P2PKH output; just send tx's first output back to an anyone-can-spend.
2019-04-07 00:19:45 +02:00
self . sync_mempools ( [ self . nodes [ 0 ] , self . nodes [ 1 ] ] )
2018-06-13 20:26:25 +02:00
tx3 . vin = [ CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) ]
tx3 . vout = [ CTxOut ( tx . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) ]
tx3 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx3 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2018-06-13 20:26:25 +02:00
tx3 . rehash ( )
2019-05-20 20:59:07 +02:00
if not self . segwit_active :
2018-06-13 20:26:25 +02:00
# Just check mempool acceptance, but don't add the transaction to the mempool, since witness is disallowed
# in blocks and the tx is impossible to mine right now.
2021-01-07 16:47:35 +01:00
assert_equal (
self . nodes [ 0 ] . testmempoolaccept ( [ tx3 . serialize_with_witness ( ) . hex ( ) ] ) ,
[ {
' txid ' : tx3 . hash ,
' wtxid ' : tx3 . getwtxid ( ) ,
' allowed ' : True ,
' vsize ' : tx3 . get_vsize ( ) ,
' fees ' : {
' base ' : Decimal ( ' 0.00001000 ' ) ,
} ,
} ] ,
)
2018-06-13 20:26:25 +02:00
# Create the same output as tx3, but by replacing tx
tx3_out = tx3 . vout [ 0 ]
tx3 = tx
tx3 . vout = [ tx3_out ]
tx3 . rehash ( )
2021-01-07 16:47:35 +01:00
assert_equal (
self . nodes [ 0 ] . testmempoolaccept ( [ tx3 . serialize_with_witness ( ) . hex ( ) ] ) ,
[ {
' txid ' : tx3 . hash ,
' wtxid ' : tx3 . getwtxid ( ) ,
' allowed ' : True ,
' vsize ' : tx3 . get_vsize ( ) ,
' fees ' : {
' base ' : Decimal ( ' 0.00011000 ' ) ,
} ,
} ] ,
)
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , with_witness = True , accepted = True )
2018-06-13 20:26:25 +02:00
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 20:26:25 +02:00
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx3 . sha256 , 0 , tx3 . vout [ 0 ] . nValue ) )
assert_equal ( len ( self . nodes [ 1 ] . getrawmempool ( ) ) , 0 )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def advance_to_segwit_active ( self ) :
""" Mine enough blocks to activate segwit. """
2019-05-20 20:59:07 +02:00
assert not softfork_active ( self . nodes [ 0 ] , ' segwit ' )
2018-06-13 20:26:25 +02:00
height = self . nodes [ 0 ] . getblockcount ( )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , SEGWIT_HEIGHT - height - 2 )
2019-05-20 20:59:07 +02:00
assert not softfork_active ( self . nodes [ 0 ] , ' segwit ' )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-05-20 20:59:07 +02:00
assert softfork_active ( self . nodes [ 0 ] , ' segwit ' )
self . segwit_active = True
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 23:03:40 +02:00
def test_p2sh_witness ( self ) :
2018-06-13 20:26:25 +02:00
""" Test P2SH wrapped witness programs. """
# Prepare the p2sh-wrapped witness output
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_DROP , OP_TRUE ] )
p2wsh_pubkey = script_to_p2wsh_script ( witness_script )
2021-06-27 23:52:38 +02:00
script_pubkey = script_to_p2sh_script ( p2wsh_pubkey )
2018-06-13 20:26:25 +02:00
script_sig = CScript ( [ p2wsh_pubkey ] ) # a push of the redeem script
# Fund the P2SH output
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
tx . rehash ( )
# Verify mempool acceptance and block validity
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = False , accepted = True )
2018-06-13 20:26:25 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True , with_witness = True )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 20:26:25 +02:00
# Now test attempts to spend the output.
spend_tx = CTransaction ( )
spend_tx . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , script_sig ) )
spend_tx . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE ] ) ) )
spend_tx . rehash ( )
# This transaction should not be accepted into the mempool pre- or
# post-segwit. Mempool acceptance will use SCRIPT_VERIFY_WITNESS which
# will require a witness to spend a witness program regardless of
# segwit activation. Note that older bitcoind's that are not
# segwit-aware would also reject this for failing CLEANSTACK.
2018-09-26 04:10:13 +02:00
with self . nodes [ 0 ] . assert_debug_log (
expected_msgs = ( spend_tx . hash , ' was not accepted: non-mandatory-script-verify-flag (Witness program was passed an empty witness) ' ) ) :
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , spend_tx , with_witness = False , accepted = False )
2018-06-13 20:26:25 +02:00
2018-09-23 20:44:15 +02:00
# Try to put the witness script in the scriptSig, should also fail.
spend_tx . vin [ 0 ] . scriptSig = CScript ( [ p2wsh_pubkey , b ' a ' ] )
2018-06-13 20:26:25 +02:00
spend_tx . rehash ( )
2018-09-26 04:10:13 +02:00
with self . nodes [ 0 ] . assert_debug_log (
2019-01-17 22:50:50 +01:00
expected_msgs = ( spend_tx . hash , ' was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element) ' ) ) :
2018-09-26 04:10:13 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , spend_tx , with_witness = False , accepted = False )
2018-06-13 20:26:25 +02:00
# Now put the witness script in the witness, should succeed after
# segwit activates.
spend_tx . vin [ 0 ] . scriptSig = script_sig
spend_tx . rehash ( )
spend_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
spend_tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' , witness_script ]
2018-06-13 20:26:25 +02:00
# Verify mempool acceptance
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , spend_tx , with_witness = True , accepted = True )
2018-06-13 20:26:25 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ spend_tx ] )
# If we're after activation, then sending this with witnesses should be valid.
# This no longer works before activation, because SCRIPT_VERIFY_WITNESS
# is always set.
# TODO: rewrite this test to make clear that it only works after activation.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
# Update self.utxo
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( spend_tx . sha256 , 0 , spend_tx . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_witness_commitments ( self ) :
2018-06-13 20:16:28 +02:00
""" Test witness commitments.
This test can only be run after segwit has activated . """
2016-04-09 03:02:24 +02:00
# First try a correct witness commitment.
block = self . build_next_block ( )
add_witness_commitment ( block )
block . solve ( )
# Test the test -- witness serialization should be different
tests: Make msg_block a witness block
This diff has been generated with the following script, but is better
reviewed without looking at the script.
# -BEGIN VERIFY SCRIPT-
echo "Use msg_witness_block everywhere, except for tests that require msg_block"
# This could be a separate commit, but it is combined with the
# following scripts to reduce the overall diff
sed -i -e 's/msg_block/msg_witness_block/g' ./test/functional/{feature_assumevalid,feature_cltv,feature_dersig,feature_versionbits_warning,p2p_fingerprint,p2p_sendheaders,p2p_unrequested_blocks,example_test,rpc_blockchain}.py
echo "Rename msg_block to msg_no_witness_block"
# Rename msg_block to msg_no_witness_block in all tests (not the
# framework)
sed -i -e 's/msg_block/msg_no_witness_block/g' $(git grep -l msg_block ./test/functional/*.py)
# Derive msg_no_witness_block from msg_block
# Make msg_block a witness block in messages.py
patch -p1 --fuzz 0 << EOF
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 00190e4cbd..e454ed5987 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1133 +1133 @@ class msg_block:
- return self.block.serialize(with_witness=False)
+ return self.block.serialize()
@@ -1155 +1155 @@ class msg_generic:
-class msg_witness_block(msg_block):
+class msg_no_witness_block(msg_block):
@@ -1158,2 +1158 @@ class msg_witness_block(msg_block):
- r = self.block.serialize()
- return r
+ return self.block.serialize(with_witness=False)
@@ -1445 +1444 @@ class msg_blocktxn:
- r += self.block_transactions.serialize(with_witness=False)
+ r += self.block_transactions.serialize()
@@ -1452 +1451 @@ class msg_blocktxn:
-class msg_witness_blocktxn(msg_blocktxn):
+class msg_no_witness_blocktxn(msg_blocktxn):
@@ -1456,3 +1455 @@ class msg_witness_blocktxn(msg_blocktxn):
- r = b""
- r += self.block_transactions.serialize()
- return r
+ return self.block_transactions.serialize(with_witness=False)
EOF
# Conclude rename of msg_block to msg_no_witness_block
sed -i -e 's/msg_witness_block/msg_block/g' $(git grep -l msg_witness_block)
# -END VERIFY SCRIPT-
2019-05-08 16:21:25 +02:00
assert msg_block ( block ) . serialize ( ) != msg_no_witness_block ( block ) . serialize ( )
2016-04-09 03:02:24 +02:00
# This empty block should be valid.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Try to tweak the nonce
block_2 = self . build_next_block ( )
add_witness_commitment ( block_2 , nonce = 28 )
block_2 . solve ( )
# The commitment should have changed!
2019-02-19 23:43:44 +01:00
assert block_2 . vtx [ 0 ] . vout [ - 1 ] != block . vtx [ 0 ] . vout [ - 1 ]
2016-04-09 03:02:24 +02:00
# This should also be valid.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_2 , accepted = True )
2016-04-09 03:02:24 +02:00
# Now test commitments with actual transactions
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2021-07-11 15:51:48 +02:00
# Let's construct a witness script
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx . rehash ( )
# tx2 will spend tx1, and send back to a regular anyone-can-spend address
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
2021-07-11 15:51:48 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , witness_script ) )
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
block_3 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block_3 , [ tx , tx2 ] , nonce = 1 )
# Add an extra OP_RETURN output that matches the witness commitment template,
# even though it has extra data after the incorrect commitment.
# This block should fail.
block_3 . vtx [ 0 ] . vout . append ( CTxOut ( 0 , CScript ( [ OP_RETURN , WITNESS_COMMITMENT_HEADER + ser_uint256 ( 2 ) , 10 ] ) ) )
block_3 . vtx [ 0 ] . rehash ( )
block_3 . hashMerkleRoot = block_3 . calc_merkle_root ( )
block_3 . rehash ( )
block_3 . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_3 , accepted = False )
2016-04-09 03:02:24 +02:00
# Add a different commitment with different nonce, but in the
# right location, and with some funds burned(!).
# This should succeed (nValue shouldn't affect finding the
# witness commitment).
add_witness_commitment ( block_3 , nonce = 0 )
block_3 . vtx [ 0 ] . vout [ 0 ] . nValue - = 1
block_3 . vtx [ 0 ] . vout [ - 1 ] . nValue + = 1
block_3 . vtx [ 0 ] . rehash ( )
block_3 . hashMerkleRoot = block_3 . calc_merkle_root ( )
block_3 . rehash ( )
2019-02-19 23:43:44 +01:00
assert len ( block_3 . vtx [ 0 ] . vout ) == 4 # 3 OP_returns
2016-04-09 03:02:24 +02:00
block_3 . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_3 , accepted = True )
2016-04-09 03:02:24 +02:00
# Finally test that a block with no witness transactions can
# omit the commitment.
block_4 = self . build_next_block ( )
tx3 = CTransaction ( )
tx3 . vin . append ( CTxIn ( COutPoint ( tx2 . sha256 , 0 ) , b " " ) )
2021-07-11 15:51:48 +02:00
tx3 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , witness_script ) )
2016-04-09 03:02:24 +02:00
tx3 . rehash ( )
block_4 . vtx . append ( tx3 )
block_4 . hashMerkleRoot = block_4 . calc_merkle_root ( )
block_4 . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_4 , with_witness = False , accepted = True )
2016-04-09 03:02:24 +02:00
# Update available utxo's for use in later test.
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx3 . sha256 , 0 , tx3 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_block_malleability ( self ) :
# Make sure that a block that has too big a virtual size
# because of a too-large coinbase witness is not permanently
# marked bad.
block = self . build_next_block ( )
add_witness_commitment ( block )
block . solve ( )
2018-06-13 17:56:20 +02:00
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack . append ( b ' a ' * 5000000 )
2021-07-01 01:43:45 +02:00
assert block . get_weight ( ) > MAX_BLOCK_WEIGHT
2016-04-09 03:02:24 +02:00
# We can't send over the p2p network, because this is too big to relay
# TODO: repeat this test with a block that can be relayed
2020-04-22 22:57:19 +02:00
assert_equal ( ' bad-witness-nonce-size ' , self . nodes [ 0 ] . submitblock ( block . serialize ( ) . hex ( ) ) )
2016-04-09 03:02:24 +02:00
2019-02-19 23:43:44 +01:00
assert self . nodes [ 0 ] . getbestblockhash ( ) != block . hash
2016-04-09 03:02:24 +02:00
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack . pop ( )
2021-07-01 01:43:45 +02:00
assert block . get_weight ( ) < MAX_BLOCK_WEIGHT
2020-04-22 22:57:19 +02:00
assert_equal ( None , self . nodes [ 0 ] . submitblock ( block . serialize ( ) . hex ( ) ) )
2016-04-09 03:02:24 +02:00
2019-02-19 23:43:44 +01:00
assert self . nodes [ 0 ] . getbestblockhash ( ) == block . hash
2016-04-09 03:02:24 +02:00
2018-03-26 23:24:17 +02:00
# Now make sure that malleating the witness reserved value doesn't
2016-04-09 03:02:24 +02:00
# result in a block permanently marked bad.
block = self . build_next_block ( )
add_witness_commitment ( block )
block . solve ( )
# Change the nonce -- should not cause the block to be permanently
# failed
2018-06-13 17:56:20 +02:00
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ ser_uint256 ( 1 ) ]
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
2018-03-26 23:24:17 +02:00
# Changing the witness reserved value doesn't change the block hash
2018-06-13 17:56:20 +02:00
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ ser_uint256 ( 0 ) ]
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_witness_block_size ( self ) :
# TODO: Test that non-witness carrying blocks can't exceed 1MB
# Skipping this test for now; this is covered in p2p-fullblocktest.py
# Test that witness-bearing blocks are limited at ceil(base + wit/4) <= 1MB.
block = self . build_next_block ( )
2019-02-19 23:43:44 +01:00
assert len ( self . utxo ) > 0
2018-04-16 11:13:07 +02:00
2016-04-09 03:02:24 +02:00
# Create a P2WSH transaction.
2021-07-11 15:51:48 +02:00
# The witness script will be a bunch of OP_2DROP's, followed by OP_TRUE.
2016-04-09 03:02:24 +02:00
# This should give us plenty of room to tweak the spending tx's
# virtual size.
2018-06-13 17:56:20 +02:00
NUM_DROPS = 200 # 201 max ops per script!
2016-04-09 03:02:24 +02:00
NUM_OUTPUTS = 50
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_2DROP ] * NUM_DROPS + [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
prevout = COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n )
value = self . utxo [ 0 ] . nValue
parent_tx = CTransaction ( )
parent_tx . vin . append ( CTxIn ( prevout , b " " ) )
2018-06-13 17:56:20 +02:00
child_value = int ( value / NUM_OUTPUTS )
2020-08-03 01:10:56 +02:00
for _ in range ( NUM_OUTPUTS ) :
2018-06-13 17:56:20 +02:00
parent_tx . vout . append ( CTxOut ( child_value , script_pubkey ) )
2016-04-09 03:02:24 +02:00
parent_tx . vout [ 0 ] . nValue - = 50000
2019-02-19 23:43:44 +01:00
assert parent_tx . vout [ 0 ] . nValue > 0
2016-04-09 03:02:24 +02:00
parent_tx . rehash ( )
child_tx = CTransaction ( )
for i in range ( NUM_OUTPUTS ) :
child_tx . vin . append ( CTxIn ( COutPoint ( parent_tx . sha256 , i ) , b " " ) )
child_tx . vout = [ CTxOut ( value - 100000 , CScript ( [ OP_TRUE ] ) ) ]
2020-08-03 01:10:56 +02:00
for _ in range ( NUM_OUTPUTS ) :
2016-07-07 01:46:46 +02:00
child_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
child_tx . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ b ' a ' * 195 ] * ( 2 * NUM_DROPS ) + [ witness_script ]
2016-04-09 03:02:24 +02:00
child_tx . rehash ( )
self . update_witness_block_with_transactions ( block , [ parent_tx , child_tx ] )
2021-07-01 01:43:45 +02:00
additional_bytes = MAX_BLOCK_WEIGHT - block . get_weight ( )
2016-04-09 03:02:24 +02:00
i = 0
while additional_bytes > 0 :
2021-07-01 01:43:45 +02:00
# Add some more bytes to each input until we hit MAX_BLOCK_WEIGHT+1
2018-06-13 17:56:20 +02:00
extra_bytes = min ( additional_bytes + 1 , 55 )
block . vtx [ - 1 ] . wit . vtxinwit [ int ( i / ( 2 * NUM_DROPS ) ) ] . scriptWitness . stack [ i % ( 2 * NUM_DROPS ) ] = b ' a ' * ( 195 + extra_bytes )
2016-04-09 03:02:24 +02:00
additional_bytes - = extra_bytes
i + = 1
block . vtx [ 0 ] . vout . pop ( ) # Remove old commitment
add_witness_commitment ( block )
block . solve ( )
2021-07-01 01:43:45 +02:00
assert_equal ( block . get_weight ( ) , MAX_BLOCK_WEIGHT + 1 )
2016-04-09 03:02:24 +02:00
# Make sure that our test case would exceed the old max-network-message
# limit
2019-05-08 16:03:06 +02:00
assert len ( block . serialize ( ) ) > 2 * 1024 * 1024
2016-04-09 03:02:24 +02:00
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now resize the second transaction to make the block fit.
cur_length = len ( block . vtx [ - 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] )
2018-06-13 17:56:20 +02:00
block . vtx [ - 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] = b ' a ' * ( cur_length - 1 )
2016-04-09 03:02:24 +02:00
block . vtx [ 0 ] . vout . pop ( )
add_witness_commitment ( block )
block . solve ( )
2021-07-01 01:43:45 +02:00
assert block . get_weight ( ) == MAX_BLOCK_WEIGHT
2016-04-09 03:02:24 +02:00
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Update available utxo's
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( block . vtx [ - 1 ] . sha256 , 0 , block . vtx [ - 1 ] . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_submit_block ( self ) :
2018-06-13 20:16:28 +02:00
""" Test that submitblock adds the nonce automatically when possible. """
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
# Try using a custom nonce and then don't supply it.
# This shouldn't possibly work.
add_witness_commitment ( block , nonce = 1 )
2018-06-13 17:56:20 +02:00
block . vtx [ 0 ] . wit = CTxWitness ( ) # drop the nonce
2016-04-09 03:02:24 +02:00
block . solve ( )
2020-04-22 22:57:19 +02:00
assert_equal ( ' bad-witness-merkle-match ' , self . nodes [ 0 ] . submitblock ( block . serialize ( ) . hex ( ) ) )
2019-02-19 23:43:44 +01:00
assert self . nodes [ 0 ] . getbestblockhash ( ) != block . hash
2016-04-09 03:02:24 +02:00
# Now redo commitment with the standard nonce, but let bitcoind fill it in.
add_witness_commitment ( block , nonce = 0 )
block . vtx [ 0 ] . wit = CTxWitness ( )
block . solve ( )
2020-04-22 22:57:19 +02:00
assert_equal ( None , self . nodes [ 0 ] . submitblock ( block . serialize ( ) . hex ( ) ) )
2016-04-09 03:02:24 +02:00
assert_equal ( self . nodes [ 0 ] . getbestblockhash ( ) , block . hash )
# This time, add a tx with non-empty witness, but don't supply
# the commitment.
block_2 = self . build_next_block ( )
add_witness_commitment ( block_2 )
block_2 . solve ( )
# Drop commitment and nonce -- submitblock should not fill in.
block_2 . vtx [ 0 ] . vout . pop ( )
block_2 . vtx [ 0 ] . wit = CTxWitness ( )
2020-04-22 22:57:19 +02:00
assert_equal ( ' bad-txnmrklroot ' , self . nodes [ 0 ] . submitblock ( block_2 . serialize ( ) . hex ( ) ) )
2016-04-09 03:02:24 +02:00
# Tip should not advance!
2019-02-19 23:43:44 +01:00
assert self . nodes [ 0 ] . getbestblockhash ( ) != block_2 . hash
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_extra_witness_data ( self ) :
2018-06-13 20:16:28 +02:00
""" Test extra witness data in a transaction. """
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_DROP , OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
# First try extra witness data on a tx that doesn't require a witness
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 2000 , script_pubkey ) )
tx . vout . append ( CTxOut ( 1000 , CScript ( [ OP_TRUE ] ) ) ) # non-witness output
2016-07-07 01:46:46 +02:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-04-09 03:02:24 +02:00
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ ] ) ]
tx . rehash ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
# Extra witness data should not be allowed.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Try extra signature data. Ok if we're not spending a witness output.
block . vtx [ 1 ] . wit . vtxinwit = [ ]
block . vtx [ 1 ] . vin [ 0 ] . scriptSig = CScript ( [ OP_0 ] )
block . vtx [ 1 ] . rehash ( )
add_witness_commitment ( block )
block . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Now try extra witness/signature data on an input that DOES require a
# witness
tx2 = CTransaction ( )
2018-06-13 17:56:20 +02:00
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) ) # witness output
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 1 ) , b " " ) ) # non-witness
2016-04-09 03:02:24 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue , CScript ( [ OP_TRUE ] ) ) )
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . extend ( [ CTxInWitness ( ) , CTxInWitness ( ) ] )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ CScriptNum ( 1 ) ] ) , CScript ( [ CScriptNum ( 1 ) ] ) , witness_script ]
2018-06-13 17:56:20 +02:00
tx2 . wit . vtxinwit [ 1 ] . scriptWitness . stack = [ CScript ( [ OP_TRUE ] ) ]
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx2 ] )
# This has extra witness data, so it should fail.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now get rid of the extra witness, but add extra scriptSig data
tx2 . vin [ 0 ] . scriptSig = CScript ( [ OP_TRUE ] )
tx2 . vin [ 1 ] . scriptSig = CScript ( [ OP_TRUE ] )
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack . pop ( 0 )
tx2 . wit . vtxinwit [ 1 ] . scriptWitness . stack = [ ]
tx2 . rehash ( )
add_witness_commitment ( block )
block . solve ( )
# This has extra signature data for a witness input, so it should fail.
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now get rid of the extra scriptsig on the witness input, and verify
# success (even with extra scriptsig data in the non-witness input)
tx2 . vin [ 0 ] . scriptSig = b " "
tx2 . rehash ( )
add_witness_commitment ( block )
block . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Update utxo for later tests
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_max_witness_push_length ( self ) :
2018-06-13 20:16:28 +02:00
""" Test that witness stack can only allow up to 520 byte pushes. """
2018-06-13 21:58:59 +02:00
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_DROP , OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx . rehash ( )
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE ] ) ) )
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-04-09 03:02:24 +02:00
# First try a 521-byte stack element
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' * ( MAX_SCRIPT_ELEMENT_SIZE + 1 ) , witness_script ]
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
self . update_witness_block_with_transactions ( block , [ tx , tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now reduce the length of the stack element
2018-06-13 17:56:20 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] = b ' a ' * ( MAX_SCRIPT_ELEMENT_SIZE )
2016-04-09 03:02:24 +02:00
add_witness_commitment ( block )
block . solve ( )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Update the utxo for later tests
self . utxo . pop ( )
self . utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2021-07-11 15:51:48 +02:00
def test_max_witness_script_length ( self ) :
2018-06-13 20:16:28 +02:00
""" Test that witness outputs greater than 10kB can ' t be spent. """
2018-06-13 21:58:59 +02:00
2021-07-11 15:51:48 +02:00
MAX_WITNESS_SCRIPT_LENGTH = 10000
2016-04-09 03:02:24 +02:00
2021-07-11 15:51:48 +02:00
# This script is 19 max pushes (9937 bytes), then 64 more opcode-bytes.
long_witness_script = CScript ( [ b ' a ' * MAX_SCRIPT_ELEMENT_SIZE ] * 19 + [ OP_DROP ] * 63 + [ OP_TRUE ] )
assert len ( long_witness_script ) == MAX_WITNESS_SCRIPT_LENGTH + 1
long_script_pubkey = script_to_p2wsh_script ( long_witness_script )
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , long_script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx . rehash ( )
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE ] ) ) )
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' ] * 44 + [ long_witness_script ]
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
self . update_witness_block_with_transactions ( block , [ tx , tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
2021-07-11 15:51:48 +02:00
# Try again with one less byte in the witness script
witness_script = CScript ( [ b ' a ' * MAX_SCRIPT_ELEMENT_SIZE ] * 19 + [ OP_DROP ] * 62 + [ OP_TRUE ] )
assert len ( witness_script ) == MAX_WITNESS_SCRIPT_LENGTH
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
2018-06-13 17:56:20 +02:00
tx . vout [ 0 ] = CTxOut ( tx . vout [ 0 ] . nValue , script_pubkey )
2016-04-09 03:02:24 +02:00
tx . rehash ( )
tx2 . vin [ 0 ] . prevout . hash = tx . sha256
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' ] * 43 + [ witness_script ]
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
block . vtx = [ block . vtx [ 0 ] ]
self . update_witness_block_with_transactions ( block , [ tx , tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
self . utxo . pop ( )
self . utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_witness_input_length ( self ) :
2018-06-13 20:16:28 +02:00
""" Test that vin length must match vtxinwit length. """
2018-06-13 21:58:59 +02:00
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_DROP , OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2018-04-16 11:13:07 +02:00
2016-04-09 03:02:24 +02:00
# Create a transaction that splits our utxo into many outputs
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
value = self . utxo [ 0 ] . nValue
2020-08-03 01:10:56 +02:00
for _ in range ( 10 ) :
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( int ( value / 10 ) , script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx . vout [ 0 ] . nValue - = 1000
2019-02-19 23:43:44 +01:00
assert tx . vout [ 0 ] . nValue > = 0
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Try various ways to spend tx that should all break.
# This "broken" transaction serializer will not normalize
# the length of vtxinwit.
class BrokenCTransaction ( CTransaction ) :
def serialize_with_witness ( self ) :
flags = 0
if not self . wit . is_null ( ) :
flags | = 1
r = b " "
r + = struct . pack ( " <i " , self . nVersion )
if flags :
dummy = [ ]
r + = ser_vector ( dummy )
r + = struct . pack ( " <B " , flags )
r + = ser_vector ( self . vin )
r + = ser_vector ( self . vout )
if flags & 1 :
r + = self . wit . serialize ( )
r + = struct . pack ( " <I " , self . nLockTime )
return r
tx2 = BrokenCTransaction ( )
for i in range ( 10 ) :
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , i ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx2 . vout . append ( CTxOut ( value - 3000 , CScript ( [ OP_TRUE ] ) ) )
2016-04-09 03:02:24 +02:00
# First try using a too long vtxinwit
for i in range ( 11 ) :
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ i ] . scriptWitness . stack = [ b ' a ' , witness_script ]
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now try using a too short vtxinwit
tx2 . wit . vtxinwit . pop ( )
tx2 . wit . vtxinwit . pop ( )
block . vtx = [ block . vtx [ 0 ] ]
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Now make one of the intermediate witnesses be incorrect
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ b ' a ' , witness_script ]
tx2 . wit . vtxinwit [ 5 ] . scriptWitness . stack = [ witness_script ]
2016-04-09 03:02:24 +02:00
block . vtx = [ block . vtx [ 0 ] ]
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2016-04-09 03:02:24 +02:00
# Fix the broken witness and the block should be accepted.
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 5 ] . scriptWitness . stack = [ b ' a ' , witness_script ]
2016-04-09 03:02:24 +02:00
block . vtx = [ block . vtx [ 0 ] ]
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
self . utxo . pop ( )
self . utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_tx_relay_after_segwit_activation ( self ) :
2018-06-13 20:16:28 +02:00
""" Test transaction relay after segwit activation.
After segwit activates , verify that mempool :
- rejects transactions with unnecessary / extra witnesses
- accepts transactions with valid witnesses
and that witness transactions are relayed to non - upgraded peers . """
2016-04-09 03:02:24 +02:00
# Generate a transaction that doesn't require a witness, but send it
# with a witness. Should be rejected because we can't use a witness
# when spending a non-witness output.
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-05-03 22:50:25 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) )
2016-07-07 01:46:46 +02:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2018-06-13 17:56:20 +02:00
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' ]
2016-04-09 03:02:24 +02:00
tx . rehash ( )
tx_hash = tx . sha256
# Verify that unnecessary witnesses are rejected.
self . test_node . announce_tx_and_wait_for_getdata ( tx )
assert_equal ( len ( self . nodes [ 0 ] . getrawmempool ( ) ) , 0 )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = True , accepted = False )
2016-04-09 03:02:24 +02:00
# Verify that removing the witness succeeds.
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = False , accepted = True )
2016-04-09 03:02:24 +02:00
# Now try to add extra witness data to a valid witness tx.
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx_hash , 0 ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
tx3 = CTransaction ( )
tx3 . vin . append ( CTxIn ( COutPoint ( tx2 . sha256 , 0 ) , b " " ) )
2016-07-07 01:46:46 +02:00
tx3 . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-08-18 18:04:33 +02:00
# Add too-large for IsStandard witness and check that it does not enter reject filter
2021-07-11 15:51:48 +02:00
p2sh_script = CScript ( [ OP_TRUE ] )
witness_script2 = CScript ( [ b ' a ' * 400000 ] )
tx3 . vout . append ( CTxOut ( tx2 . vout [ 0 ] . nValue - 1000 , script_to_p2sh_script ( p2sh_script ) ) )
tx3 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script2 ]
2016-08-18 18:04:33 +02:00
tx3 . rehash ( )
2020-08-03 02:56:52 +02:00
# Node will not be blinded to the transaction, requesting it any number of times
2020-08-03 05:29:11 +02:00
# if it is being announced via txid relay.
# Node will be blinded to the transaction via wtxid, however.
2016-08-18 18:04:33 +02:00
self . std_node . announce_tx_and_wait_for_getdata ( tx3 )
2020-08-03 05:29:11 +02:00
self . std_wtx_node . announce_tx_and_wait_for_getdata ( tx3 , use_wtxid = True )
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx3 , True , False , ' tx-size ' )
2020-08-03 02:56:52 +02:00
self . std_node . announce_tx_and_wait_for_getdata ( tx3 )
2020-08-03 05:29:11 +02:00
self . std_wtx_node . announce_tx_and_wait_for_getdata ( tx3 , use_wtxid = True , success = False )
2016-08-18 18:04:33 +02:00
# Remove witness stuffing, instead add extra witness push on stack
2018-05-03 22:50:25 +02:00
tx3 . vout [ 0 ] = CTxOut ( tx2 . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) )
2021-07-11 15:51:48 +02:00
tx3 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ CScript ( [ CScriptNum ( 1 ) ] ) , witness_script ]
2016-04-09 03:02:24 +02:00
tx3 . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx2 , with_witness = True , accepted = True )
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , with_witness = True , accepted = False )
2016-04-09 03:02:24 +02:00
# Get rid of the extra witness, and verify acceptance.
2021-07-11 15:51:48 +02:00
tx3 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2016-04-09 03:02:24 +02:00
# Also check that old_node gets a tx announcement, even though this is
# a witness transaction.
2020-04-25 13:44:44 +02:00
self . old_node . wait_for_inv ( [ CInv ( MSG_TX , tx2 . sha256 ) ] ) # wait until tx2 was inv'ed
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , with_witness = True , accepted = True )
2020-04-25 13:44:44 +02:00
self . old_node . wait_for_inv ( [ CInv ( MSG_TX , tx3 . sha256 ) ] )
2016-04-09 03:02:24 +02:00
# Test that getrawtransaction returns correct witness information
# hash, size, vsize
raw_tx = self . nodes [ 0 ] . getrawtransaction ( tx3 . hash , 1 )
assert_equal ( int ( raw_tx [ " hash " ] , 16 ) , tx3 . calc_sha256 ( True ) )
assert_equal ( raw_tx [ " size " ] , len ( tx3 . serialize_with_witness ( ) ) )
2021-06-30 23:40:39 +02:00
vsize = tx3 . get_vsize ( )
2016-04-09 03:02:24 +02:00
assert_equal ( raw_tx [ " vsize " ] , vsize )
2021-06-30 23:40:39 +02:00
assert_equal ( raw_tx [ " weight " ] , tx3 . get_weight ( ) )
2016-04-09 03:02:24 +02:00
assert_equal ( len ( raw_tx [ " vin " ] [ 0 ] [ " txinwitness " ] ) , 1 )
2021-07-11 15:51:48 +02:00
assert_equal ( raw_tx [ " vin " ] [ 0 ] [ " txinwitness " ] [ 0 ] , witness_script . hex ( ) )
2019-02-19 23:43:44 +01:00
assert vsize != raw_tx [ " size " ]
2016-04-09 03:02:24 +02:00
# Cleanup: mine the transactions and update utxo for next test
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2018-06-13 17:56:20 +02:00
assert_equal ( len ( self . nodes [ 0 ] . getrawmempool ( ) ) , 0 )
2016-04-09 03:02:24 +02:00
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx3 . sha256 , 0 , tx3 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def test_segwit_versions ( self ) :
""" Test validity of future segwit version transactions.
2016-04-09 03:02:24 +02:00
2019-04-18 21:46:07 +02:00
Future segwit versions are non - standard to spend , but valid in blocks .
Sending to future segwit versions is always allowed .
2018-06-13 20:26:25 +02:00
Can run this before and after segwit activation . """
2018-06-13 20:16:28 +02:00
2018-07-10 22:20:24 +02:00
NUM_SEGWIT_VERSIONS = 17 # will test OP_0, OP1, ..., OP_16
if len ( self . utxo ) < NUM_SEGWIT_VERSIONS :
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-07-10 22:20:24 +02:00
split_value = ( self . utxo [ 0 ] . nValue - 4000 ) / / NUM_SEGWIT_VERSIONS
2020-08-03 01:10:56 +02:00
for _ in range ( NUM_SEGWIT_VERSIONS ) :
2016-04-09 03:02:24 +02:00
tx . vout . append ( CTxOut ( split_value , CScript ( [ OP_TRUE ] ) ) )
tx . rehash ( )
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
self . utxo . pop ( 0 )
2018-07-10 22:20:24 +02:00
for i in range ( NUM_SEGWIT_VERSIONS ) :
2016-04-09 03:02:24 +02:00
self . utxo . append ( UTXO ( tx . sha256 , i , split_value ) )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-04-09 03:02:24 +02:00
temp_utxo = [ ]
tx = CTransaction ( )
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
witness_hash = sha256 ( witness_script )
2016-04-09 03:02:24 +02:00
assert_equal ( len ( self . nodes [ 1 ] . getrawmempool ( ) ) , 0 )
2018-06-13 17:56:20 +02:00
for version in list ( range ( OP_1 , OP_16 + 1 ) ) + [ OP_0 ] :
# First try to spend to a future version segwit script_pubkey.
2020-09-11 23:34:10 +02:00
if version == OP_1 :
# Don't use 32-byte v1 witness (used by Taproot; see BIP 341)
script_pubkey = CScript ( [ CScriptOp ( version ) , witness_hash + b ' \x00 ' ] )
else :
script_pubkey = CScript ( [ CScriptOp ( version ) , witness_hash ] )
2016-04-09 03:02:24 +02:00
tx . vin = [ CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) ]
2018-06-13 17:56:20 +02:00
tx . vout = [ CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) ]
2016-04-09 03:02:24 +02:00
tx . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx , with_witness = True , accepted = False )
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = True , accepted = True )
2016-04-09 03:02:24 +02:00
self . utxo . pop ( 0 )
temp_utxo . append ( UTXO ( tx . sha256 , 0 , tx . vout [ 0 ] . nValue ) )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 ) # Mine all the transactions
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2019-02-19 23:43:44 +01:00
assert len ( self . nodes [ 0 ] . getrawmempool ( ) ) == 0
2016-04-09 03:02:24 +02:00
2020-09-11 23:34:10 +02:00
# Finally, verify that version 0 -> version 2 transactions
2019-04-18 21:46:07 +02:00
# are standard
2020-09-11 23:34:10 +02:00
script_pubkey = CScript ( [ CScriptOp ( OP_2 ) , witness_hash ] )
2016-04-09 03:02:24 +02:00
tx2 = CTransaction ( )
tx2 . vin = [ CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) ]
2018-06-13 17:56:20 +02:00
tx2 . vout = [ CTxOut ( tx . vout [ 0 ] . nValue - 1000 , script_pubkey ) ]
2016-07-07 01:46:46 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2016-04-09 03:02:24 +02:00
tx2 . rehash ( )
2019-04-18 21:46:07 +02:00
# Gets accepted to both policy-enforcing nodes and others.
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx2 , with_witness = True , accepted = True )
2019-04-18 21:46:07 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx2 , with_witness = True , accepted = True )
2018-06-13 17:56:20 +02:00
temp_utxo . pop ( ) # last entry in temp_utxo was the output we just spent
2016-04-09 03:02:24 +02:00
temp_utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
2020-08-03 20:37:58 +02:00
# Spend everything in temp_utxo into an segwit v1 output.
2016-04-09 03:02:24 +02:00
tx3 = CTransaction ( )
total_value = 0
for i in temp_utxo :
tx3 . vin . append ( CTxIn ( COutPoint ( i . sha256 , i . n ) , b " " ) )
2016-07-07 01:46:46 +02:00
tx3 . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-04-09 03:02:24 +02:00
total_value + = i . nValue
2021-07-11 15:51:48 +02:00
tx3 . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ witness_script ]
2020-08-03 20:37:58 +02:00
tx3 . vout . append ( CTxOut ( total_value - 1000 , script_pubkey ) )
2016-04-09 03:02:24 +02:00
tx3 . rehash ( )
2020-08-03 20:37:58 +02:00
# First we test this transaction against fRequireStandard=true node
# making sure the txid is added to the reject filter
self . std_node . announce_tx_and_wait_for_getdata ( tx3 )
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx3 , with_witness = True , accepted = False , reason = " bad-txns-nonstandard-inputs " )
# Now the node will no longer ask for getdata of this transaction when advertised by same txid
2021-04-29 10:17:56 +02:00
self . std_node . announce_tx_and_wait_for_getdata ( tx3 , success = False )
2020-08-03 20:37:58 +02:00
2016-04-09 03:02:24 +02:00
# Spending a higher version witness output is not allowed by policy,
# even with fRequireStandard=false.
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , with_witness = True , accepted = False , reason = " reserved for soft-fork upgrades " )
2016-04-09 03:02:24 +02:00
# Building a block with the transaction must be valid, however.
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx2 , tx3 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-04-09 03:02:24 +02:00
# Add utxo to our list
self . utxo . append ( UTXO ( tx3 . sha256 , 0 , tx3 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-04-09 03:02:24 +02:00
def test_premature_coinbase_witness_spend ( self ) :
2018-06-13 21:58:59 +02:00
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
# Change the output of the block to be a witness output.
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2018-06-13 17:56:20 +02:00
block . vtx [ 0 ] . vout [ 0 ] . scriptPubKey = script_pubkey
2016-04-09 03:02:24 +02:00
# This next line will rehash the coinbase and update the merkle
# root, and solve.
self . update_witness_block_with_transactions ( block , [ ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
spend_tx = CTransaction ( )
spend_tx . vin = [ CTxIn ( COutPoint ( block . vtx [ 0 ] . sha256 , 0 ) , b " " ) ]
2021-07-11 15:51:48 +02:00
spend_tx . vout = [ CTxOut ( block . vtx [ 0 ] . vout [ 0 ] . nValue , witness_script ) ]
2016-07-07 01:46:46 +02:00
spend_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
spend_tx . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2016-04-09 03:02:24 +02:00
spend_tx . rehash ( )
# Now test a premature spend.
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 98 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-04-09 03:02:24 +02:00
block2 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block2 , [ spend_tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block2 , accepted = False )
2016-04-09 03:02:24 +02:00
# Advancing one more block should allow the spend.
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2016-04-09 03:02:24 +02:00
block2 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block2 , [ spend_tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block2 , accepted = True )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-04-09 03:02:24 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def test_uncompressed_pubkey ( self ) :
""" Test uncompressed pubkey validity in segwit transactions.
Uncompressed pubkeys are no longer supported in default relay policy ,
but ( for now ) are still valid in blocks . """
# Segwit transactions using uncompressed pubkeys are not accepted
# under default policy, but should still pass consensus.
2019-04-16 01:49:18 +02:00
key = ECKey ( )
key . generate ( False )
pubkey = key . get_pubkey ( ) . get_bytes ( )
2018-06-13 20:26:25 +02:00
assert_equal ( len ( pubkey ) , 65 ) # This should be an uncompressed pubkey
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
utxo = self . utxo . pop ( 0 )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# Test 1: P2WPKH
# First create a P2WPKH output that uses an uncompressed pubkey
pubkeyhash = hash160 ( pubkey )
2021-06-28 20:45:04 +02:00
script_pkh = key_to_p2wpkh_script ( pubkey )
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
2018-06-13 20:26:25 +02:00
tx . vin . append ( CTxIn ( COutPoint ( utxo . sha256 , utxo . n ) , b " " ) )
tx . vout . append ( CTxOut ( utxo . nValue - 1000 , script_pkh ) )
2016-04-09 03:02:24 +02:00
tx . rehash ( )
2018-06-13 20:26:25 +02:00
# Confirm it in a block.
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# Now try to spend it. Send it to a P2WSH output, which we'll
# use in the next test.
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ pubkey , CScriptOp ( OP_CHECKSIG ) ] )
script_wsh = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , script_wsh ) )
2021-06-27 23:03:40 +02:00
script = keyhash_to_p2pkh_script ( pubkeyhash )
2019-10-14 23:04:34 +02:00
sig_hash = SegwitV0SignatureHash ( script , tx2 , 0 , SIGHASH_ALL , tx . vout [ 0 ] . nValue )
2019-04-16 01:49:18 +02:00
signature = key . sign_ecdsa ( sig_hash ) + b ' \x01 ' # 0x1 is SIGHASH_ALL
2018-06-13 20:26:25 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ signature , pubkey ]
tx2 . rehash ( )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# Should fail policy test.
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx2 , True , False , ' non-mandatory-script-verify-flag (Using non-compressed keys in segwit) ' )
2018-06-13 20:26:25 +02:00
# But passes consensus.
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# Test 2: P2WSH
# Try to spend the P2WSH output created in last test.
# Send it to a P2SH(P2WSH) output, which we'll use in the next test.
2021-06-27 23:52:38 +02:00
script_p2sh = script_to_p2sh_script ( script_wsh )
2018-06-13 20:26:25 +02:00
script_sig = CScript ( [ script_wsh ] )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
tx3 = CTransaction ( )
tx3 . vin . append ( CTxIn ( COutPoint ( tx2 . sha256 , 0 ) , b " " ) )
tx3 . vout . append ( CTxOut ( tx2 . vout [ 0 ] . nValue - 1000 , script_p2sh ) )
tx3 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx3 , 0 , SIGHASH_ALL , tx2 . vout [ 0 ] . nValue , key )
2018-06-13 20:26:25 +02:00
# Should fail policy test.
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , True , False , ' non-mandatory-script-verify-flag (Using non-compressed keys in segwit) ' )
2018-06-13 20:26:25 +02:00
# But passes consensus.
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx3 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
# Test 3: P2SH(P2WSH)
# Try to spend the P2SH output created in the last test.
# Send it to a P2PKH output, which we'll use in the next test.
2021-06-27 23:03:40 +02:00
script_pubkey = keyhash_to_p2pkh_script ( pubkeyhash )
2018-06-13 20:26:25 +02:00
tx4 = CTransaction ( )
tx4 . vin . append ( CTxIn ( COutPoint ( tx3 . sha256 , 0 ) , script_sig ) )
tx4 . vout . append ( CTxOut ( tx3 . vout [ 0 ] . nValue - 1000 , script_pubkey ) )
tx4 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx4 , 0 , SIGHASH_ALL , tx3 . vout [ 0 ] . nValue , key )
2018-06-13 20:26:25 +02:00
# Should fail policy test.
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx4 , True , False , ' non-mandatory-script-verify-flag (Using non-compressed keys in segwit) ' )
2018-06-13 20:26:25 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx4 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
# Test 4: Uncompressed pubkeys should still be valid in non-segwit
# transactions.
tx5 = CTransaction ( )
tx5 . vin . append ( CTxIn ( COutPoint ( tx4 . sha256 , 0 ) , b " " ) )
tx5 . vout . append ( CTxOut ( tx4 . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE ] ) ) )
2019-10-14 23:04:34 +02:00
( sig_hash , err ) = LegacySignatureHash ( script_pubkey , tx5 , 0 , SIGHASH_ALL )
2019-04-16 01:49:18 +02:00
signature = key . sign_ecdsa ( sig_hash ) + b ' \x01 ' # 0x1 is SIGHASH_ALL
2018-06-13 20:26:25 +02:00
tx5 . vin [ 0 ] . scriptSig = CScript ( [ signature , pubkey ] )
tx5 . rehash ( )
# Should pass policy and consensus.
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx5 , True , True )
2018-06-13 20:26:25 +02:00
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx5 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
self . utxo . append ( UTXO ( tx5 . sha256 , 0 , tx5 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def test_signature_version_1 ( self ) :
2018-06-13 21:58:59 +02:00
2019-04-16 01:49:18 +02:00
key = ECKey ( )
key . generate ( )
pubkey = key . get_pubkey ( ) . get_bytes ( )
2018-06-13 20:26:25 +02:00
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ pubkey , CScriptOp ( OP_CHECKSIG ) ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2018-06-13 20:26:25 +02:00
# First create a witness output for use in the tests.
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
tx . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = True , accepted = True )
2018-06-13 20:26:25 +02:00
# Mine this transaction in preparation for following tests.
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 20:26:25 +02:00
self . utxo . pop ( 0 )
# Test each hashtype
prev_utxo = UTXO ( tx . sha256 , 0 , tx . vout [ 0 ] . nValue )
for sigflag in [ 0 , SIGHASH_ANYONECANPAY ] :
for hashtype in [ SIGHASH_ALL , SIGHASH_NONE , SIGHASH_SINGLE ] :
hashtype | = sigflag
block = self . build_next_block ( )
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( prev_utxo . sha256 , prev_utxo . n ) , b " " ) )
tx . vout . append ( CTxOut ( prev_utxo . nValue - 1000 , script_pubkey ) )
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
# Too-large input value
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , 0 , hashtype , prev_utxo . nValue + 1 , key )
2018-06-13 20:26:25 +02:00
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2018-06-13 20:26:25 +02:00
# Too-small input value
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , 0 , hashtype , prev_utxo . nValue - 1 , key )
2018-06-13 20:26:25 +02:00
block . vtx . pop ( ) # remove last tx
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2018-06-13 20:26:25 +02:00
# Now try correct value
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , 0 , hashtype , prev_utxo . nValue , key )
2018-06-13 20:26:25 +02:00
block . vtx . pop ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2018-06-13 20:26:25 +02:00
prev_utxo = UTXO ( tx . sha256 , 0 , tx . vout [ 0 ] . nValue )
# Test combinations of signature hashes.
# Split the utxo into a lot of outputs.
# Randomly choose up to 10 to spend, sign with different hashtypes, and
2018-07-10 22:20:24 +02:00
# output to a random number of outputs. Repeat NUM_SIGHASH_TESTS times.
2016-04-09 03:02:24 +02:00
# Ensure that we've tested a situation where we use SIGHASH_SINGLE with
# an input index > number of outputs.
2018-07-10 22:20:24 +02:00
NUM_SIGHASH_TESTS = 500
2016-04-09 03:02:24 +02:00
temp_utxos = [ ]
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( prev_utxo . sha256 , prev_utxo . n ) , b " " ) )
2018-07-10 22:20:24 +02:00
split_value = prev_utxo . nValue / / NUM_SIGHASH_TESTS
2020-08-03 01:10:56 +02:00
for _ in range ( NUM_SIGHASH_TESTS ) :
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( split_value , script_pubkey ) )
2016-07-07 01:46:46 +02:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , 0 , SIGHASH_ALL , prev_utxo . nValue , key )
2018-07-10 22:20:24 +02:00
for i in range ( NUM_SIGHASH_TESTS ) :
2016-04-09 03:02:24 +02:00
temp_utxos . append ( UTXO ( tx . sha256 , i , split_value ) )
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
used_sighash_single_out_of_bounds = False
2018-07-10 22:20:24 +02:00
for i in range ( NUM_SIGHASH_TESTS ) :
2016-09-24 10:26:26 +02:00
# Ping regularly to keep the connection alive
if ( not i % 100 ) :
2017-03-30 14:38:46 +02:00
self . test_node . sync_with_ping ( )
2016-04-09 03:02:24 +02:00
# Choose random number of inputs to use.
num_inputs = random . randint ( 1 , 10 )
# Create a slight bias for producing more utxos
num_outputs = random . randint ( 1 , 11 )
random . shuffle ( temp_utxos )
2019-02-19 23:43:44 +01:00
assert len ( temp_utxos ) > num_inputs
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
total_value = 0
for i in range ( num_inputs ) :
tx . vin . append ( CTxIn ( COutPoint ( temp_utxos [ i ] . sha256 , temp_utxos [ i ] . n ) , b " " ) )
2016-07-07 01:46:46 +02:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2016-04-09 03:02:24 +02:00
total_value + = temp_utxos [ i ] . nValue
split_value = total_value / / num_outputs
2020-08-03 01:10:56 +02:00
for _ in range ( num_outputs ) :
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( split_value , script_pubkey ) )
2016-04-09 03:02:24 +02:00
for i in range ( num_inputs ) :
# Now try to sign each input, using a random hashtype.
anyonecanpay = 0
if random . randint ( 0 , 1 ) :
anyonecanpay = SIGHASH_ANYONECANPAY
hashtype = random . randint ( 1 , 3 ) | anyonecanpay
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , i , hashtype , temp_utxos [ i ] . nValue , key )
2016-04-09 03:02:24 +02:00
if ( hashtype == SIGHASH_SINGLE and i > = num_outputs ) :
used_sighash_single_out_of_bounds = True
tx . rehash ( )
for i in range ( num_outputs ) :
temp_utxos . append ( UTXO ( tx . sha256 , i , split_value ) )
temp_utxos = temp_utxos [ num_inputs : ]
block . vtx . append ( tx )
# Test the block periodically, if we're close to maxblocksize
2021-07-01 01:43:45 +02:00
if block . get_weight ( ) > MAX_BLOCK_WEIGHT - 4000 :
2016-04-09 03:02:24 +02:00
self . update_witness_block_with_transactions ( block , [ ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
block = self . build_next_block ( )
if ( not used_sighash_single_out_of_bounds ) :
2017-03-08 00:46:17 +01:00
self . log . info ( " WARNING: this test run didn ' t attempt SIGHASH_SINGLE with out-of-bounds index value " )
2016-04-09 03:02:24 +02:00
# Test the transactions we've added to the block
if ( len ( block . vtx ) > 1 ) :
self . update_witness_block_with_transactions ( block , [ ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-04-09 03:02:24 +02:00
# Now test witness version 0 P2PKH transactions
pubkeyhash = hash160 ( pubkey )
2021-06-28 20:45:04 +02:00
script_pkh = key_to_p2wpkh_script ( pubkey )
2016-04-09 03:02:24 +02:00
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( temp_utxos [ 0 ] . sha256 , temp_utxos [ 0 ] . n ) , b " " ) )
2018-06-13 20:26:25 +02:00
tx . vout . append ( CTxOut ( temp_utxos [ 0 ] . nValue , script_pkh ) )
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , 0 , SIGHASH_ALL , temp_utxos [ 0 ] . nValue , key )
2016-10-06 19:15:33 +02:00
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
2018-06-13 20:26:25 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue , CScript ( [ OP_TRUE ] ) ) )
2021-06-27 23:03:40 +02:00
script = keyhash_to_p2pkh_script ( pubkeyhash )
2019-10-14 23:04:34 +02:00
sig_hash = SegwitV0SignatureHash ( script , tx2 , 0 , SIGHASH_ALL , tx . vout [ 0 ] . nValue )
2019-04-16 01:49:18 +02:00
signature = key . sign_ecdsa ( sig_hash ) + b ' \x01 ' # 0x1 is SIGHASH_ALL
2018-06-13 20:26:25 +02:00
# Check that we can't have a scriptSig
tx2 . vin [ 0 ] . scriptSig = CScript ( [ signature , pubkey ] )
block = self . build_next_block ( )
self . update_witness_block_with_transactions ( block , [ tx , tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = False )
2018-06-13 20:26:25 +02:00
# Move the signature to the witness.
block . vtx . pop ( )
2016-10-06 19:15:33 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2018-06-13 17:56:20 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ signature , pubkey ]
2018-06-13 20:26:25 +02:00
tx2 . vin [ 0 ] . scriptSig = b " "
2016-10-06 19:15:33 +02:00
tx2 . rehash ( )
self . update_witness_block_with_transactions ( block , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-10-06 19:15:33 +02:00
2018-06-13 20:26:25 +02:00
temp_utxos . pop ( 0 )
2016-10-06 19:15:33 +02:00
2018-06-13 20:26:25 +02:00
# Update self.utxos for later tests by creating two outputs
# that consolidate all the coins in temp_utxos.
output_value = sum ( i . nValue for i in temp_utxos ) / / 2
2016-10-06 19:15:33 +02:00
2018-06-13 20:26:25 +02:00
tx = CTransaction ( )
index = 0
# Just spend to our usual anyone-can-spend output
tx . vout = [ CTxOut ( output_value , CScript ( [ OP_TRUE ] ) ) ] * 2
for i in temp_utxos :
# Use SIGHASH_ALL|SIGHASH_ANYONECANPAY so we can build up
# the signatures as we go.
tx . vin . append ( CTxIn ( COutPoint ( i . sha256 , i . n ) , b " " ) )
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
sign_p2pk_witness_input ( witness_script , tx , index , SIGHASH_ALL | SIGHASH_ANYONECANPAY , i . nValue , key )
2018-06-13 20:26:25 +02:00
index + = 1
2016-10-06 19:15:33 +02:00
block = self . build_next_block ( )
2018-06-13 20:26:25 +02:00
self . update_witness_block_with_transactions ( block , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block , accepted = True )
2016-10-06 19:15:33 +02:00
2018-06-13 20:26:25 +02:00
for i in range ( len ( tx . vout ) ) :
self . utxo . append ( UTXO ( tx . sha256 , i , tx . vout [ i ] . nValue ) )
2016-10-06 19:15:33 +02:00
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-04-30 01:34:57 +02:00
def test_non_standard_witness_blinding ( self ) :
2018-06-13 21:58:59 +02:00
""" Test behavior of unnecessary witnesses in transactions does not blind the node for the transaction """
2018-04-30 01:34:57 +02:00
# Create a p2sh output -- this is so we can pass the standardness
# rules (an anyone-can-spend OP_TRUE would be rejected, if not wrapped
# in P2SH).
p2sh_program = CScript ( [ OP_TRUE ] )
2021-06-27 23:52:38 +02:00
script_pubkey = script_to_p2sh_script ( p2sh_program )
2018-04-30 01:34:57 +02:00
# Now check that unnecessary witnesses can't be used to blind a node
# to a transaction, eg by violating standardness checks.
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2018-06-13 17:56:20 +02:00
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
2018-04-30 01:34:57 +02:00
tx . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , False , True )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-04-30 01:34:57 +02:00
# We'll add an unnecessary witness to this transaction that would cause
# it to be non-standard, to test that violating policy with a witness
# doesn't blind a node to a transaction. Transactions
# rejected for having a witness shouldn't be added
# to the rejection cache.
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , CScript ( [ p2sh_program ] ) ) )
2018-06-13 17:56:20 +02:00
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , script_pubkey ) )
2018-04-30 01:34:57 +02:00
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ b ' a ' * 400 ]
tx2 . rehash ( )
# This will be rejected due to a policy check:
# No witness is allowed, since it is not a witness program but a p2sh program
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx2 , True , False , ' bad-witness-nonstandard ' )
2018-04-30 01:34:57 +02:00
# If we send without witness, it should be accepted.
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , tx2 , False , True )
2018-04-30 01:34:57 +02:00
# Now create a new anyone-can-spend utxo for the next test.
tx3 = CTransaction ( )
tx3 . vin . append ( CTxIn ( COutPoint ( tx2 . sha256 , 0 ) , CScript ( [ p2sh_program ] ) ) )
tx3 . vout . append ( CTxOut ( tx2 . vout [ 0 ] . nValue - 1000 , CScript ( [ OP_TRUE , OP_DROP ] * 15 + [ OP_TRUE ] ) ) )
tx3 . rehash ( )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx2 , False , True )
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx3 , False , True )
2018-04-30 01:34:57 +02:00
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-04-30 01:34:57 +02:00
# Update our utxo list; we spent the first entry.
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx3 . sha256 , 0 , tx3 . vout [ 0 ] . nValue ) )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2016-10-16 17:53:16 +02:00
def test_non_standard_witness ( self ) :
2018-06-13 21:58:59 +02:00
""" Test detection of non-standard P2WSH witness """
2016-10-16 17:53:16 +02:00
pad = chr ( 1 ) . encode ( ' latin-1 ' )
# Create scripts for tests
scripts = [ ]
scripts . append ( CScript ( [ OP_DROP ] * 100 ) )
scripts . append ( CScript ( [ OP_DROP ] * 99 ) )
scripts . append ( CScript ( [ pad * 59 ] * 59 + [ OP_DROP ] * 60 ) )
scripts . append ( CScript ( [ pad * 59 ] * 59 + [ OP_DROP ] * 61 ) )
p2wsh_scripts = [ ]
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
# For each script, generate a pair of P2WSH and P2SH-P2WSH output.
outputvalue = ( self . utxo [ 0 ] . nValue - 1000 ) / / ( len ( scripts ) * 2 )
for i in scripts :
2021-06-28 20:45:04 +02:00
p2wsh = script_to_p2wsh_script ( i )
2016-10-16 17:53:16 +02:00
p2wsh_scripts . append ( p2wsh )
tx . vout . append ( CTxOut ( outputvalue , p2wsh ) )
2021-06-27 23:52:38 +02:00
tx . vout . append ( CTxOut ( outputvalue , script_to_p2sh_script ( p2wsh ) ) )
2016-10-16 17:53:16 +02:00
tx . rehash ( )
txid = tx . sha256
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , tx , with_witness = False , accepted = True )
2016-10-16 17:53:16 +02:00
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-10-16 17:53:16 +02:00
# Creating transactions for tests
p2wsh_txs = [ ]
p2sh_txs = [ ]
for i in range ( len ( scripts ) ) :
p2wsh_tx = CTransaction ( )
2018-06-13 17:56:20 +02:00
p2wsh_tx . vin . append ( CTxIn ( COutPoint ( txid , i * 2 ) ) )
2021-06-28 20:45:04 +02:00
p2wsh_tx . vout . append ( CTxOut ( outputvalue - 5000 , CScript ( [ OP_0 , hash160 ( b " " ) ] ) ) )
2016-10-16 17:53:16 +02:00
p2wsh_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
p2wsh_tx . rehash ( )
p2wsh_txs . append ( p2wsh_tx )
p2sh_tx = CTransaction ( )
2018-06-13 17:56:20 +02:00
p2sh_tx . vin . append ( CTxIn ( COutPoint ( txid , i * 2 + 1 ) , CScript ( [ p2wsh_scripts [ i ] ] ) ) )
2021-06-28 20:45:04 +02:00
p2sh_tx . vout . append ( CTxOut ( outputvalue - 5000 , CScript ( [ OP_0 , hash160 ( b " " ) ] ) ) )
2016-10-16 17:53:16 +02:00
p2sh_tx . wit . vtxinwit . append ( CTxInWitness ( ) )
p2sh_tx . rehash ( )
p2sh_txs . append ( p2sh_tx )
# Testing native P2WSH
# Witness stack size, excluding witnessScript, over 100 is non-standard
p2wsh_txs [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad ] * 101 + [ scripts [ 0 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2wsh_txs [ 0 ] , True , False , ' bad-witness-nonstandard ' )
2016-10-16 17:53:16 +02:00
# Non-standard nodes should accept
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2wsh_txs [ 0 ] , True , True )
2016-10-16 17:53:16 +02:00
# Stack element size over 80 bytes is non-standard
p2wsh_txs [ 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad * 81 ] * 100 + [ scripts [ 1 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2wsh_txs [ 1 ] , True , False , ' bad-witness-nonstandard ' )
2016-10-16 17:53:16 +02:00
# Non-standard nodes should accept
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2wsh_txs [ 1 ] , True , True )
2016-10-16 17:53:16 +02:00
# Standard nodes should accept if element size is not over 80 bytes
p2wsh_txs [ 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad * 80 ] * 100 + [ scripts [ 1 ] ]
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2wsh_txs [ 1 ] , True , True )
2016-10-16 17:53:16 +02:00
# witnessScript size at 3600 bytes is standard
p2wsh_txs [ 2 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad , pad , scripts [ 2 ] ]
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2wsh_txs [ 2 ] , True , True )
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2wsh_txs [ 2 ] , True , True )
2016-10-16 17:53:16 +02:00
# witnessScript size at 3601 bytes is non-standard
p2wsh_txs [ 3 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad , pad , pad , scripts [ 3 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2wsh_txs [ 3 ] , True , False , ' bad-witness-nonstandard ' )
2016-10-16 17:53:16 +02:00
# Non-standard nodes should accept
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2wsh_txs [ 3 ] , True , True )
2016-10-16 17:53:16 +02:00
# Repeating the same tests with P2SH-P2WSH
p2sh_txs [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad ] * 101 + [ scripts [ 0 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2sh_txs [ 0 ] , True , False , ' bad-witness-nonstandard ' )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2sh_txs [ 0 ] , True , True )
2016-10-16 17:53:16 +02:00
p2sh_txs [ 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad * 81 ] * 100 + [ scripts [ 1 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2sh_txs [ 1 ] , True , False , ' bad-witness-nonstandard ' )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2sh_txs [ 1 ] , True , True )
2016-10-16 17:53:16 +02:00
p2sh_txs [ 1 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad * 80 ] * 100 + [ scripts [ 1 ] ]
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2sh_txs [ 1 ] , True , True )
2016-10-16 17:53:16 +02:00
p2sh_txs [ 2 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad , pad , scripts [ 2 ] ]
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2sh_txs [ 2 ] , True , True )
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2sh_txs [ 2 ] , True , True )
2016-10-16 17:53:16 +02:00
p2sh_txs [ 3 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ pad , pad , pad , scripts [ 3 ] ]
2018-08-24 21:26:42 +02:00
test_transaction_acceptance ( self . nodes [ 1 ] , self . std_node , p2sh_txs [ 3 ] , True , False , ' bad-witness-nonstandard ' )
2018-08-29 17:50:04 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . test_node , p2sh_txs [ 3 ] , True , True )
2016-10-16 17:53:16 +02:00
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 ) # Mine and clean up the mempool of non-standard node
2016-10-16 17:53:16 +02:00
# Valid but non-standard transactions in a block should be accepted by standard node
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2016-10-16 17:53:16 +02:00
assert_equal ( len ( self . nodes [ 0 ] . getrawmempool ( ) ) , 0 )
assert_equal ( len ( self . nodes [ 1 ] . getrawmempool ( ) ) , 0 )
self . utxo . pop ( 0 )
2020-02-25 20:05:48 +01:00
@subtest # type: ignore
2018-06-13 20:26:25 +02:00
def test_witness_sigops ( self ) :
""" Test sigop counting is correct inside witnesses. """
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# Keep this under MAX_OPS_PER_SCRIPT (201)
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE , OP_IF , OP_TRUE , OP_ELSE ] + [ OP_CHECKMULTISIG ] * 5 + [ OP_CHECKSIG ] * 193 + [ OP_ENDIF ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
sigops_per_script = 20 * 5 + 193 * 1
# We'll produce 2 extra outputs, one with a program that would take us
# over max sig ops, and one with a program that would exactly reach max
# sig ops
outputs = ( MAX_SIGOP_COST / / sigops_per_script ) + 2
extra_sigops_available = MAX_SIGOP_COST % sigops_per_script
2016-04-09 03:02:24 +02:00
2018-06-13 20:26:25 +02:00
# We chose the number of checkmultisigs/checksigs to make this work:
2019-02-19 23:43:44 +01:00
assert extra_sigops_available < 100 # steer clear of MAX_OPS_PER_SCRIPT
2018-06-13 20:26:25 +02:00
# This script, when spent with the first
# N(=MAX_SIGOP_COST//sigops_per_script) outputs of our transaction,
# would push us just over the block sigop limit.
2021-07-11 15:51:48 +02:00
witness_script_toomany = CScript ( [ OP_TRUE , OP_IF , OP_TRUE , OP_ELSE ] + [ OP_CHECKSIG ] * ( extra_sigops_available + 1 ) + [ OP_ENDIF ] )
script_pubkey_toomany = script_to_p2wsh_script ( witness_script_toomany )
2018-06-13 20:26:25 +02:00
# If we spend this script instead, we would exactly reach our sigop
# limit (for witness sigops).
2021-07-11 15:51:48 +02:00
witness_script_justright = CScript ( [ OP_TRUE , OP_IF , OP_TRUE , OP_ELSE ] + [ OP_CHECKSIG ] * ( extra_sigops_available ) + [ OP_ENDIF ] )
script_pubkey_justright = script_to_p2wsh_script ( witness_script_justright )
2018-06-13 20:26:25 +02:00
# First split our available utxo into a bunch of outputs
split_value = self . utxo [ 0 ] . nValue / / outputs
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
2020-08-03 01:10:56 +02:00
for _ in range ( outputs ) :
2018-06-13 20:26:25 +02:00
tx . vout . append ( CTxOut ( split_value , script_pubkey ) )
tx . vout [ - 2 ] . scriptPubKey = script_pubkey_toomany
tx . vout [ - 1 ] . scriptPubKey = script_pubkey_justright
tx . rehash ( )
block_1 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block_1 , [ tx ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_1 , accepted = True )
2018-06-13 20:26:25 +02:00
tx2 = CTransaction ( )
# If we try to spend the first n-1 outputs from tx, that should be
# too many sigops.
total_value = 0
for i in range ( outputs - 1 ) :
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , i ) , b " " ) )
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ witness_script ]
2018-06-13 20:26:25 +02:00
total_value + = tx . vout [ i ] . nValue
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ witness_script_toomany ]
2018-06-13 20:26:25 +02:00
tx2 . vout . append ( CTxOut ( total_value , CScript ( [ OP_TRUE ] ) ) )
tx2 . rehash ( )
block_2 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block_2 , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_2 , accepted = False )
2018-06-13 20:26:25 +02:00
# Try dropping the last input in tx2, and add an output that has
# too many sigops (contributing to legacy sigop count).
checksig_count = ( extra_sigops_available / / 4 ) + 1
script_pubkey_checksigs = CScript ( [ OP_CHECKSIG ] * checksig_count )
tx2 . vout . append ( CTxOut ( 0 , script_pubkey_checksigs ) )
tx2 . vin . pop ( )
tx2 . wit . vtxinwit . pop ( )
tx2 . vout [ 0 ] . nValue - = tx . vout [ - 2 ] . nValue
tx2 . rehash ( )
block_3 = self . build_next_block ( )
self . update_witness_block_with_transactions ( block_3 , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_3 , accepted = False )
2018-06-13 20:26:25 +02:00
# If we drop the last checksig in this output, the tx should succeed.
block_4 = self . build_next_block ( )
tx2 . vout [ - 1 ] . scriptPubKey = CScript ( [ OP_CHECKSIG ] * ( checksig_count - 1 ) )
tx2 . rehash ( )
self . update_witness_block_with_transactions ( block_4 , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_4 , accepted = True )
2018-06-13 20:26:25 +02:00
# Reset the tip back down for the next test
2019-04-07 00:19:45 +02:00
self . sync_blocks ( )
2018-06-13 20:26:25 +02:00
for x in self . nodes :
x . invalidateblock ( block_4 . hash )
# Try replacing the last input of tx2 to be spending the last
# output of tx
block_5 = self . build_next_block ( )
tx2 . vout . pop ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , outputs - 1 ) , b " " ) )
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ - 1 ] . scriptWitness . stack = [ witness_script_justright ]
2018-06-13 20:26:25 +02:00
tx2 . rehash ( )
self . update_witness_block_with_transactions ( block_5 , [ tx2 ] )
2018-08-29 17:50:04 +02:00
test_witness_block ( self . nodes [ 0 ] , self . test_node , block_5 , accepted = True )
2018-06-13 20:26:25 +02:00
# TODO: test p2sh sigop counting
2016-04-09 03:02:24 +02:00
2020-03-27 02:13:32 +01:00
# Cleanup and prep for next test
self . utxo . pop ( 0 )
self . utxo . append ( UTXO ( tx2 . sha256 , 0 , tx2 . vout [ 0 ] . nValue ) )
@subtest # type: ignore
2019-03-21 18:47:47 +01:00
def test_superfluous_witness ( self ) :
2019-05-13 21:38:10 +02:00
# Serialization of tx that puts witness flag to 3 always
2019-03-21 18:47:47 +01:00
def serialize_with_bogus_witness ( tx ) :
2019-05-13 21:38:10 +02:00
flags = 3
2019-03-21 18:47:47 +01:00
r = b " "
r + = struct . pack ( " <i " , tx . nVersion )
if flags :
dummy = [ ]
r + = ser_vector ( dummy )
r + = struct . pack ( " <B " , flags )
r + = ser_vector ( tx . vin )
r + = ser_vector ( tx . vout )
if flags & 1 :
if ( len ( tx . wit . vtxinwit ) != len ( tx . vin ) ) :
# vtxinwit must have the same length as vin
tx . wit . vtxinwit = tx . wit . vtxinwit [ : len ( tx . vin ) ]
2020-08-03 01:10:56 +02:00
for _ in range ( len ( tx . wit . vtxinwit ) , len ( tx . vin ) ) :
2019-03-21 18:47:47 +01:00
tx . wit . vtxinwit . append ( CTxInWitness ( ) )
r + = tx . wit . serialize ( )
r + = struct . pack ( " <I " , tx . nLockTime )
return r
2019-05-13 21:38:10 +02:00
class msg_bogus_tx ( msg_tx ) :
def serialize ( self ) :
return serialize_with_bogus_witness ( self . tx )
self . nodes [ 0 ] . sendtoaddress ( self . nodes [ 0 ] . getnewaddress ( address_type = ' bech32 ' ) , 5 )
2021-08-19 17:10:24 +02:00
self . generate ( self . nodes [ 0 ] , 1 )
2019-05-13 21:38:10 +02:00
unspent = next ( u for u in self . nodes [ 0 ] . listunspent ( ) if u [ ' spendable ' ] and u [ ' address ' ] . startswith ( ' bcrt ' ) )
raw = self . nodes [ 0 ] . createrawtransaction ( [ { " txid " : unspent [ ' txid ' ] , " vout " : unspent [ ' vout ' ] } ] , { self . nodes [ 0 ] . getnewaddress ( ) : 1 } )
2021-06-15 23:02:28 +02:00
tx = tx_from_hex ( raw )
2020-11-02 10:35:06 +01:00
assert_raises_rpc_error ( - 22 , " TX decode failed " , self . nodes [ 0 ] . decoderawtransaction , hexstring = serialize_with_bogus_witness ( tx ) . hex ( ) , iswitness = True )
2019-05-13 21:38:10 +02:00
with self . nodes [ 0 ] . assert_debug_log ( [ ' Superfluous witness record ' ] ) :
2020-09-04 03:05:26 +02:00
self . test_node . send_and_ping ( msg_bogus_tx ( tx ) )
2019-05-13 21:38:10 +02:00
raw = self . nodes [ 0 ] . signrawtransactionwithwallet ( raw )
assert raw [ ' complete ' ]
raw = raw [ ' hex ' ]
2021-06-15 23:02:28 +02:00
tx = tx_from_hex ( raw )
2020-11-02 10:35:06 +01:00
assert_raises_rpc_error ( - 22 , " TX decode failed " , self . nodes [ 0 ] . decoderawtransaction , hexstring = serialize_with_bogus_witness ( tx ) . hex ( ) , iswitness = True )
2019-05-13 21:38:10 +02:00
with self . nodes [ 0 ] . assert_debug_log ( [ ' Unknown transaction optional data ' ] ) :
2020-09-04 03:05:26 +02:00
self . test_node . send_and_ping ( msg_bogus_tx ( tx ) )
2019-05-13 21:38:10 +02:00
2020-03-27 02:13:32 +01:00
@subtest # type: ignore
def test_wtxid_relay ( self ) :
# Use brand new nodes to avoid contamination from earlier tests
2021-09-19 14:11:09 +02:00
self . wtx_node = self . nodes [ 0 ] . add_p2p_connection ( TestP2PConn ( wtxidrelay = True ) , services = P2P_SERVICES )
self . tx_node = self . nodes [ 0 ] . add_p2p_connection ( TestP2PConn ( wtxidrelay = False ) , services = P2P_SERVICES )
2020-03-27 02:13:32 +01:00
# Check wtxidrelay feature negotiation message through connecting a new peer
def received_wtxidrelay ( ) :
return ( len ( self . wtx_node . last_wtxidrelay ) > 0 )
2020-08-17 17:50:47 +02:00
self . wtx_node . wait_until ( received_wtxidrelay )
2020-03-27 02:13:32 +01:00
# Create a Segwit output from the latest UTXO
# and announce it to the network
2021-07-11 15:51:48 +02:00
witness_script = CScript ( [ OP_TRUE ] )
script_pubkey = script_to_p2wsh_script ( witness_script )
2020-03-27 02:13:32 +01:00
tx = CTransaction ( )
tx . vin . append ( CTxIn ( COutPoint ( self . utxo [ 0 ] . sha256 , self . utxo [ 0 ] . n ) , b " " ) )
tx . vout . append ( CTxOut ( self . utxo [ 0 ] . nValue - 1000 , script_pubkey ) )
tx . rehash ( )
# Create a Segwit transaction
tx2 = CTransaction ( )
tx2 . vin . append ( CTxIn ( COutPoint ( tx . sha256 , 0 ) , b " " ) )
tx2 . vout . append ( CTxOut ( tx . vout [ 0 ] . nValue - 1000 , script_pubkey ) )
tx2 . wit . vtxinwit . append ( CTxInWitness ( ) )
2021-07-11 15:51:48 +02:00
tx2 . wit . vtxinwit [ 0 ] . scriptWitness . stack = [ witness_script ]
2020-03-27 02:13:32 +01:00
tx2 . rehash ( )
# Announce Segwit transaction with wtxid
# and wait for getdata
self . wtx_node . announce_tx_and_wait_for_getdata ( tx2 , use_wtxid = True )
2020-07-19 09:47:05 +02:00
with p2p_lock :
2020-03-27 02:13:32 +01:00
lgd = self . wtx_node . lastgetdata [ : ]
assert_equal ( lgd , [ CInv ( MSG_WTX , tx2 . calc_sha256 ( True ) ) ] )
# Announce Segwit transaction from non wtxidrelay peer
# and wait for getdata
self . tx_node . announce_tx_and_wait_for_getdata ( tx2 , use_wtxid = False )
2020-07-19 09:47:05 +02:00
with p2p_lock :
2020-03-27 02:13:32 +01:00
lgd = self . tx_node . lastgetdata [ : ]
assert_equal ( lgd , [ CInv ( MSG_TX | MSG_WITNESS_FLAG , tx2 . sha256 ) ] )
# Send tx2 through; it's an orphan so won't be accepted
2020-07-19 09:47:05 +02:00
with p2p_lock :
2020-07-07 10:11:19 +02:00
self . wtx_node . last_message . pop ( " getdata " , None )
test_transaction_acceptance ( self . nodes [ 0 ] , self . wtx_node , tx2 , with_witness = True , accepted = False )
2020-03-27 02:13:32 +01:00
2020-07-07 10:11:19 +02:00
# Expect a request for parent (tx) by txid despite use of WTX peer
self . wtx_node . wait_for_getdata ( [ tx . sha256 ] , 60 )
2020-07-19 09:47:05 +02:00
with p2p_lock :
2020-07-07 10:11:19 +02:00
lgd = self . wtx_node . lastgetdata [ : ]
2020-08-08 13:22:19 +02:00
assert_equal ( lgd , [ CInv ( MSG_WITNESS_TX , tx . sha256 ) ] )
2020-03-27 02:13:32 +01:00
# Send tx through
2020-07-07 10:11:19 +02:00
test_transaction_acceptance ( self . nodes [ 0 ] , self . wtx_node , tx , with_witness = False , accepted = True )
2020-03-27 02:13:32 +01:00
# Check tx2 is there now
assert_equal ( tx2 . hash in self . nodes [ 0 ] . getrawmempool ( ) , True )
2019-03-21 18:47:47 +01:00
2016-04-09 03:02:24 +02:00
if __name__ == ' __main__ ' :
SegWitTest ( ) . main ( )