[tests] p2p_segwit: Fix flake8 warnings.

This commit is contained in:
John Newbery 2018-06-13 11:56:20 -04:00
parent a6ed99a1e6
commit f7c7f8ecf3
1 changed files with 283 additions and 235 deletions

View File

@ -3,17 +3,84 @@
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test segwit transactions and blocks on P2P network.""" """Test segwit transactions and blocks on P2P network."""
from binascii import hexlify
import math
import random
import struct
import time
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.blocktools import create_block, create_coinbase, add_witness_commitment, get_witness_script, WITNESS_COMMITMENT_HEADER
from test_framework.key import CECKey, CPubKey from test_framework.key import CECKey, CPubKey
import math from test_framework.messages import (
import time BIP125_SEQUENCE_NUMBER,
import random CBlock,
from binascii import hexlify CBlockHeader,
CInv,
COutPoint,
CTransaction,
CTxIn,
CTxInWitness,
CTxOut,
CTxWitness,
MAX_BLOCK_BASE_SIZE,
MSG_WITNESS_FLAG,
NODE_NETWORK,
NODE_WITNESS,
msg_block,
msg_getdata,
msg_headers,
msg_inv,
msg_tx,
msg_witness_block,
msg_witness_tx,
ser_uint256,
ser_vector,
sha256,
uint256_from_str,
)
from test_framework.mininode import (
P2PInterface,
mininode_lock,
network_thread_start,
)
from test_framework.script import (
CScript,
CScriptNum,
CScriptOp,
OP_0,
OP_1,
OP_16,
OP_2DROP,
OP_CHECKMULTISIG,
OP_CHECKSIG,
OP_DROP,
OP_DUP,
OP_ELSE,
OP_ENDIF,
OP_EQUAL,
OP_EQUALVERIFY,
OP_HASH160,
OP_IF,
OP_RETURN,
OP_TRUE,
SIGHASH_ALL,
SIGHASH_ANYONECANPAY,
SIGHASH_NONE,
SIGHASH_SINGLE,
SegwitVersion1SignatureHash,
SignatureHash,
hash160,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
bytes_to_hex_str,
connect_nodes,
get_bip9_status,
hex_str_to_bytes,
sync_blocks,
sync_mempools,
)
# The versionbit bit used to signal activation of SegWit # The versionbit bit used to signal activation of SegWit
VB_WITNESS_BIT = 1 VB_WITNESS_BIT = 1
@ -43,7 +110,7 @@ def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=Non
p2p.send_message(tx_message) p2p.send_message(tx_message)
p2p.sync_with_ping() p2p.sync_with_ping()
assert_equal(tx.hash in rpc.getrawmempool(), accepted) assert_equal(tx.hash in rpc.getrawmempool(), accepted)
if (reason != None and not accepted): if (reason is not None and not accepted):
# Check the rejection reason as well. # Check the rejection reason as well.
with mininode_lock: with mininode_lock:
assert_equal(p2p.last_message["reject"].reason, reason) assert_equal(p2p.last_message["reject"].reason, reason)
@ -59,7 +126,7 @@ def test_witness_block(rpc, p2p, block, accepted, with_witness=True, reason=None
p2p.send_message(msg_block(block)) p2p.send_message(msg_block(block))
p2p.sync_with_ping() p2p.sync_with_ping()
assert_equal(rpc.getbestblockhash() == block.hash, accepted) assert_equal(rpc.getbestblockhash() == block.hash, accepted)
if (reason != None and not accepted): if (reason is not None and not accepted):
# Check the rejection reason as well. # Check the rejection reason as well.
with mininode_lock: with mininode_lock:
assert_equal(p2p.last_message["reject"].reason, reason) assert_equal(p2p.last_message["reject"].reason, reason)
@ -106,21 +173,21 @@ class TestP2PConn(P2PInterface):
# Used to keep track of anyone-can-spend outputs that we can use in the tests # Used to keep track of anyone-can-spend outputs that we can use in the tests
class UTXO(): class UTXO():
def __init__(self, sha256, n, nValue): def __init__(self, sha256, n, value):
self.sha256 = sha256 self.sha256 = sha256
self.n = n self.n = n
self.nValue = nValue self.nValue = value
# Helper for getting the script associated with a P2PKH # Helper for getting the script associated with a P2PKH
def GetP2PKHScript(pubkeyhash): def get_p2pkh_script(pubkeyhash):
return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)])
# Add signature for a P2PK witness program. # Add signature for a P2PK witness program.
def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key):
tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) tx_hash = SegwitVersion1SignatureHash(script, tx_to, in_idx, hashtype, value)
signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1')
txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] tx_to.wit.vtxinwit[in_idx].scriptWitness.stack = [signature, script]
txTo.rehash() tx_to.rehash()
class SegWitTest(BitcoinTestFramework): class SegWitTest(BitcoinTestFramework):
@ -138,12 +205,12 @@ class SegWitTest(BitcoinTestFramework):
''' Helpers ''' ''' Helpers '''
# Build a block on top of node0's tip. # Build a block on top of node0's tip.
def build_next_block(self, nVersion=4): def build_next_block(self, version=4):
tip = self.nodes[0].getbestblockhash() tip = self.nodes[0].getbestblockhash()
height = self.nodes[0].getblockcount() + 1 height = self.nodes[0].getblockcount() + 1
block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1 block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1
block = create_block(int(tip, 16), create_coinbase(height), block_time) block = create_block(int(tip, 16), create_coinbase(height), block_time)
block.nVersion = nVersion block.version = version
block.rehash() block.rehash()
return block return block
@ -159,14 +226,13 @@ class SegWitTest(BitcoinTestFramework):
self.log.info("Verifying NODE_WITNESS service bit") self.log.info("Verifying NODE_WITNESS service bit")
assert((self.test_node.nServices & NODE_WITNESS) != 0) assert((self.test_node.nServices & NODE_WITNESS) != 0)
# See if sending a regular transaction works, and create a utxo # See if sending a regular transaction works, and create a utxo
# to use in later tests. # to use in later tests.
def test_non_witness_transaction(self): def test_non_witness_transaction(self):
# Mine a block with an anyone-can-spend coinbase, # Mine a block with an anyone-can-spend coinbase,
# let it mature, then try to spend it. # let it mature, then try to spend it.
self.log.info("Testing non-witness transaction") self.log.info("Testing non-witness transaction")
block = self.build_next_block(nVersion=1) block = self.build_next_block(version=1)
block.solve() block.solve()
self.test_node.send_message(msg_block(block)) self.test_node.send_message(msg_block(block))
self.test_node.sync_with_ping() # make sure the block was processed self.test_node.sync_with_ping() # make sure the block was processed
@ -191,7 +257,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.append(UTXO(tx.sha256, 0, 49 * 100000000)) self.utxo.append(UTXO(tx.sha256, 0, 49 * 100000000))
self.nodes[0].generate(1) self.nodes[0].generate(1)
# Verify that blocks with witnesses are rejected before activation. # Verify that blocks with witnesses are rejected before activation.
def test_unnecessary_witness_before_segwit_activation(self): def test_unnecessary_witness_before_segwit_activation(self):
self.log.info("Testing behavior of unnecessary witnesses") self.log.info("Testing behavior of unnecessary witnesses")
@ -212,7 +277,7 @@ class SegWitTest(BitcoinTestFramework):
assert(tx.sha256 != tx.calc_sha256(with_witness=True)) assert(tx.sha256 != tx.calc_sha256(with_witness=True))
# Construct a segwit-signaling block that includes the transaction. # Construct a segwit-signaling block that includes the transaction.
block = self.build_next_block(nVersion=(VB_TOP_BITS|(1 << VB_WITNESS_BIT))) block = self.build_next_block(version=(VB_TOP_BITS | (1 << VB_WITNESS_BIT)))
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
# Sending witness data before activation is not allowed (anti-spam # Sending witness data before activation is not allowed (anti-spam
# rule). # rule).
@ -249,16 +314,16 @@ class SegWitTest(BitcoinTestFramework):
# Create two outputs, a p2wsh and p2sh-p2wsh # Create two outputs, a p2wsh and p2sh-p2wsh
witness_program = CScript([OP_TRUE]) witness_program = CScript([OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
p2sh_pubkey = hash160(scriptPubKey) p2sh_pubkey = hash160(script_pubkey)
p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) p2sh_script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
value = self.utxo[0].nValue // 3 value = self.utxo[0].nValue // 3
tx = CTransaction() tx = CTransaction()
tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b'')] tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b'')]
tx.vout = [CTxOut(value, scriptPubKey), CTxOut(value, p2sh_scriptPubKey)] tx.vout = [CTxOut(value, script_pubkey), CTxOut(value, p2sh_script_pubkey)]
tx.vout.append(CTxOut(value, CScript([OP_TRUE]))) tx.vout.append(CTxOut(value, CScript([OP_TRUE])))
tx.rehash() tx.rehash()
txid = tx.sha256 txid = tx.sha256
@ -281,7 +346,7 @@ class SegWitTest(BitcoinTestFramework):
p2wsh_tx.rehash() p2wsh_tx.rehash()
p2sh_p2wsh_tx = CTransaction() p2sh_p2wsh_tx = CTransaction()
p2sh_p2wsh_tx.vin = [CTxIn(COutPoint(txid, 1), CScript([scriptPubKey]))] p2sh_p2wsh_tx.vin = [CTxIn(COutPoint(txid, 1), CScript([script_pubkey]))]
p2sh_p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))] p2sh_p2wsh_tx.vout = [CTxOut(value, CScript([OP_TRUE]))]
p2sh_p2wsh_tx.wit.vtxinwit.append(CTxInWitness()) p2sh_p2wsh_tx.wit.vtxinwit.append(CTxInWitness())
p2sh_p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])] p2sh_p2wsh_tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
@ -334,7 +399,6 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[0].generate(1) self.nodes[0].generate(1)
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in') assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in')
# Mine enough blocks to activate segwit. # Mine enough blocks to activate segwit.
# TODO: we could verify that activation only happens at the right threshold # TODO: we could verify that activation only happens at the right threshold
# of signalling blocks, rather than just at the right period boundary. # of signalling blocks, rather than just at the right period boundary.
@ -346,7 +410,6 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[0].generate(1) self.nodes[0].generate(1)
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active') assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active')
# This test can only be run after segwit has activated # This test can only be run after segwit has activated
def test_witness_commitments(self): def test_witness_commitments(self):
self.log.info("Testing witness commitments") self.log.info("Testing witness commitments")
@ -381,8 +444,8 @@ class SegWitTest(BitcoinTestFramework):
# Let's construct a witness program # Let's construct a witness program
witness_program = CScript([OP_TRUE]) witness_program = CScript([OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
tx.vout.append(CTxOut(self.utxo[0].nValue-1000, scriptPubKey)) tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash() tx.rehash()
# tx2 will spend tx1, and send back to a regular anyone-can-spend address # tx2 will spend tx1, and send back to a regular anyone-can-spend address
@ -436,7 +499,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop(0) self.utxo.pop(0)
self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue))
def test_block_malleability(self): def test_block_malleability(self):
self.log.info("Testing witness block malleability") self.log.info("Testing witness block malleability")
@ -477,7 +539,6 @@ class SegWitTest(BitcoinTestFramework):
block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)] block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)]
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
def test_witness_block_size(self): def test_witness_block_size(self):
self.log.info("Testing witness block size limit") self.log.info("Testing witness block size limit")
# TODO: Test that non-witness carrying blocks can't exceed 1MB # TODO: Test that non-witness carrying blocks can't exceed 1MB
@ -497,7 +558,7 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([OP_2DROP] * NUM_DROPS + [OP_TRUE]) witness_program = CScript([OP_2DROP] * NUM_DROPS + [OP_TRUE])
witness_hash = uint256_from_str(sha256(witness_program)) witness_hash = uint256_from_str(sha256(witness_program))
scriptPubKey = CScript([OP_0, ser_uint256(witness_hash)]) script_pubkey = CScript([OP_0, ser_uint256(witness_hash)])
prevout = COutPoint(self.utxo[0].sha256, self.utxo[0].n) prevout = COutPoint(self.utxo[0].sha256, self.utxo[0].n)
value = self.utxo[0].nValue value = self.utxo[0].nValue
@ -506,7 +567,7 @@ class SegWitTest(BitcoinTestFramework):
parent_tx.vin.append(CTxIn(prevout, b"")) parent_tx.vin.append(CTxIn(prevout, b""))
child_value = int(value / NUM_OUTPUTS) child_value = int(value / NUM_OUTPUTS)
for i in range(NUM_OUTPUTS): for i in range(NUM_OUTPUTS):
parent_tx.vout.append(CTxOut(child_value, scriptPubKey)) parent_tx.vout.append(CTxOut(child_value, script_pubkey))
parent_tx.vout[0].nValue -= 50000 parent_tx.vout[0].nValue -= 50000
assert(parent_tx.vout[0].nValue > 0) assert(parent_tx.vout[0].nValue > 0)
parent_tx.rehash() parent_tx.rehash()
@ -556,7 +617,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop(0) self.utxo.pop(0)
self.utxo.append(UTXO(block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue)) 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 # submitblock will try to add the nonce automatically, so that mining
# software doesn't need to worry about doing so itself. # software doesn't need to worry about doing so itself.
def test_submit_block(self): def test_submit_block(self):
@ -593,7 +653,6 @@ class SegWitTest(BitcoinTestFramework):
# Tip should not advance! # Tip should not advance!
assert(self.nodes[0].getbestblockhash() != block_2.hash) assert(self.nodes[0].getbestblockhash() != block_2.hash)
# Consensus tests of extra witness data in a transaction. # Consensus tests of extra witness data in a transaction.
def test_extra_witness_data(self): def test_extra_witness_data(self):
self.log.info("Testing extra witness data in tx") self.log.info("Testing extra witness data in tx")
@ -604,12 +663,12 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([OP_DROP, OP_TRUE]) witness_program = CScript([OP_DROP, OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
# First try extra witness data on a tx that doesn't require a witness # First try extra witness data on a tx that doesn't require a witness
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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(self.utxo[0].nValue - 2000, script_pubkey))
tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output tx.vout.append(CTxOut(1000, CScript([OP_TRUE]))) # non-witness output
tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit.append(CTxInWitness())
tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])] tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([])]
@ -669,7 +728,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop(0) self.utxo.pop(0)
self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
def test_max_witness_push_length(self): def test_max_witness_push_length(self):
''' Should only allow up to 520 byte pushes in witness stack ''' ''' Should only allow up to 520 byte pushes in witness stack '''
self.log.info("Testing maximum witness push size") self.log.info("Testing maximum witness push size")
@ -680,11 +738,11 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([OP_DROP, OP_TRUE]) witness_program = CScript([OP_DROP, OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash() tx.rehash()
tx2 = CTransaction() tx2 = CTransaction()
@ -720,13 +778,13 @@ class SegWitTest(BitcoinTestFramework):
long_witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 63 + [OP_TRUE]) long_witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 63 + [OP_TRUE])
assert(len(long_witness_program) == MAX_PROGRAM_LENGTH + 1) assert(len(long_witness_program) == MAX_PROGRAM_LENGTH + 1)
long_witness_hash = sha256(long_witness_program) long_witness_hash = sha256(long_witness_program)
long_scriptPubKey = CScript([OP_0, long_witness_hash]) long_script_pubkey = CScript([OP_0, long_witness_hash])
block = self.build_next_block() block = self.build_next_block()
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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.vout.append(CTxOut(self.utxo[0].nValue - 1000, long_script_pubkey))
tx.rehash() tx.rehash()
tx2 = CTransaction() tx2 = CTransaction()
@ -744,9 +802,9 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 62 + [OP_TRUE]) witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 62 + [OP_TRUE])
assert(len(witness_program) == MAX_PROGRAM_LENGTH) assert(len(witness_program) == MAX_PROGRAM_LENGTH)
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
tx.vout[0] = CTxOut(tx.vout[0].nValue, scriptPubKey) tx.vout[0] = CTxOut(tx.vout[0].nValue, script_pubkey)
tx.rehash() tx.rehash()
tx2.vin[0].prevout.hash = tx.sha256 tx2.vin[0].prevout.hash = tx.sha256
tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a'] * 43 + [witness_program] tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a'] * 43 + [witness_program]
@ -758,7 +816,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop() self.utxo.pop()
self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
def test_witness_input_length(self): def test_witness_input_length(self):
''' Ensure that vin length must match vtxinwit length ''' ''' Ensure that vin length must match vtxinwit length '''
self.log.info("Testing witness input length") self.log.info("Testing witness input length")
@ -766,14 +823,14 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([OP_DROP, OP_TRUE]) witness_program = CScript([OP_DROP, OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
# Create a transaction that splits our utxo into many outputs # Create a transaction that splits our utxo into many outputs
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
nValue = self.utxo[0].nValue value = self.utxo[0].nValue
for i in range(10): for i in range(10):
tx.vout.append(CTxOut(int(nValue/10), scriptPubKey)) tx.vout.append(CTxOut(int(value / 10), script_pubkey))
tx.vout[0].nValue -= 1000 tx.vout[0].nValue -= 1000
assert(tx.vout[0].nValue >= 0) assert(tx.vout[0].nValue >= 0)
@ -805,7 +862,7 @@ class SegWitTest(BitcoinTestFramework):
tx2 = BrokenCTransaction() tx2 = BrokenCTransaction()
for i in range(10): for i in range(10):
tx2.vin.append(CTxIn(COutPoint(tx.sha256, i), b"")) tx2.vin.append(CTxIn(COutPoint(tx.sha256, i), b""))
tx2.vout.append(CTxOut(nValue-3000, CScript([OP_TRUE]))) tx2.vout.append(CTxOut(value - 3000, CScript([OP_TRUE])))
# First try using a too long vtxinwit # First try using a too long vtxinwit
for i in range(11): for i in range(11):
@ -842,7 +899,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop() self.utxo.pop()
self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue))
def test_witness_tx_relay_before_segwit_activation(self): def test_witness_tx_relay_before_segwit_activation(self):
self.log.info("Testing relay of witness transactions") self.log.info("Testing relay of witness transactions")
# Generate a transaction that doesn't require a witness, but send it # Generate a transaction that doesn't require a witness, but send it
@ -885,7 +941,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop(0) self.utxo.pop(0)
self.utxo.append(UTXO(tx_hash, 0, tx_value)) self.utxo.append(UTXO(tx_hash, 0, tx_value))
# After segwit activates, verify that mempool: # After segwit activates, verify that mempool:
# - rejects transactions with unnecessary/extra witnesses # - rejects transactions with unnecessary/extra witnesses
# - accepts transactions with valid witnesses # - accepts transactions with valid witnesses
@ -917,10 +972,10 @@ class SegWitTest(BitcoinTestFramework):
# Now try to add extra witness data to a valid witness tx. # Now try to add extra witness data to a valid witness tx.
witness_program = CScript([OP_TRUE]) witness_program = CScript([OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx_hash, 0), b"")) tx2.vin.append(CTxIn(COutPoint(tx_hash, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptPubKey)) tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_pubkey))
tx2.rehash() tx2.rehash()
tx3 = CTransaction() tx3 = CTransaction()
@ -977,7 +1032,6 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.pop(0) self.utxo.pop(0)
self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue))
# Test that block requests to NODE_WITNESS peer are with MSG_WITNESS_FLAG # Test that block requests to NODE_WITNESS peer are with MSG_WITNESS_FLAG
# This is true regardless of segwit activation. # This is true regardless of segwit activation.
# Also test that we don't ask for blocks from unupgraded peers # Also test that we don't ask for blocks from unupgraded peers
@ -997,14 +1051,14 @@ class SegWitTest(BitcoinTestFramework):
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
test_witness_block(self.nodes[0].rpc, self.test_node, block1, True) test_witness_block(self.nodes[0].rpc, self.test_node, block1, True)
block2 = self.build_next_block(nVersion=4) block2 = self.build_next_block(version=4)
block2.solve() block2.solve()
self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True) self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True)
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
test_witness_block(self.nodes[0].rpc, self.test_node, block2, True) test_witness_block(self.nodes[0].rpc, self.test_node, block2, True)
block3 = self.build_next_block(nVersion=(VB_TOP_BITS | (1<<15))) block3 = self.build_next_block(version=(VB_TOP_BITS | (1 << 15)))
block3.solve() block3.solve()
self.test_node.announce_block_and_wait_for_getdata(block3, use_header=True) self.test_node.announce_block_and_wait_for_getdata(block3, use_header=True)
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
@ -1012,7 +1066,7 @@ class SegWitTest(BitcoinTestFramework):
# Check that we can getdata for witness blocks or regular blocks, # Check that we can getdata for witness blocks or regular blocks,
# and the right thing happens. # and the right thing happens.
if segwit_activated == False: if not segwit_activated:
# Before activation, we should be able to request old blocks with # Before activation, we should be able to request old blocks with
# or without witness, and they should be the same. # or without witness, and they should be the same.
chain_height = self.nodes[0].getblockcount() chain_height = self.nodes[0].getblockcount()
@ -1055,7 +1109,7 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(rpc_details["weight"], weight) assert_equal(rpc_details["weight"], weight)
# Upgraded node should not ask for blocks from unupgraded # Upgraded node should not ask for blocks from unupgraded
block4 = self.build_next_block(nVersion=4) block4 = self.build_next_block(version=4)
block4.solve() block4.solve()
self.old_node.getdataset = set() self.old_node.getdataset = set()
@ -1080,15 +1134,15 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([OP_TRUE]) witness_program = CScript([OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
p2sh_pubkey = hash160(witness_program) p2sh_pubkey = hash160(witness_program)
p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) p2sh_script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
# First prepare a p2sh output (so that spending it will pass standardness) # First prepare a p2sh output (so that spending it will pass standardness)
p2sh_tx = CTransaction() p2sh_tx = CTransaction()
p2sh_tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] 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.vout = [CTxOut(self.utxo[0].nValue - 1000, p2sh_script_pubkey)]
p2sh_tx.rehash() p2sh_tx.rehash()
# Mine it on test_node to create the confirmed output. # Mine it on test_node to create the confirmed output.
@ -1100,8 +1154,8 @@ class SegWitTest(BitcoinTestFramework):
# Start by creating a transaction with two outputs. # Start by creating a transaction with two outputs.
tx = CTransaction() tx = CTransaction()
tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))]
tx.vout = [CTxOut(p2sh_tx.vout[0].nValue-10000, scriptPubKey)] tx.vout = [CTxOut(p2sh_tx.vout[0].nValue - 10000, script_pubkey)]
tx.vout.append(CTxOut(8000, scriptPubKey)) # Might burn this later 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.vin[0].nSequence = BIP125_SEQUENCE_NUMBER # Just to have the option to bump this tx from the mempool
tx.rehash() tx.rehash()
@ -1110,11 +1164,11 @@ class SegWitTest(BitcoinTestFramework):
test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=True) test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=True)
# Now create something that looks like a P2PKH output. This won't be spendable. # Now create something that looks like a P2PKH output. This won't be spendable.
scriptPubKey = CScript([OP_0, hash160(witness_hash)]) script_pubkey = CScript([OP_0, hash160(witness_hash)])
tx2 = CTransaction() tx2 = CTransaction()
# tx was accepted, so we spend the second output. # tx was accepted, so we spend the second output.
tx2.vin = [CTxIn(COutPoint(tx.sha256, 1), b"")] tx2.vin = [CTxIn(COutPoint(tx.sha256, 1), b"")]
tx2.vout = [CTxOut(7000, scriptPubKey)] tx2.vout = [CTxOut(7000, script_pubkey)]
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program]
tx2.rehash() tx2.rehash()
@ -1149,25 +1203,24 @@ class SegWitTest(BitcoinTestFramework):
self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue))
assert_equal(len(self.nodes[1].getrawmempool()), 0) assert_equal(len(self.nodes[1].getrawmempool()), 0)
# Verify that future segwit upgraded transactions are non-standard, # Verify that future segwit upgraded transactions are non-standard,
# but valid in blocks. Can run this before and after segwit activation. # but valid in blocks. Can run this before and after segwit activation.
def test_segwit_versions(self): def test_segwit_versions(self):
self.log.info("Testing standardness/consensus for segwit versions (0-16)") self.log.info("Testing standardness/consensus for segwit versions (0-16)")
assert(len(self.utxo)) assert(len(self.utxo))
NUM_TESTS = 17 # will test OP_0, OP1, ..., OP_16 num_tests = 17 # will test OP_0, OP1, ..., OP_16
if (len(self.utxo) < NUM_TESTS): if (len(self.utxo) < num_tests):
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
split_value = (self.utxo[0].nValue - 4000) // NUM_TESTS split_value = (self.utxo[0].nValue - 4000) // num_tests
for i in range(NUM_TESTS): for i in range(num_tests):
tx.vout.append(CTxOut(split_value, CScript([OP_TRUE]))) tx.vout.append(CTxOut(split_value, CScript([OP_TRUE])))
tx.rehash() tx.rehash()
block = self.build_next_block() block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
self.utxo.pop(0) self.utxo.pop(0)
for i in range(NUM_TESTS): for i in range(num_tests):
self.utxo.append(UTXO(tx.sha256, i, split_value)) self.utxo.append(UTXO(tx.sha256, i, split_value))
sync_blocks(self.nodes) sync_blocks(self.nodes)
@ -1179,10 +1232,10 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(len(self.nodes[1].getrawmempool()), 0) assert_equal(len(self.nodes[1].getrawmempool()), 0)
for version in list(range(OP_1, OP_16 + 1)) + [OP_0]: for version in list(range(OP_1, OP_16 + 1)) + [OP_0]:
count += 1 count += 1
# First try to spend to a future version segwit scriptPubKey. # First try to spend to a future version segwit script_pubkey.
scriptPubKey = CScript([CScriptOp(version), witness_hash]) script_pubkey = CScript([CScriptOp(version), witness_hash])
tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")]
tx.vout = [CTxOut(self.utxo[0].nValue-1000, scriptPubKey)] tx.vout = [CTxOut(self.utxo[0].nValue - 1000, script_pubkey)]
tx.rehash() tx.rehash()
test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=False) 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) test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True)
@ -1195,10 +1248,10 @@ class SegWitTest(BitcoinTestFramework):
# Finally, verify that version 0 -> version 1 transactions # Finally, verify that version 0 -> version 1 transactions
# are non-standard # are non-standard
scriptPubKey = CScript([CScriptOp(OP_1), witness_hash]) script_pubkey = CScript([CScriptOp(OP_1), witness_hash])
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] tx2.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")]
tx2.vout = [CTxOut(tx.vout[0].nValue-1000, scriptPubKey)] tx2.vout = [CTxOut(tx.vout[0].nValue - 1000, script_pubkey)]
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program]
tx2.rehash() tx2.rehash()
@ -1235,15 +1288,14 @@ class SegWitTest(BitcoinTestFramework):
# Add utxo to our list # Add utxo to our list
self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue))
def test_premature_coinbase_witness_spend(self): def test_premature_coinbase_witness_spend(self):
self.log.info("Testing premature coinbase witness spend") self.log.info("Testing premature coinbase witness spend")
block = self.build_next_block() block = self.build_next_block()
# Change the output of the block to be a witness output. # Change the output of the block to be a witness output.
witness_program = CScript([OP_TRUE]) witness_program = CScript([OP_TRUE])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
block.vtx[0].vout[0].scriptPubKey = scriptPubKey block.vtx[0].vout[0].scriptPubKey = script_pubkey
# This next line will rehash the coinbase and update the merkle # This next line will rehash the coinbase and update the merkle
# root, and solve. # root, and solve.
self.update_witness_block_with_transactions(block, []) self.update_witness_block_with_transactions(block, [])
@ -1270,7 +1322,6 @@ class SegWitTest(BitcoinTestFramework):
test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=True) test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=True)
sync_blocks(self.nodes) sync_blocks(self.nodes)
def test_signature_version_1(self): def test_signature_version_1(self):
self.log.info("Testing segwit signature hash version 1") self.log.info("Testing segwit signature hash version 1")
key = CECKey() key = CECKey()
@ -1279,13 +1330,13 @@ class SegWitTest(BitcoinTestFramework):
witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
# First create a witness output for use in the tests. # First create a witness output for use in the tests.
assert(len(self.utxo)) assert(len(self.utxo))
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash() tx.rehash()
test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True) test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True)
@ -1304,21 +1355,21 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block() block = self.build_next_block()
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b""))
tx.vout.append(CTxOut(prev_utxo.nValue - 1000, scriptPubKey)) tx.vout.append(CTxOut(prev_utxo.nValue - 1000, script_pubkey))
tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit.append(CTxInWitness())
# Too-large input value # Too-large input value
sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue+1, key) sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue + 1, key)
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
# Too-small input value # Too-small input value
sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue-1, key) sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue - 1, key)
block.vtx.pop() # remove last tx block.vtx.pop() # remove last tx
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False)
# Now try correct value # Now try correct value
sign_P2PK_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key) sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key)
block.vtx.pop() block.vtx.pop()
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True)
@ -1328,19 +1379,19 @@ class SegWitTest(BitcoinTestFramework):
# Test combinations of signature hashes. # Test combinations of signature hashes.
# Split the utxo into a lot of outputs. # Split the utxo into a lot of outputs.
# Randomly choose up to 10 to spend, sign with different hashtypes, and # Randomly choose up to 10 to spend, sign with different hashtypes, and
# output to a random number of outputs. Repeat NUM_TESTS times. # output to a random number of outputs. Repeat num_tests times.
# Ensure that we've tested a situation where we use SIGHASH_SINGLE with # Ensure that we've tested a situation where we use SIGHASH_SINGLE with
# an input index > number of outputs. # an input index > number of outputs.
NUM_TESTS = 500 num_tests = 500
temp_utxos = [] temp_utxos = []
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b"")) tx.vin.append(CTxIn(COutPoint(prev_utxo.sha256, prev_utxo.n), b""))
split_value = prev_utxo.nValue // NUM_TESTS split_value = prev_utxo.nValue // num_tests
for i in range(NUM_TESTS): for i in range(num_tests):
tx.vout.append(CTxOut(split_value, scriptPubKey)) tx.vout.append(CTxOut(split_value, script_pubkey))
tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit.append(CTxInWitness())
sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, prev_utxo.nValue, key) sign_p2pk_witness_input(witness_program, tx, 0, SIGHASH_ALL, prev_utxo.nValue, key)
for i in range(NUM_TESTS): for i in range(num_tests):
temp_utxos.append(UTXO(tx.sha256, i, split_value)) temp_utxos.append(UTXO(tx.sha256, i, split_value))
block = self.build_next_block() block = self.build_next_block()
@ -1349,7 +1400,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block() block = self.build_next_block()
used_sighash_single_out_of_bounds = False used_sighash_single_out_of_bounds = False
for i in range(NUM_TESTS): for i in range(num_tests):
# Ping regularly to keep the connection alive # Ping regularly to keep the connection alive
if (not i % 100): if (not i % 100):
self.test_node.sync_with_ping() self.test_node.sync_with_ping()
@ -1367,14 +1418,14 @@ class SegWitTest(BitcoinTestFramework):
total_value += temp_utxos[i].nValue total_value += temp_utxos[i].nValue
split_value = total_value // num_outputs split_value = total_value // num_outputs
for i in range(num_outputs): for i in range(num_outputs):
tx.vout.append(CTxOut(split_value, scriptPubKey)) tx.vout.append(CTxOut(split_value, script_pubkey))
for i in range(num_inputs): for i in range(num_inputs):
# Now try to sign each input, using a random hashtype. # Now try to sign each input, using a random hashtype.
anyonecanpay = 0 anyonecanpay = 0
if random.randint(0, 1): if random.randint(0, 1):
anyonecanpay = SIGHASH_ANYONECANPAY anyonecanpay = SIGHASH_ANYONECANPAY
hashtype = random.randint(1, 3) | anyonecanpay hashtype = random.randint(1, 3) | anyonecanpay
sign_P2PK_witness_input(witness_program, tx, i, hashtype, temp_utxos[i].nValue, key) sign_p2pk_witness_input(witness_program, tx, i, hashtype, temp_utxos[i].nValue, key)
if (hashtype == SIGHASH_SINGLE and i >= num_outputs): if (hashtype == SIGHASH_SINGLE and i >= num_outputs):
used_sighash_single_out_of_bounds = True used_sighash_single_out_of_bounds = True
tx.rehash() tx.rehash()
@ -1399,17 +1450,17 @@ class SegWitTest(BitcoinTestFramework):
# Now test witness version 0 P2PKH transactions # Now test witness version 0 P2PKH transactions
pubkeyhash = hash160(pubkey) pubkeyhash = hash160(pubkey)
scriptPKH = CScript([OP_0, pubkeyhash]) script_pkh = CScript([OP_0, pubkeyhash])
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b"")) tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b""))
tx.vout.append(CTxOut(temp_utxos[0].nValue, scriptPKH)) tx.vout.append(CTxOut(temp_utxos[0].nValue, script_pkh))
tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit.append(CTxInWitness())
sign_P2PK_witness_input(witness_program, tx, 0, SIGHASH_ALL, temp_utxos[0].nValue, key) sign_p2pk_witness_input(witness_program, tx, 0, SIGHASH_ALL, temp_utxos[0].nValue, key)
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
script = GetP2PKHScript(pubkeyhash) script = get_p2pkh_script(pubkeyhash)
sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
@ -1444,7 +1495,7 @@ class SegWitTest(BitcoinTestFramework):
# the signatures as we go. # the signatures as we go.
tx.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) tx.vin.append(CTxIn(COutPoint(i.sha256, i.n), b""))
tx.wit.vtxinwit.append(CTxInWitness()) tx.wit.vtxinwit.append(CTxInWitness())
sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_ALL|SIGHASH_ANYONECANPAY, i.nValue, key) sign_p2pk_witness_input(witness_program, tx, index, SIGHASH_ALL | SIGHASH_ANYONECANPAY, i.nValue, key)
index += 1 index += 1
block = self.build_next_block() block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx]) self.update_witness_block_with_transactions(block, [tx])
@ -1453,7 +1504,6 @@ class SegWitTest(BitcoinTestFramework):
for i in range(len(tx.vout)): for i in range(len(tx.vout)):
self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue)) self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue))
# Test P2SH wrapped witness programs. # Test P2SH wrapped witness programs.
def test_p2sh_witness(self, segwit_activated): def test_p2sh_witness(self, segwit_activated):
self.log.info("Testing P2SH witness transactions") self.log.info("Testing P2SH witness transactions")
@ -1465,13 +1515,13 @@ class SegWitTest(BitcoinTestFramework):
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
p2wsh_pubkey = CScript([OP_0, witness_hash]) p2wsh_pubkey = CScript([OP_0, witness_hash])
p2sh_witness_hash = hash160(p2wsh_pubkey) p2sh_witness_hash = hash160(p2wsh_pubkey)
scriptPubKey = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) script_pubkey = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL])
scriptSig = CScript([p2wsh_pubkey]) # a push of the redeem script script_sig = CScript([p2wsh_pubkey]) # a push of the redeem script
# Fund the P2SH output # Fund the P2SH output
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash() tx.rehash()
# Verify mempool acceptance and block validity # Verify mempool acceptance and block validity
@ -1483,7 +1533,7 @@ class SegWitTest(BitcoinTestFramework):
# Now test attempts to spend the output. # Now test attempts to spend the output.
spend_tx = CTransaction() spend_tx = CTransaction()
spend_tx.vin.append(CTxIn(COutPoint(tx.sha256, 0), scriptSig)) 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.vout.append(CTxOut(tx.vout[0].nValue - 1000, CScript([OP_TRUE])))
spend_tx.rehash() spend_tx.rehash()
@ -1494,14 +1544,14 @@ class SegWitTest(BitcoinTestFramework):
# segwit-aware would also reject this for failing CLEANSTACK. # 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) 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. # Try to put the witness script in the script_sig, should also fail.
spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a']) spend_tx.vin[0].script_sig = CScript([p2wsh_pubkey, b'a'])
spend_tx.rehash() spend_tx.rehash()
test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False) 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 # Now put the witness script in the witness, should succeed after
# segwit activates. # segwit activates.
spend_tx.vin[0].scriptSig = scriptSig spend_tx.vin[0].scriptSig = script_sig
spend_tx.rehash() spend_tx.rehash()
spend_tx.wit.vtxinwit.append(CTxInWitness()) spend_tx.wit.vtxinwit.append(CTxInWitness())
spend_tx.wit.vtxinwit[0].scriptWitness.stack = [b'a', witness_program] spend_tx.wit.vtxinwit[0].scriptWitness.stack = [b'a', witness_program]
@ -1555,7 +1605,6 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getblock(block_hash), self.nodes[node_id].getblock(block_hash)) assert_equal(self.nodes[0].getblock(block_hash), self.nodes[node_id].getblock(block_hash))
height -= 1 height -= 1
def test_witness_sigops(self): def test_witness_sigops(self):
'''Ensure sigop counting is correct inside witnesses.''' '''Ensure sigop counting is correct inside witnesses.'''
self.log.info("Testing sigops limit") self.log.info("Testing sigops limit")
@ -1565,7 +1614,7 @@ class SegWitTest(BitcoinTestFramework):
# Keep this under MAX_OPS_PER_SCRIPT (201) # 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_program = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKMULTISIG] * 5 + [OP_CHECKSIG] * 193 + [OP_ENDIF])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptPubKey = CScript([OP_0, witness_hash]) script_pubkey = CScript([OP_0, witness_hash])
sigops_per_script = 20 * 5 + 193 * 1 sigops_per_script = 20 * 5 + 193 * 1
# We'll produce 2 extra outputs, one with a program that would take us # We'll produce 2 extra outputs, one with a program that would take us
@ -1582,22 +1631,22 @@ class SegWitTest(BitcoinTestFramework):
# would push us just over the block sigop limit. # 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_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) witness_hash_toomany = sha256(witness_program_toomany)
scriptPubKey_toomany = CScript([OP_0, witness_hash_toomany]) script_pubkey_toomany = CScript([OP_0, witness_hash_toomany])
# If we spend this script instead, we would exactly reach our sigop # If we spend this script instead, we would exactly reach our sigop
# limit (for witness sigops). # limit (for witness sigops).
witness_program_justright = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG] * (extra_sigops_available) + [OP_ENDIF]) 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) witness_hash_justright = sha256(witness_program_justright)
scriptPubKey_justright = CScript([OP_0, witness_hash_justright]) script_pubkey_justright = CScript([OP_0, witness_hash_justright])
# First split our available utxo into a bunch of outputs # First split our available utxo into a bunch of outputs
split_value = self.utxo[0].nValue // outputs split_value = self.utxo[0].nValue // outputs
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
for i in range(outputs): for i in range(outputs):
tx.vout.append(CTxOut(split_value, scriptPubKey)) tx.vout.append(CTxOut(split_value, script_pubkey))
tx.vout[-2].scriptPubKey = scriptPubKey_toomany tx.vout[-2].scriptPubKey = script_pubkey_toomany
tx.vout[-1].scriptPubKey = scriptPubKey_justright tx.vout[-1].scriptPubKey = script_pubkey_justright
tx.rehash() tx.rehash()
block_1 = self.build_next_block() block_1 = self.build_next_block()
@ -1624,8 +1673,8 @@ class SegWitTest(BitcoinTestFramework):
# Try dropping the last input in tx2, and add an output that has # Try dropping the last input in tx2, and add an output that has
# too many sigops (contributing to legacy sigop count). # too many sigops (contributing to legacy sigop count).
checksig_count = (extra_sigops_available // 4) + 1 checksig_count = (extra_sigops_available // 4) + 1
scriptPubKey_checksigs = CScript([OP_CHECKSIG]*checksig_count) script_pubkey_checksigs = CScript([OP_CHECKSIG] * checksig_count)
tx2.vout.append(CTxOut(0, scriptPubKey_checksigs)) tx2.vout.append(CTxOut(0, script_pubkey_checksigs))
tx2.vin.pop() tx2.vin.pop()
tx2.wit.vtxinwit.pop() tx2.wit.vtxinwit.pop()
tx2.vout[0].nValue -= tx.vout[-2].nValue tx2.vout[0].nValue -= tx.vout[-2].nValue
@ -1724,10 +1773,10 @@ class SegWitTest(BitcoinTestFramework):
# Test 1: P2WPKH # Test 1: P2WPKH
# First create a P2WPKH output that uses an uncompressed pubkey # First create a P2WPKH output that uses an uncompressed pubkey
pubkeyhash = hash160(pubkey) pubkeyhash = hash160(pubkey)
scriptPKH = CScript([OP_0, pubkeyhash]) script_pkh = CScript([OP_0, pubkeyhash])
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b"")) tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b""))
tx.vout.append(CTxOut(utxo.nValue-1000, scriptPKH)) tx.vout.append(CTxOut(utxo.nValue - 1000, script_pkh))
tx.rehash() tx.rehash()
# Confirm it in a block. # Confirm it in a block.
@ -1739,12 +1788,12 @@ class SegWitTest(BitcoinTestFramework):
# use in the next test. # use in the next test.
witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)])
witness_hash = sha256(witness_program) witness_hash = sha256(witness_program)
scriptWSH = CScript([OP_0, witness_hash]) script_wsh = CScript([OP_0, witness_hash])
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptWSH)) tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh))
script = GetP2PKHScript(pubkeyhash) script = get_p2pkh_script(pubkeyhash)
sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
@ -1761,15 +1810,15 @@ class SegWitTest(BitcoinTestFramework):
# Test 2: P2WSH # Test 2: P2WSH
# Try to spend the P2WSH output created in last test. # 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. # Send it to a P2SH(P2WSH) output, which we'll use in the next test.
p2sh_witness_hash = hash160(scriptWSH) p2sh_witness_hash = hash160(script_wsh)
scriptP2SH = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) script_p2sh = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL])
scriptSig = CScript([scriptWSH]) script_sig = CScript([script_wsh])
tx3 = CTransaction() tx3 = CTransaction()
tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b""))
tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptP2SH)) tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, script_p2sh))
tx3.wit.vtxinwit.append(CTxInWitness()) tx3.wit.vtxinwit.append(CTxInWitness())
sign_P2PK_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) sign_p2pk_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key)
# Should fail policy test. # 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)') 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)')
@ -1781,12 +1830,12 @@ class SegWitTest(BitcoinTestFramework):
# Test 3: P2SH(P2WSH) # Test 3: P2SH(P2WSH)
# Try to spend the P2SH output created in the last test. # 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. # Send it to a P2PKH output, which we'll use in the next test.
scriptPubKey = GetP2PKHScript(pubkeyhash) script_pubkey = get_p2pkh_script(pubkeyhash)
tx4 = CTransaction() tx4 = CTransaction()
tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), scriptSig)) tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), script_sig))
tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, scriptPubKey)) tx4.vout.append(CTxOut(tx3.vout[0].nValue - 1000, script_pubkey))
tx4.wit.vtxinwit.append(CTxInWitness()) tx4.wit.vtxinwit.append(CTxInWitness())
sign_P2PK_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) sign_p2pk_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key)
# Should fail policy test. # 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)') 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)')
@ -1799,7 +1848,7 @@ class SegWitTest(BitcoinTestFramework):
tx5 = CTransaction() tx5 = CTransaction()
tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b"")) tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b""))
tx5.vout.append(CTxOut(tx4.vout[0].nValue - 1000, CScript([OP_TRUE]))) tx5.vout.append(CTxOut(tx4.vout[0].nValue - 1000, CScript([OP_TRUE])))
(sig_hash, err) = SignatureHash(scriptPubKey, tx5, 0, SIGHASH_ALL) (sig_hash, err) = SignatureHash(script_pubkey, tx5, 0, SIGHASH_ALL)
signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx5.vin[0].scriptSig = CScript([signature, pubkey]) tx5.vin[0].scriptSig = CScript([signature, pubkey])
tx5.rehash() tx5.rehash()
@ -1819,13 +1868,13 @@ class SegWitTest(BitcoinTestFramework):
# in P2SH). # in P2SH).
p2sh_program = CScript([OP_TRUE]) p2sh_program = CScript([OP_TRUE])
p2sh_pubkey = hash160(p2sh_program) p2sh_pubkey = hash160(p2sh_program)
scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
# Now check that unnecessary witnesses can't be used to blind a node # Now check that unnecessary witnesses can't be used to blind a node
# to a transaction, eg by violating standardness checks. # to a transaction, eg by violating standardness checks.
tx = CTransaction() tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) 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.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash() tx.rehash()
test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, False, True) test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, False, True)
self.nodes[0].generate(1) self.nodes[0].generate(1)
@ -1838,7 +1887,7 @@ class SegWitTest(BitcoinTestFramework):
# to the rejection cache. # to the rejection cache.
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), CScript([p2sh_program]))) tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), CScript([p2sh_program])))
tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, scriptPubKey)) tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_pubkey))
tx2.wit.vtxinwit.append(CTxInWitness()) tx2.wit.vtxinwit.append(CTxInWitness())
tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a' * 400] tx2.wit.vtxinwit[0].scriptWitness.stack = [b'a' * 400]
tx2.rehash() tx2.rehash()
@ -2035,6 +2084,5 @@ class SegWitTest(BitcoinTestFramework):
self.test_upgrade_after_activation(node_id=2) self.test_upgrade_after_activation(node_id=2)
self.test_witness_sigops() self.test_witness_sigops()
if __name__ == '__main__': if __name__ == '__main__':
SegWitTest().main() SegWitTest().main()