Improve readability of segwit.py

This commit is contained in:
Suhas Daftuar 2017-03-10 11:21:20 -05:00
parent 21833f9456
commit b9f34e84be
2 changed files with 43 additions and 41 deletions

View File

@ -102,7 +102,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
segwit_out = rbf_node.validateaddress(rbf_node.getnewaddress()) segwit_out = rbf_node.validateaddress(rbf_node.getnewaddress())
rbf_node.addwitnessaddress(segwit_out["address"]) rbf_node.addwitnessaddress(segwit_out["address"])
segwitid = send_to_witness( segwitid = send_to_witness(
version=0, use_p2wsh=False,
node=rbf_node, node=rbf_node,
utxo=segwit_in, utxo=segwit_in,
pubkey=segwit_out["pubkey"], pubkey=segwit_out["pubkey"],

View File

@ -6,11 +6,11 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut, COIN
from test_framework.address import script_to_p2sh, key_to_p2pkh from test_framework.address import script_to_p2sh, key_to_p2pkh
from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, hash160
from io import BytesIO from io import BytesIO
from test_framework.mininode import FromHex from test_framework.mininode import FromHex, ToHex
NODE_0 = 0 NODE_0 = 0
NODE_1 = 1 NODE_1 = 1
@ -18,47 +18,49 @@ NODE_2 = 2
WIT_V0 = 0 WIT_V0 = 0
WIT_V1 = 1 WIT_V1 = 1
def witness_script(version, pubkey): # Create a scriptPubKey corresponding to either a P2WPKH output for the
if (version == 0): # given pubkey, or a P2WSH output of a 1-of-1 multisig for the given
pubkeyhash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pubkey)))) # pubkey. Returns the hex encoding of the scriptPubKey.
pkscript = "0014" + pubkeyhash def witness_script(use_p2wsh, pubkey):
elif (version == 1): if (use_p2wsh == False):
# 1-of-1 multisig # P2WPKH instead
scripthash = bytes_to_hex_str(sha256(hex_str_to_bytes("5121" + pubkey + "51ae"))) pubkeyhash = hash160(hex_str_to_bytes(pubkey))
pkscript = "0020" + scripthash pkscript = CScript([OP_0, pubkeyhash])
else: else:
assert("Wrong version" == "0 or 1") # 1-of-1 multisig
return pkscript witness_program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG])
scripthash = sha256(witness_program)
pkscript = CScript([OP_0, scripthash])
return bytes_to_hex_str(pkscript)
def addlength(script): # Return a transaction (in hex) that spends the given utxo to a segwit output,
scriptlen = format(len(script)//2, 'x') # optionally wrapping the segwit output using P2SH.
assert(len(scriptlen) == 2) def create_witnessprogram(use_p2wsh, utxo, pubkey, encode_p2sh, amount):
return scriptlen + script pkscript = hex_str_to_bytes(witness_script(use_p2wsh, pubkey))
def create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount):
pkscript = witness_script(version, pubkey)
if (encode_p2sh): if (encode_p2sh):
p2sh_hash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pkscript)))) p2sh_hash = hash160(pkscript)
pkscript = "a914"+p2sh_hash+"87" pkscript = CScript([OP_HASH160, p2sh_hash, OP_EQUAL])
inputs = [] tx = CTransaction()
outputs = {} tx.vin.append(CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), b""))
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]} ) tx.vout.append(CTxOut(int(amount*COIN), pkscript))
DUMMY_P2SH = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP" return ToHex(tx)
outputs[DUMMY_P2SH] = amount
tx_to_witness = node.createrawtransaction(inputs,outputs)
#replace dummy output with our own
tx_to_witness = tx_to_witness[0:110] + addlength(pkscript) + tx_to_witness[-8:]
return tx_to_witness
def send_to_witness(version, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""): # Create a transaction spending a given utxo to a segwit output corresponding
tx_to_witness = create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount) # to the given pubkey: use_p2wsh determines whether to use P2WPKH or P2WSH;
# encode_p2sh determines whether to wrap in P2SH.
# sign=True will have the given node sign the transaction.
# insert_redeem_script will be added to the scriptSig, if given.
def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):
tx_to_witness = create_witnessprogram(use_p2wsh, utxo, pubkey, encode_p2sh, amount)
if (sign): if (sign):
signed = node.signrawtransaction(tx_to_witness) signed = node.signrawtransaction(tx_to_witness)
assert("errors" not in signed or len(["errors"]) == 0) assert("errors" not in signed or len(["errors"]) == 0)
return node.sendrawtransaction(signed["hex"]) return node.sendrawtransaction(signed["hex"])
else: else:
if (insert_redeem_script): if (insert_redeem_script):
tx_to_witness = tx_to_witness[0:82] + addlength(insert_redeem_script) + tx_to_witness[84:] tx = FromHex(CTransaction(), tx_to_witness)
tx.vin[0].scriptSig += CScript([hex_str_to_bytes(insert_redeem_script)])
tx_to_witness = ToHex(tx)
return node.sendrawtransaction(tx_to_witness) return node.sendrawtransaction(tx_to_witness)
@ -180,8 +182,8 @@ class SegWitTest(BitcoinTestFramework):
self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False) self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False)
self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False) self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False)
# unsigned with redeem script # unsigned with redeem script
self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False, addlength(witness_script(0, self.pubkey[0]))) self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False, witness_script(False, self.pubkey[0]))
self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False, addlength(witness_script(1, self.pubkey[0]))) self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False, witness_script(True, self.pubkey[0]))
# signed # signed
self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True)
self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True) self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True)
@ -205,8 +207,8 @@ class SegWitTest(BitcoinTestFramework):
self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False) self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False)
self.log.info("Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork") self.log.info("Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork")
self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False, addlength(witness_script(0, self.pubkey[2]))) #block 430 self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False, witness_script(False, self.pubkey[2])) #block 430
self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False, addlength(witness_script(1, self.pubkey[2]))) #block 431 self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False, witness_script(True, self.pubkey[2])) #block 431
self.log.info("Verify previous witness txs skipped for mining can now be mined") self.log.info("Verify previous witness txs skipped for mining can now be mined")
assert_equal(len(self.nodes[2].getrawmempool()), 4) assert_equal(len(self.nodes[2].getrawmempool()), 4)
@ -230,8 +232,8 @@ class SegWitTest(BitcoinTestFramework):
self.log.info("Verify witness txs without witness data are invalid after the fork") self.log.info("Verify witness txs without witness data are invalid after the fork")
self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False) self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False)
self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][2], False) self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][2], False)
self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False, addlength(witness_script(0, self.pubkey[2]))) self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False, witness_script(False, self.pubkey[2]))
self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False, addlength(witness_script(1, self.pubkey[2]))) self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False, witness_script(True, self.pubkey[2]))
self.log.info("Verify default node can now use witness txs") self.log.info("Verify default node can now use witness txs")
self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) #block 432 self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) #block 432