diff options
author | Anthony Towns <aj@erisian.com.au> | 2018-01-25 09:44:29 +1000 |
---|---|---|
committer | Anthony Towns <aj@erisian.com.au> | 2018-01-25 09:44:29 +1000 |
commit | 61b8f7f273022d3163f998ff5d66d53ca0460c8b (patch) | |
tree | f0c697967c9a15ea61758170af0cd0418ab34585 /test/functional/p2p-segwit.py | |
parent | 90600bc7db2a8047c93bc10d403e862141ada770 (diff) |
[tests] Rename p2p_* functional tests.
Diffstat (limited to 'test/functional/p2p-segwit.py')
-rwxr-xr-x | test/functional/p2p-segwit.py | 1952 |
1 files changed, 0 insertions, 1952 deletions
diff --git a/test/functional/p2p-segwit.py b/test/functional/p2p-segwit.py deleted file mode 100755 index 20e4805df0..0000000000 --- a/test/functional/p2p-segwit.py +++ /dev/null @@ -1,1952 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2016-2017 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test segwit transactions and blocks on P2P network.""" - -from test_framework.mininode import * -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.script import * -from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment, get_witness_script, WITNESS_COMMITMENT_HEADER -from test_framework.key import CECKey, CPubKey -import time -import random -from binascii import hexlify - -# The versionbit bit used to signal activation of SegWit -VB_WITNESS_BIT = 1 -VB_PERIOD = 144 -VB_TOP_BITS = 0x20000000 - -MAX_SIGOP_COST = 80000 - - -# Calculate the virtual size of a witness block: -# (base + witness/4) -def get_virtual_size(witness_block): - base_size = len(witness_block.serialize(with_witness=False)) - total_size = len(witness_block.serialize(with_witness=True)) - # the "+3" is so we round up - vsize = int((3*base_size + total_size + 3)/4) - return vsize - -def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=None): - """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.""" - tx_message = msg_tx(tx) - if with_witness: - tx_message = msg_witness_tx(tx) - p2p.send_message(tx_message) - p2p.sync_with_ping() - assert_equal(tx.hash in rpc.getrawmempool(), accepted) - if (reason != None and not accepted): - # Check the rejection reason as well. - with mininode_lock: - assert_equal(p2p.last_message["reject"].reason, reason) - -def test_witness_block(rpc, p2p, block, accepted, with_witness=True): - """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.""" - if with_witness: - p2p.send_message(msg_witness_block(block)) - else: - p2p.send_message(msg_block(block)) - p2p.sync_with_ping() - assert_equal(rpc.getbestblockhash() == block.hash, accepted) - -class TestNode(P2PInterface): - def __init__(self): - super().__init__() - self.getdataset = set() - - def on_getdata(self, message): - for inv in message.inv: - self.getdataset.add(inv.hash) - - def announce_tx_and_wait_for_getdata(self, tx, timeout=60): - with mininode_lock: - self.last_message.pop("getdata", None) - self.send_message(msg_inv(inv=[CInv(1, tx.sha256)])) - self.wait_for_getdata(timeout) - - def announce_block_and_wait_for_getdata(self, block, use_header, timeout=60): - with mininode_lock: - self.last_message.pop("getdata", None) - self.last_message.pop("getheaders", None) - msg = msg_headers() - msg.headers = [ CBlockHeader(block) ] - if use_header: - self.send_message(msg) - else: - self.send_message(msg_inv(inv=[CInv(2, block.sha256)])) - self.wait_for_getheaders() - self.send_message(msg) - self.wait_for_getdata() - - def request_block(self, blockhash, inv_type, timeout=60): - with mininode_lock: - self.last_message.pop("block", None) - self.send_message(msg_getdata(inv=[CInv(inv_type, blockhash)])) - self.wait_for_block(blockhash, timeout) - return self.last_message["block"].block - -# Used to keep track of anyone-can-spend outputs that we can use in the tests -class UTXO(): - def __init__(self, sha256, n, nValue): - self.sha256 = sha256 - self.n = n - self.nValue = nValue - -# Helper for getting the script associated with a P2PKH -def GetP2PKHScript(pubkeyhash): - return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) - -# Add signature for a P2PK witness program. -def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): - tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) - signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') - txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] - txTo.rehash() - - -class SegWitTest(BitcoinTestFramework): - def set_test_params(self): - self.setup_clean_chain = True - self.num_nodes = 3 - # This test tests SegWit both pre and post-activation, so use the normal BIP9 activation. - self.extra_args = [["-whitelist=127.0.0.1", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-acceptnonstdtxn=0", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-vbparams=segwit:0:0"]] - - def setup_network(self): - self.setup_nodes() - connect_nodes(self.nodes[0], 1) - connect_nodes(self.nodes[0], 2) - self.sync_all() - - ''' Helpers ''' - # Build a block on top of node0's tip. - def build_next_block(self, nVersion=4): - 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) - block.nVersion = nVersion - block.rehash() - return block - - # Adds list of transactions to block, adds witness commitment, then solves. - def update_witness_block_with_transactions(self, block, tx_list, nonce=0): - block.vtx.extend(tx_list) - add_witness_commitment(block, nonce) - block.solve() - return - - ''' Individual tests ''' - def test_witness_services(self): - self.log.info("Verifying NODE_WITNESS service bit") - assert((self.test_node.nServices & NODE_WITNESS) != 0) - - - # See if sending a regular transaction works, and create a utxo - # to use in later tests. - def test_non_witness_transaction(self): - # Mine a block with an anyone-can-spend coinbase, - # let it mature, then try to spend it. - self.log.info("Testing non-witness transaction") - block = self.build_next_block(nVersion=1) - block.solve() - self.test_node.send_message(msg_block(block)) - self.test_node.sync_with_ping() # make sure the block was processed - txid = block.vtx[0].sha256 - - self.nodes[0].generate(99) # let the block mature - - # Create a transaction that spends the coinbase - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(txid, 0), b"")) - tx.vout.append(CTxOut(49*100000000, CScript([OP_TRUE]))) - tx.calc_sha256() - - # Check that serializing it with or without witness is the same - # This is a sanity check of our testing framework. - assert_equal(msg_tx(tx).serialize(), msg_witness_tx(tx).serialize()) - - self.test_node.send_message(msg_witness_tx(tx)) - self.test_node.sync_with_ping() # make sure the tx was processed - assert(tx.hash in self.nodes[0].getrawmempool()) - # Save this transaction for later - self.utxo.append(UTXO(tx.sha256, 0, 49*100000000)) - self.nodes[0].generate(1) - - - # Verify that blocks with witnesses are rejected before activation. - def test_unnecessary_witness_before_segwit_activation(self): - self.log.info("Testing behavior of unnecessary witnesses") - # For now, rely on earlier tests to have created at least one utxo for - # us to use - assert(len(self.utxo) > 0) - assert(get_bip9_status(self.nodes[0], 'segwit')['status'] != 'active') - - 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]))) - tx.wit.vtxinwit.append(CTxInWitness()) - 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() - assert(tx.sha256 != tx.calc_sha256(with_witness=True)) - - # Construct a segwit-signaling block that includes the transaction. - block = self.build_next_block(nVersion=(VB_TOP_BITS|(1 << VB_WITNESS_BIT))) - self.update_witness_block_with_transactions(block, [tx]) - # Sending witness data before activation is not allowed (anti-spam - # rule). - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - # TODO: fix synchronization so we can test reject reason - # Right now, bitcoind delays sending reject messages for blocks - # until the future, making synchronization here difficult. - #assert_equal(self.test_node.last_message["reject"].reason, "unexpected-witness") - - # But it should not be permanently marked bad... - # Resend without witness information. - self.test_node.send_message(msg_block(block)) - self.test_node.sync_with_ping() - assert_equal(self.nodes[0].getbestblockhash(), block.hash) - - sync_blocks(self.nodes) - - # 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]) - p2sh_pubkey = hash160(p2sh_program) - scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) - - # Now check that unnecessary witnesses can't be used to blind a node - # to a transaction, eg by violating standardness checks. - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptPubKey)) - tx2.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, False, True) - self.nodes[0].generate(1) - sync_blocks(self.nodes) - - # 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 before - # segwit activation doesn't blind a node to a transaction. Transactions - # rejected for having a witness before segwit activation shouldn't be added - # to the rejection cache. - tx3 = CTransaction() - tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) - tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptPubKey)) - tx3.wit.vtxinwit.append(CTxInWitness()) - tx3.wit.vtxinwit[0].scriptWitness.stack = [b'a'*400000] - tx3.rehash() - # Note that this should be rejected for the premature witness reason, - # rather than a policy check, since segwit hasn't activated yet. - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'no-witness-yet') - - # If we send without witness, it should be accepted. - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, False, True) - - # Now create a new anyone-can-spend utxo for the next test. - tx4 = CTransaction() - tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), CScript([p2sh_program]))) - tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx4.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, False, True) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx4, False, True) - - self.nodes[0].generate(1) - sync_blocks(self.nodes) - - # Update our utxo list; we spent the first entry. - self.utxo.pop(0) - self.utxo.append(UTXO(tx4.sha256, 0, tx4.vout[0].nValue)) - - - # Mine enough blocks for segwit's vb state to be 'started'. - def advance_to_segwit_started(self): - height = self.nodes[0].getblockcount() - # Will need to rewrite the tests here if we are past the first period - assert(height < VB_PERIOD - 1) - # Genesis block is 'defined'. - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'defined') - # Advance to end of period, status should now be 'started' - self.nodes[0].generate(VB_PERIOD-height-1) - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') - - # Mine enough blocks to lock in segwit, but don't activate. - # TODO: we could verify that lockin only happens at the right threshold of - # signalling blocks, rather than just at the right period boundary. - def advance_to_segwit_lockin(self): - height = self.nodes[0].getblockcount() - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') - # Advance to end of period, and verify lock-in happens at the end - self.nodes[0].generate(VB_PERIOD-1) - height = self.nodes[0].getblockcount() - assert((height % VB_PERIOD) == VB_PERIOD - 2) - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started') - self.nodes[0].generate(1) - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') - - - # Mine enough blocks to activate segwit. - # TODO: we could verify that activation only happens at the right threshold - # of signalling blocks, rather than just at the right period boundary. - def advance_to_segwit_active(self): - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') - height = self.nodes[0].getblockcount() - self.nodes[0].generate(VB_PERIOD - (height%VB_PERIOD) - 2) - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') - self.nodes[0].generate(1) - assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active') - - - # This test can only be run after segwit has activated - def test_witness_commitments(self): - self.log.info("Testing witness commitments") - - # 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 - assert(msg_witness_block(block).serialize() != msg_block(block).serialize()) - - # This empty block should be valid. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # 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! - assert(block_2.vtx[0].vout[-1] != block.vtx[0].vout[-1]) - - # This should also be valid. - test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=True) - - # Now test commitments with actual transactions - assert (len(self.utxo) > 0) - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) - - # Let's construct a witness program - witness_program = CScript([OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) - 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"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, witness_program)) - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] - 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() - - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False) - - # 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() - assert(len(block_3.vtx[0].vout) == 4) # 3 OP_returns - block_3.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=True) - - # 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"")) - tx3.vout.append(CTxOut(tx.vout[0].nValue-1000, witness_program)) - tx3.rehash() - block_4.vtx.append(tx3) - block_4.hashMerkleRoot = block_4.calc_merkle_root() - block_4.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block_4, with_witness=False, accepted=True) - - # Update available utxo's for use in later test. - self.utxo.pop(0) - self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) - - - def test_block_malleability(self): - self.log.info("Testing witness block malleability") - - # 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() - - block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.append(b'a'*5000000) - assert(get_virtual_size(block) > MAX_BLOCK_BASE_SIZE) - - # 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 - self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) - - assert(self.nodes[0].getbestblockhash() != block.hash) - - block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop() - assert(get_virtual_size(block) < MAX_BLOCK_BASE_SIZE) - self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) - - assert(self.nodes[0].getbestblockhash() == block.hash) - - # Now make sure that malleating the witness nonce doesn't - # 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 - block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ ser_uint256(1) ] - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Changing the witness nonce doesn't change the block hash - block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ ser_uint256(0) ] - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - - def test_witness_block_size(self): - self.log.info("Testing witness block size limit") - # 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() - - assert(len(self.utxo) > 0) - - # Create a P2WSH transaction. - # The witness program will be a bunch of OP_2DROP's, followed by OP_TRUE. - # This should give us plenty of room to tweak the spending tx's - # virtual size. - NUM_DROPS = 200 # 201 max ops per script! - NUM_OUTPUTS = 50 - - witness_program = CScript([OP_2DROP]*NUM_DROPS + [OP_TRUE]) - witness_hash = uint256_from_str(sha256(witness_program)) - scriptPubKey = CScript([OP_0, ser_uint256(witness_hash)]) - - 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"")) - child_value = int(value/NUM_OUTPUTS) - for i in range(NUM_OUTPUTS): - parent_tx.vout.append(CTxOut(child_value, scriptPubKey)) - parent_tx.vout[0].nValue -= 50000 - assert(parent_tx.vout[0].nValue > 0) - 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]))] - for i in range(NUM_OUTPUTS): - child_tx.wit.vtxinwit.append(CTxInWitness()) - child_tx.wit.vtxinwit[-1].scriptWitness.stack = [b'a'*195]*(2*NUM_DROPS) + [witness_program] - child_tx.rehash() - self.update_witness_block_with_transactions(block, [parent_tx, child_tx]) - - vsize = get_virtual_size(block) - additional_bytes = (MAX_BLOCK_BASE_SIZE - vsize)*4 - i = 0 - while additional_bytes > 0: - # Add some more bytes to each input until we hit MAX_BLOCK_BASE_SIZE+1 - 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) - additional_bytes -= extra_bytes - i += 1 - - block.vtx[0].vout.pop() # Remove old commitment - add_witness_commitment(block) - block.solve() - vsize = get_virtual_size(block) - assert_equal(vsize, MAX_BLOCK_BASE_SIZE + 1) - # Make sure that our test case would exceed the old max-network-message - # limit - assert(len(block.serialize(True)) > 2*1024*1024) - - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Now resize the second transaction to make the block fit. - cur_length = len(block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0]) - block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0] = b'a'*(cur_length-1) - block.vtx[0].vout.pop() - add_witness_commitment(block) - block.solve() - assert(get_virtual_size(block) == MAX_BLOCK_BASE_SIZE) - - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Update available utxo's - self.utxo.pop(0) - self.utxo.append(UTXO(block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue)) - - - # submitblock will try to add the nonce automatically, so that mining - # software doesn't need to worry about doing so itself. - def test_submit_block(self): - 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) - block.vtx[0].wit = CTxWitness() # drop the nonce - block.solve() - self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) - assert(self.nodes[0].getbestblockhash() != block.hash) - - # 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() - self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) - 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() - - self.nodes[0].submitblock(bytes_to_hex_str(block_2.serialize(True))) - # Tip should not advance! - assert(self.nodes[0].getbestblockhash() != block_2.hash) - - - # Consensus tests of extra witness data in a transaction. - def test_extra_witness_data(self): - self.log.info("Testing extra witness data in tx") - - assert(len(self.utxo) > 0) - - block = self.build_next_block() - - witness_program = CScript([OP_DROP, OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - # 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"")) - tx.vout.append(CTxOut(self.utxo[0].nValue-2000, scriptPubKey)) - tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output - tx.wit.vtxinwit.append(CTxInWitness()) - tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])] - tx.rehash() - self.update_witness_block_with_transactions(block, [tx]) - - # Extra witness data should not be allowed. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # 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() - - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Now try extra witness/signature data on an input that DOES require a - # witness - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) # witness output - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 1), b"")) # non-witness - tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()]) - tx2.wit.vtxinwit[0].scriptWitness.stack = [ CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_program ] - tx2.wit.vtxinwit[1].scriptWitness.stack = [ CScript([OP_TRUE]) ] - - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx2]) - - # This has extra witness data, so it should fail. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # 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. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # 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() - - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Update utxo for later tests - self.utxo.pop(0) - self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) - - - def test_max_witness_push_length(self): - ''' Should only allow up to 520 byte pushes in witness stack ''' - self.log.info("Testing maximum witness push size") - MAX_SCRIPT_ELEMENT_SIZE = 520 - assert(len(self.utxo)) - - block = self.build_next_block() - - witness_program = CScript([OP_DROP, OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - 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, scriptPubKey)) - tx.rehash() - - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.append(CTxInWitness()) - # First try a 521-byte stack element - tx2.wit.vtxinwit[0].scriptWitness.stack = [ b'a'*(MAX_SCRIPT_ELEMENT_SIZE+1), witness_program ] - tx2.rehash() - - self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Now reduce the length of the stack element - tx2.wit.vtxinwit[0].scriptWitness.stack[0] = b'a'*(MAX_SCRIPT_ELEMENT_SIZE) - - add_witness_commitment(block) - block.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Update the utxo for later tests - self.utxo.pop() - self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) - - def test_max_witness_program_length(self): - # Can create witness outputs that are long, but can't be greater than - # 10k bytes to successfully spend - self.log.info("Testing maximum witness program length") - assert(len(self.utxo)) - MAX_PROGRAM_LENGTH = 10000 - - # This program is 19 max pushes (9937 bytes), then 64 more opcode-bytes. - long_witness_program = CScript([b'a'*520]*19 + [OP_DROP]*63 + [OP_TRUE]) - assert(len(long_witness_program) == MAX_PROGRAM_LENGTH+1) - long_witness_hash = sha256(long_witness_program) - long_scriptPubKey = CScript([OP_0, long_witness_hash]) - - block = self.build_next_block() - - 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, long_scriptPubKey)) - tx.rehash() - - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))) - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a']*44 + [long_witness_program] - tx2.rehash() - - self.update_witness_block_with_transactions(block, [tx, tx2]) - - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Try again with one less byte in the witness program - witness_program = CScript([b'a'*520]*19 + [OP_DROP]*62 + [OP_TRUE]) - assert(len(witness_program) == MAX_PROGRAM_LENGTH) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - tx.vout[0] = CTxOut(tx.vout[0].nValue, scriptPubKey) - tx.rehash() - tx2.vin[0].prevout.hash = tx.sha256 - tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a']*43 + [witness_program] - tx2.rehash() - block.vtx = [block.vtx[0]] - self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - self.utxo.pop() - self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) - - - def test_witness_input_length(self): - ''' Ensure that vin length must match vtxinwit length ''' - self.log.info("Testing witness input length") - assert(len(self.utxo)) - - witness_program = CScript([OP_DROP, OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - # 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"")) - nValue = self.utxo[0].nValue - for i in range(10): - tx.vout.append(CTxOut(int(nValue/10), scriptPubKey)) - tx.vout[0].nValue -= 1000 - assert(tx.vout[0].nValue >= 0) - - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # 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"")) - tx2.vout.append(CTxOut(nValue-3000, CScript([OP_TRUE]))) - - # First try using a too long vtxinwit - for i in range(11): - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[i].scriptWitness.stack = [b'a', witness_program] - - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # 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]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Now make one of the intermediate witnesses be incorrect - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[-1].scriptWitness.stack = [b'a', witness_program] - tx2.wit.vtxinwit[5].scriptWitness.stack = [ witness_program ] - - block.vtx = [block.vtx[0]] - self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Fix the broken witness and the block should be accepted. - tx2.wit.vtxinwit[5].scriptWitness.stack = [b'a', witness_program] - block.vtx = [block.vtx[0]] - self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - self.utxo.pop() - self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) - - - def test_witness_tx_relay_before_segwit_activation(self): - self.log.info("Testing relay of witness transactions") - # 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. - assert(len(self.utxo)) - 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]))) - 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) - assert(self.old_node.last_message["getdata"].inv[0].type == 1) - - # Since we haven't delivered the tx yet, inv'ing the same tx from - # a witness transaction ought not result in a getdata. - try: - self.test_node.announce_tx_and_wait_for_getdata(tx, timeout=2) - self.log.error("Error: duplicate tx getdata!") - assert(False) - except AssertionError as e: - pass - - # 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) - test_transaction_acceptance(self.nodes[0].rpc, self.old_node, tx, with_witness=True, accepted=False) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False) - - # But eliminating the witness should fix it - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) - - # Cleanup: mine the first transaction and update utxo - self.nodes[0].generate(1) - assert_equal(len(self.nodes[0].getrawmempool()), 0) - - self.utxo.pop(0) - self.utxo.append(UTXO(tx_hash, 0, tx_value)) - - - # 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. - def test_tx_relay_after_segwit_activation(self): - self.log.info("Testing relay of witness transactions") - # 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. - assert(len(self.utxo)) - 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]))) - tx.wit.vtxinwit.append(CTxInWitness()) - tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a' ] - 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) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False) - - # Verify that removing the witness succeeds. - self.test_node.announce_tx_and_wait_for_getdata(tx) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) - - # Now try to add extra witness data to a valid witness tx. - witness_program = CScript([OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx_hash, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptPubKey)) - tx2.rehash() - - tx3 = CTransaction() - tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) - tx3.wit.vtxinwit.append(CTxInWitness()) - - # Add too-large for IsStandard witness and check that it does not enter reject filter - p2sh_program = CScript([OP_TRUE]) - p2sh_pubkey = hash160(p2sh_program) - witness_program2 = CScript([b'a'*400000]) - tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]))) - tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program2] - tx3.rehash() - - # Node will not be blinded to the transaction - self.std_node.announce_tx_and_wait_for_getdata(tx3) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size') - self.std_node.announce_tx_and_wait_for_getdata(tx3) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size') - - # Remove witness stuffing, instead add extra witness push on stack - tx3.vout[0] = CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE])) - tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program ] - tx3.rehash() - - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False) - - # Get rid of the extra witness, and verify acceptance. - tx3.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] - # Also check that old_node gets a tx announcement, even though this is - # a witness transaction. - self.old_node.wait_for_inv([CInv(1, tx2.sha256)]) # wait until tx2 was inv'ed - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True) - self.old_node.wait_for_inv([CInv(1, tx3.sha256)]) - - # 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())) - vsize = (len(tx3.serialize_with_witness()) + 3*len(tx3.serialize_without_witness()) + 3) / 4 - assert_equal(raw_tx["vsize"], vsize) - assert_equal(len(raw_tx["vin"][0]["txinwitness"]), 1) - assert_equal(raw_tx["vin"][0]["txinwitness"][0], hexlify(witness_program).decode('ascii')) - assert(vsize != raw_tx["size"]) - - # Cleanup: mine the transactions and update utxo for next test - self.nodes[0].generate(1) - assert_equal(len(self.nodes[0].getrawmempool()), 0) - - self.utxo.pop(0) - self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) - - - # 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 - def test_block_relay(self, segwit_activated): - self.log.info("Testing block relay") - - 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 - # announcing a version 4 or random VB block with a header results in a getdata - block1 = self.build_next_block() - block1.solve() - - self.test_node.announce_block_and_wait_for_getdata(block1, use_header=False) - assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block1, True) - - block2 = self.build_next_block(nVersion=4) - block2.solve() - - self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True) - assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, True) - - block3 = self.build_next_block(nVersion=(VB_TOP_BITS | (1<<15))) - block3.solve() - self.test_node.announce_block_and_wait_for_getdata(block3, use_header=True) - assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block3, True) - - # Check that we can getdata for witness blocks or regular blocks, - # and the right thing happens. - if segwit_activated == False: - # 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) - assert_equal(block.serialize(True), wit_block.serialize(True)) - assert_equal(block.serialize(), hex_str_to_bytes(rpc_block)) - 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. - assert(len(block.vtx[0].wit.vtxinwit) == 1) - assert(len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack) == 1) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - # 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) - assert_equal(wit_block.serialize(True), hex_str_to_bytes(rpc_block)) - assert_equal(wit_block.serialize(False), non_wit_block.serialize()) - assert_equal(wit_block.serialize(True), block.serialize(True)) - - # Test size, vsize, weight - rpc_details = self.nodes[0].getblock(block.hash, True) - assert_equal(rpc_details["size"], len(block.serialize(True))) - assert_equal(rpc_details["strippedsize"], len(block.serialize(False))) - weight = 3*len(block.serialize(False)) + len(block.serialize(True)) - assert_equal(rpc_details["weight"], weight) - - # Upgraded node should not ask for blocks from unupgraded - block4 = self.build_next_block(nVersion=4) - 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]) - assert(block4.sha256 not in self.old_node.getdataset) - - # V0 segwit outputs should be standard after activation, but not before. - def test_standardness_v0(self, segwit_activated): - self.log.info("Testing standardness of v0 outputs (%s activation)" % ("after" if segwit_activated else "before")) - assert(len(self.utxo)) - - witness_program = CScript([OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - p2sh_pubkey = hash160(witness_program) - p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) - - # 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_scriptPubKey)] - p2sh_tx.rehash() - - # Mine it on test_node to create the confirmed output. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_tx, with_witness=True, accepted=True) - self.nodes[0].generate(1) - sync_blocks(self.nodes) - - # Now test standardness of v0 P2WSH outputs. - # Start by creating a transaction with two outputs. - tx = CTransaction() - tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] - tx.vout = [CTxOut(p2sh_tx.vout[0].nValue-10000, scriptPubKey)] - tx.vout.append(CTxOut(8000, scriptPubKey)) # Might burn this later - tx.rehash() - - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=segwit_activated) - - # Now create something that looks like a P2PKH output. This won't be spendable. - scriptPubKey = CScript([OP_0, hash160(witness_hash)]) - tx2 = CTransaction() - if segwit_activated: - # if tx was accepted, then we spend the second output. - tx2.vin = [CTxIn(COutPoint(tx.sha256, 1), b"")] - tx2.vout = [CTxOut(7000, scriptPubKey)] - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] - else: - # if tx wasn't accepted, we just re-spend the p2sh output we started with. - tx2.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] - tx2.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, scriptPubKey)] - tx2.rehash() - - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=segwit_activated) - - # Now update self.utxo for later tests. - tx3 = CTransaction() - if segwit_activated: - # 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. - sync_mempools([self.nodes[0], self.nodes[1]]) - tx3.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] - tx3.vout = [CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))] - tx3.wit.vtxinwit.append(CTxInWitness()) - tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program] - tx3.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True) - else: - # tx and tx2 didn't go anywhere; just clean up the p2sh_tx output. - tx3.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] - tx3.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, witness_program)] - tx3.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True) - - self.nodes[0].generate(1) - sync_blocks(self.nodes) - self.utxo.pop(0) - self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) - assert_equal(len(self.nodes[1].getrawmempool()), 0) - - - # Verify that future segwit upgraded transactions are non-standard, - # but valid in blocks. Can run this before and after segwit activation. - def test_segwit_versions(self): - self.log.info("Testing standardness/consensus for segwit versions (0-16)") - assert(len(self.utxo)) - NUM_TESTS = 17 # will test OP_0, OP1, ..., OP_16 - if (len(self.utxo) < NUM_TESTS): - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) - split_value = (self.utxo[0].nValue - 4000) // NUM_TESTS - for i in range(NUM_TESTS): - tx.vout.append(CTxOut(split_value, CScript([OP_TRUE]))) - tx.rehash() - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - self.utxo.pop(0) - for i in range(NUM_TESTS): - self.utxo.append(UTXO(tx.sha256, i, split_value)) - - sync_blocks(self.nodes) - temp_utxo = [] - tx = CTransaction() - count = 0 - witness_program = CScript([OP_TRUE]) - witness_hash = sha256(witness_program) - assert_equal(len(self.nodes[1].getrawmempool()), 0) - for version in list(range(OP_1, OP_16+1)) + [OP_0]: - count += 1 - # First try to spend to a future version segwit scriptPubKey. - scriptPubKey = CScript([CScriptOp(version), witness_hash]) - tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] - tx.vout = [CTxOut(self.utxo[0].nValue-1000, scriptPubKey)] - tx.rehash() - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=False) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True) - self.utxo.pop(0) - temp_utxo.append(UTXO(tx.sha256, 0, tx.vout[0].nValue)) - - self.nodes[0].generate(1) # Mine all the transactions - sync_blocks(self.nodes) - assert(len(self.nodes[0].getrawmempool()) == 0) - - # Finally, verify that version 0 -> version 1 transactions - # are non-standard - scriptPubKey = CScript([CScriptOp(OP_1), witness_hash]) - tx2 = CTransaction() - tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] - tx2.vout = [CTxOut(tx.vout[0].nValue-1000, scriptPubKey)] - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] - tx2.rehash() - # Gets accepted to test_node, because standardness of outputs isn't - # checked with fRequireStandard - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=False) - temp_utxo.pop() # last entry in temp_utxo was the output we just spent - temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) - - # Spend everything in temp_utxo back to an OP_TRUE output. - tx3 = CTransaction() - total_value = 0 - for i in temp_utxo: - tx3.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) - tx3.wit.vtxinwit.append(CTxInWitness()) - total_value += i.nValue - tx3.wit.vtxinwit[-1].scriptWitness.stack = [witness_program] - tx3.vout.append(CTxOut(total_value - 1000, CScript([OP_TRUE]))) - tx3.rehash() - # Spending a higher version witness output is not allowed by policy, - # even with fRequireStandard=false. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False) - self.test_node.sync_with_ping() - with mininode_lock: - assert(b"reserved for soft-fork upgrades" in self.test_node.last_message["reject"].reason) - - # Building a block with the transaction must be valid, however. - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx2, tx3]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - sync_blocks(self.nodes) - - # Add utxo to our list - self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) - - - def test_premature_coinbase_witness_spend(self): - self.log.info("Testing premature coinbase witness spend") - block = self.build_next_block() - # Change the output of the block to be a witness output. - witness_program = CScript([OP_TRUE]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - block.vtx[0].vout[0].scriptPubKey = scriptPubKey - # This next line will rehash the coinbase and update the merkle - # root, and solve. - self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - spend_tx = CTransaction() - spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")] - spend_tx.vout = [CTxOut(block.vtx[0].vout[0].nValue, witness_program)] - spend_tx.wit.vtxinwit.append(CTxInWitness()) - spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ witness_program ] - spend_tx.rehash() - - # Now test a premature spend. - self.nodes[0].generate(98) - sync_blocks(self.nodes) - block2 = self.build_next_block() - self.update_witness_block_with_transactions(block2, [spend_tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=False) - - # Advancing one more block should allow the spend. - self.nodes[0].generate(1) - block2 = self.build_next_block() - self.update_witness_block_with_transactions(block2, [spend_tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=True) - sync_blocks(self.nodes) - - - def test_signature_version_1(self): - self.log.info("Testing segwit signature hash version 1") - key = CECKey() - key.set_secretbytes(b"9") - pubkey = CPubKey(key.get_pubkey()) - - witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - # First create a witness output for use in the tests. - assert(len(self.utxo)) - 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, scriptPubKey)) - tx.rehash() - - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True) - # Mine this transaction in preparation for following tests. - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - sync_blocks(self.nodes) - 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, scriptPubKey)) - tx.wit.vtxinwit.append(CTxInWitness()) - # Too-large input value - sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue+1, key) - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Too-small input value - sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue-1, key) - block.vtx.pop() # remove last tx - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Now try correct value - sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key) - block.vtx.pop() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - 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 - # output to a random number of outputs. Repeat NUM_TESTS times. - # Ensure that we've tested a situation where we use SIGHASH_SINGLE with - # an input index > number of outputs. - NUM_TESTS = 500 - temp_utxos = [] - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) - split_value = prev_utxo.nValue // NUM_TESTS - for i in range(NUM_TESTS): - tx.vout.append(CTxOut(split_value, scriptPubKey)) - tx.wit.vtxinwit.append(CTxInWitness()) - sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, prev_utxo.nValue, key) - for i in range(NUM_TESTS): - temp_utxos.append(UTXO(tx.sha256, i, split_value)) - - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - block = self.build_next_block() - used_sighash_single_out_of_bounds = False - for i in range(NUM_TESTS): - # Ping regularly to keep the connection alive - if (not i % 100): - self.test_node.sync_with_ping() - # 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) - assert(len(temp_utxos) > num_inputs) - 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"")) - tx.wit.vtxinwit.append(CTxInWitness()) - total_value += temp_utxos[i].nValue - split_value = total_value // num_outputs - for i in range(num_outputs): - tx.vout.append(CTxOut(split_value, scriptPubKey)) - 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 - sign_P2PK_witness_input(witness_program, tx, i, hashtype, temp_utxos[i].nValue, key) - 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 - if (get_virtual_size(block) > MAX_BLOCK_BASE_SIZE - 1000): - self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - block = self.build_next_block() - - if (not used_sighash_single_out_of_bounds): - self.log.info("WARNING: this test run didn't attempt SIGHASH_SINGLE with out-of-bounds index value") - # Test the transactions we've added to the block - if (len(block.vtx) > 1): - self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Now test witness version 0 P2PKH transactions - pubkeyhash = hash160(pubkey) - scriptPKH = CScript([OP_0, pubkeyhash]) - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b"")) - tx.vout.append(CTxOut(temp_utxos[0].nValue, scriptPKH)) - tx.wit.vtxinwit.append(CTxInWitness()) - sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, temp_utxos[0].nValue, key) - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) - - script = GetP2PKHScript(pubkeyhash) - sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) - signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL - - # 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]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - - # Move the signature to the witness. - block.vtx.pop() - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [signature, pubkey] - tx2.vin[0].scriptSig = b"" - tx2.rehash() - - self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - temp_utxos.pop(0) - - # 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 - - 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()) - sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_ALL|SIGHASH_ANYONECANPAY, i.nValue, key) - index += 1 - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - for i in range(len(tx.vout)): - self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue)) - - - # Test P2SH wrapped witness programs. - def test_p2sh_witness(self, segwit_activated): - self.log.info("Testing P2SH witness transactions") - - assert(len(self.utxo)) - - # Prepare the p2sh-wrapped witness output - witness_program = CScript([OP_DROP, OP_TRUE]) - witness_hash = sha256(witness_program) - p2wsh_pubkey = CScript([OP_0, witness_hash]) - p2sh_witness_hash = hash160(p2wsh_pubkey) - scriptPubKey = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) - scriptSig = 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, scriptPubKey)) - tx.rehash() - - # Verify mempool acceptance and block validity - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True, with_witness=segwit_activated) - sync_blocks(self.nodes) - - # Now test attempts to spend the output. - spend_tx = CTransaction() - spend_tx.vin.append(CTxIn(COutPoint(tx.sha256, 0), scriptSig)) - 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. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False) - - # Try to put the witness script in the scriptSig, should also fail. - spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a']) - spend_tx.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False) - - # Now put the witness script in the witness, should succeed after - # segwit activates. - spend_tx.vin[0].scriptSig = scriptSig - spend_tx.rehash() - spend_tx.wit.vtxinwit.append(CTxInWitness()) - spend_tx.wit.vtxinwit[0].scriptWitness.stack = [ b'a', witness_program ] - - # Verify mempool acceptance - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=True, accepted=segwit_activated) - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [spend_tx]) - - # If we're before activation, then sending this without witnesses - # should be valid. If we're after activation, then sending this with - # witnesses should be valid. - if segwit_activated: - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - else: - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True, with_witness=False) - - # Update self.utxo - self.utxo.pop(0) - self.utxo.append(UTXO(spend_tx.sha256, 0, spend_tx.vout[0].nValue)) - - # Test the behavior of starting up a segwit-aware node after the softfork - # has activated. As segwit requires different block data than pre-segwit - # nodes would have stored, this requires special handling. - # To enable this test, pass --oldbinary=<path-to-pre-segwit-bitcoind> to - # the test. - def test_upgrade_after_activation(self, node_id): - self.log.info("Testing software upgrade after softfork activation") - - assert(node_id != 0) # node0 is assumed to be a segwit-active bitcoind - - # Make sure the nodes are all up - sync_blocks(self.nodes) - - # Restart with the new binary - self.stop_node(node_id) - self.start_node(node_id, extra_args=["-vbparams=segwit:0:999999999999"]) - connect_nodes(self.nodes[0], node_id) - - sync_blocks(self.nodes) - - # Make sure that this peer thinks segwit has activated. - assert(get_bip9_status(self.nodes[node_id], 'segwit')['status'] == "active") - - # Make sure this peers blocks match those of node0. - height = self.nodes[node_id].getblockcount() - while height >= 0: - block_hash = self.nodes[node_id].getblockhash(height) - assert_equal(block_hash, self.nodes[0].getblockhash(height)) - assert_equal(self.nodes[0].getblock(block_hash), self.nodes[node_id].getblock(block_hash)) - height -= 1 - - - def test_witness_sigops(self): - '''Ensure sigop counting is correct inside witnesses.''' - self.log.info("Testing sigops limit") - - assert(len(self.utxo)) - - # Keep this under MAX_OPS_PER_SCRIPT (201) - witness_program = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKMULTISIG]*5 + [OP_CHECKSIG]*193 + [OP_ENDIF]) - witness_hash = sha256(witness_program) - scriptPubKey = CScript([OP_0, witness_hash]) - - 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 - - # We chose the number of checkmultisigs/checksigs to make this work: - assert(extra_sigops_available < 100) # steer clear of MAX_OPS_PER_SCRIPT - - # 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. - witness_program_toomany = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG]*(extra_sigops_available + 1) + [OP_ENDIF]) - witness_hash_toomany = sha256(witness_program_toomany) - scriptPubKey_toomany = CScript([OP_0, witness_hash_toomany]) - - # If we spend this script instead, we would exactly reach our sigop - # limit (for witness sigops). - witness_program_justright = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG]*(extra_sigops_available) + [OP_ENDIF]) - witness_hash_justright = sha256(witness_program_justright) - scriptPubKey_justright = CScript([OP_0, witness_hash_justright]) - - # 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"")) - for i in range(outputs): - tx.vout.append(CTxOut(split_value, scriptPubKey)) - tx.vout[-2].scriptPubKey = scriptPubKey_toomany - tx.vout[-1].scriptPubKey = scriptPubKey_justright - tx.rehash() - - block_1 = self.build_next_block() - self.update_witness_block_with_transactions(block_1, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_1, accepted=True) - - 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()) - tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program ] - total_value += tx.vout[i].nValue - tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_toomany ] - 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]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=False) - - # 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 - scriptPubKey_checksigs = CScript([OP_CHECKSIG]*checksig_count) - tx2.vout.append(CTxOut(0, scriptPubKey_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]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False) - - # 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]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_4, accepted=True) - - # Reset the tip back down for the next test - sync_blocks(self.nodes) - 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()) - tx2.wit.vtxinwit[-1].scriptWitness.stack = [ witness_program_justright ] - tx2.rehash() - self.update_witness_block_with_transactions(block_5, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_5, accepted=True) - - # TODO: test p2sh sigop counting - - def test_getblocktemplate_before_lockin(self): - self.log.info("Testing getblocktemplate setting of segwit versionbit (before lockin)") - # Node0 is segwit aware, node2 is not. - for node in [self.nodes[0], self.nodes[2]]: - gbt_results = node.getblocktemplate() - block_version = gbt_results['version'] - # If we're not indicating segwit support, we will still be - # signalling for segwit activation. - assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0]) - # If we don't specify the segwit rule, then we won't get a default - # commitment. - assert('default_witness_commitment' not in gbt_results) - - # Workaround: - # Can either change the tip, or change the mempool and wait 5 seconds - # to trigger a recomputation of getblocktemplate. - txid = int(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1), 16) - # Using mocktime lets us avoid sleep() - sync_mempools(self.nodes) - self.nodes[0].setmocktime(int(time.time())+10) - self.nodes[2].setmocktime(int(time.time())+10) - - for node in [self.nodes[0], self.nodes[2]]: - gbt_results = node.getblocktemplate({"rules" : ["segwit"]}) - block_version = gbt_results['version'] - if node == self.nodes[2]: - # If this is a non-segwit node, we should still not get a witness - # commitment, nor a version bit signalling segwit. - assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) - assert('default_witness_commitment' not in gbt_results) - else: - # For segwit-aware nodes, check the version bit and the witness - # commitment are correct. - assert(block_version & (1 << VB_WITNESS_BIT) != 0) - assert('default_witness_commitment' in gbt_results) - witness_commitment = gbt_results['default_witness_commitment'] - - # Check that default_witness_commitment is present. - witness_root = CBlock.get_merkle_root([ser_uint256(0), - ser_uint256(txid)]) - script = get_witness_script(witness_root, 0) - assert_equal(witness_commitment, bytes_to_hex_str(script)) - - # undo mocktime - self.nodes[0].setmocktime(0) - self.nodes[2].setmocktime(0) - - # Uncompressed pubkeys are no longer supported in default relay policy, - # but (for now) are still valid in blocks. - def test_uncompressed_pubkey(self): - self.log.info("Testing uncompressed pubkeys") - # Segwit transactions using uncompressed pubkeys are not accepted - # under default policy, but should still pass consensus. - key = CECKey() - key.set_secretbytes(b"9") - key.set_compressed(False) - pubkey = CPubKey(key.get_pubkey()) - assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey - - assert(len(self.utxo) > 0) - utxo = self.utxo.pop(0) - - # Test 1: P2WPKH - # First create a P2WPKH output that uses an uncompressed pubkey - pubkeyhash = hash160(pubkey) - scriptPKH = CScript([OP_0, pubkeyhash]) - tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b"")) - tx.vout.append(CTxOut(utxo.nValue-1000, scriptPKH)) - tx.rehash() - - # Confirm it in a block. - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # Now try to spend it. Send it to a P2WSH output, which we'll - # use in the next test. - witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) - witness_hash = sha256(witness_program) - scriptWSH = CScript([OP_0, witness_hash]) - - tx2 = CTransaction() - tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) - tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptWSH)) - script = GetP2PKHScript(pubkeyhash) - sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) - signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL - tx2.wit.vtxinwit.append(CTxInWitness()) - tx2.wit.vtxinwit[0].scriptWitness.stack = [ signature, pubkey ] - tx2.rehash() - - # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') - # But passes consensus. - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # 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. - p2sh_witness_hash = hash160(scriptWSH) - scriptP2SH = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) - scriptSig = CScript([scriptWSH]) - - tx3 = CTransaction() - tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) - tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptP2SH)) - tx3.wit.vtxinwit.append(CTxInWitness()) - sign_P2PK_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) - - # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') - # But passes consensus. - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx3]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # 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. - scriptPubKey = GetP2PKHScript(pubkeyhash) - tx4 = CTransaction() - tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), scriptSig)) - tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, scriptPubKey)) - tx4.wit.vtxinwit.append(CTxInWitness()) - sign_P2PK_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) - - # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx4]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - - # 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]))) - (sig_hash, err) = SignatureHash(scriptPubKey, tx5, 0, SIGHASH_ALL) - signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL - tx5.vin[0].scriptSig = CScript([signature, pubkey]) - tx5.rehash() - # Should pass policy and consensus. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx5, True, True) - block = self.build_next_block() - self.update_witness_block_with_transactions(block, [tx5]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) - self.utxo.append(UTXO(tx5.sha256, 0, tx5.vout[0].nValue)) - - def test_non_standard_witness(self): - self.log.info("Testing detection of non-standard P2WSH witness") - 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 = [] - - assert(len(self.utxo)) - 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: - p2wsh = CScript([OP_0, sha256(i)]) - p2sh = hash160(p2wsh) - p2wsh_scripts.append(p2wsh) - tx.vout.append(CTxOut(outputvalue, p2wsh)) - tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL]))) - tx.rehash() - txid = tx.sha256 - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) - - self.nodes[0].generate(1) - sync_blocks(self.nodes) - - # Creating transactions for tests - p2wsh_txs = [] - p2sh_txs = [] - for i in range(len(scripts)): - p2wsh_tx = CTransaction() - p2wsh_tx.vin.append(CTxIn(COutPoint(txid,i*2))) - p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) - p2wsh_tx.wit.vtxinwit.append(CTxInWitness()) - p2wsh_tx.rehash() - p2wsh_txs.append(p2wsh_tx) - p2sh_tx = CTransaction() - p2sh_tx.vin.append(CTxIn(COutPoint(txid,i*2+1), CScript([p2wsh_scripts[i]]))) - p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) - 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]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[0], True, False, b'bad-witness-nonstandard') - # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[0], True, True) - - # Stack element size over 80 bytes is non-standard - p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, False, b'bad-witness-nonstandard') - # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[1], True, True) - # 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]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, True) - - # witnessScript size at 3600 bytes is standard - p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[2], True, True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[2], True, True) - - # witnessScript size at 3601 bytes is non-standard - p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[3], True, False, b'bad-witness-nonstandard') - # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[3], True, True) - - # Repeating the same tests with P2SH-P2WSH - p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[0], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[0], True, True) - p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[1], True, True) - p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, True) - p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[2], True, True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[2], True, True) - p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[3], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[3], True, True) - - self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node - # Valid but non-standard transactions in a block should be accepted by standard node - sync_blocks(self.nodes) - assert_equal(len(self.nodes[0].getrawmempool()), 0) - assert_equal(len(self.nodes[1].getrawmempool()), 0) - - self.utxo.pop(0) - - - def run_test(self): - # Setup the p2p connections and start up the network thread. - # self.test_node sets NODE_WITNESS|NODE_NETWORK - self.test_node = self.nodes[0].add_p2p_connection(TestNode(), services=NODE_NETWORK|NODE_WITNESS) - # self.old_node sets only NODE_NETWORK - self.old_node = self.nodes[0].add_p2p_connection(TestNode(), services=NODE_NETWORK) - # self.std_node is for testing node1 (fRequireStandard=true) - self.std_node = self.nodes[1].add_p2p_connection(TestNode(), services=NODE_NETWORK|NODE_WITNESS) - - network_thread_start() - - # Keep a place to store utxo's that can be used in later tests - self.utxo = [] - - # Test logic begins here - self.test_node.wait_for_verack() - - self.log.info("Starting tests before segwit lock in:") - - self.test_witness_services() # Verifies NODE_WITNESS - self.test_non_witness_transaction() # non-witness tx's are accepted - self.test_unnecessary_witness_before_segwit_activation() - self.test_block_relay(segwit_activated=False) - - # Advance to segwit being 'started' - self.advance_to_segwit_started() - sync_blocks(self.nodes) - self.test_getblocktemplate_before_lockin() - - sync_blocks(self.nodes) - - # At lockin, nothing should change. - self.log.info("Testing behavior post lockin, pre-activation") - self.advance_to_segwit_lockin() - - # Retest unnecessary witnesses - self.test_unnecessary_witness_before_segwit_activation() - self.test_witness_tx_relay_before_segwit_activation() - self.test_block_relay(segwit_activated=False) - self.test_p2sh_witness(segwit_activated=False) - self.test_standardness_v0(segwit_activated=False) - - sync_blocks(self.nodes) - - # Now activate segwit - self.log.info("Testing behavior after segwit activation") - self.advance_to_segwit_active() - - sync_blocks(self.nodes) - - # Test P2SH witness handling again - self.test_p2sh_witness(segwit_activated=True) - 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() - self.test_max_witness_program_length() - self.test_witness_input_length() - self.test_block_relay(segwit_activated=True) - self.test_tx_relay_after_segwit_activation() - self.test_standardness_v0(segwit_activated=True) - self.test_segwit_versions() - self.test_premature_coinbase_witness_spend() - self.test_uncompressed_pubkey() - self.test_signature_version_1() - self.test_non_standard_witness() - sync_blocks(self.nodes) - self.test_upgrade_after_activation(node_id=2) - self.test_witness_sigops() - - -if __name__ == '__main__': - SegWitTest().main() |