mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 23:07:59 +01:00
[tests] p2p_segwit: Fix flake8 warnings.
This commit is contained in:
parent
a6ed99a1e6
commit
f7c7f8ecf3
1 changed files with 283 additions and 235 deletions
|
@ -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()
|
||||||
|
|
Loading…
Add table
Reference in a new issue