0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-12 11:19:08 -05:00

test: add logging to rpc_decodescript.py

Also remove the enumerations ("1)", "2)"...) from the test
cases as those potentially hinder maintainability; e.g. if a
new case in inserted in-between, all the remaining
enumerations would need to be adapted.
This commit is contained in:
Sebastian Falbesoner 2021-11-17 23:26:28 +01:00
parent 2ef186a140
commit 0d43525c61

View file

@ -27,29 +27,29 @@ class DecodeScriptTest(BitcoinTestFramework):
# below are test cases for all of the standard transaction types # below are test cases for all of the standard transaction types
# 1) P2PK scriptSig self.log.info("- P2PK")
# the scriptSig of a public key scriptPubKey simply pushes a signature onto the stack # the scriptSig of a public key scriptPubKey simply pushes a signature onto the stack
rpc_result = self.nodes[0].decodescript(push_signature) rpc_result = self.nodes[0].decodescript(push_signature)
assert_equal(signature, rpc_result['asm']) assert_equal(signature, rpc_result['asm'])
# 2) P2PKH scriptSig self.log.info("- P2PKH")
rpc_result = self.nodes[0].decodescript(push_signature + push_public_key) rpc_result = self.nodes[0].decodescript(push_signature + push_public_key)
assert_equal(signature + ' ' + public_key, rpc_result['asm']) assert_equal(signature + ' ' + public_key, rpc_result['asm'])
# 3) multisig scriptSig self.log.info("- multisig")
# this also tests the leading portion of a P2SH multisig scriptSig # this also tests the leading portion of a P2SH multisig scriptSig
# OP_0 <A sig> <B sig> # OP_0 <A sig> <B sig>
rpc_result = self.nodes[0].decodescript('00' + push_signature + push_signature) rpc_result = self.nodes[0].decodescript('00' + push_signature + push_signature)
assert_equal('0 ' + signature + ' ' + signature, rpc_result['asm']) assert_equal('0 ' + signature + ' ' + signature, rpc_result['asm'])
# 4) P2SH scriptSig self.log.info("- P2SH")
# an empty P2SH redeemScript is valid and makes for a very simple test case. # an empty P2SH redeemScript is valid and makes for a very simple test case.
# thus, such a spending scriptSig would just need to pass the outer redeemScript # thus, such a spending scriptSig would just need to pass the outer redeemScript
# hash test and leave true on the top of the stack. # hash test and leave true on the top of the stack.
rpc_result = self.nodes[0].decodescript('5100') rpc_result = self.nodes[0].decodescript('5100')
assert_equal('1 0', rpc_result['asm']) assert_equal('1 0', rpc_result['asm'])
# 5) null data scriptSig - no such thing because null data scripts can not be spent. # null data scriptSig - no such thing because null data scripts can not be spent.
# thus, no test case for that standard transaction type is here. # thus, no test case for that standard transaction type is here.
def decodescript_script_pub_key(self): def decodescript_script_pub_key(self):
@ -63,21 +63,21 @@ class DecodeScriptTest(BitcoinTestFramework):
# below are test cases for all of the standard transaction types # below are test cases for all of the standard transaction types
# 1) P2PK scriptPubKey self.log.info("- P2PK")
# <pubkey> OP_CHECKSIG # <pubkey> OP_CHECKSIG
rpc_result = self.nodes[0].decodescript(push_public_key + 'ac') rpc_result = self.nodes[0].decodescript(push_public_key + 'ac')
assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm']) assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm'])
# P2PK is translated to P2WPKH # P2PK is translated to P2WPKH
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm']) assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
# 2) P2PKH scriptPubKey self.log.info("- P2PKH")
# OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG # OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac') rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac')
assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm']) assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm'])
# P2PKH is translated to P2WPKH # P2PKH is translated to P2WPKH
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm']) assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
# 3) multisig scriptPubKey self.log.info("- multisig")
# <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG # <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG
# just imagine that the pub keys used below are different. # just imagine that the pub keys used below are different.
# for our purposes here it does not matter that they are the same even though it is unrealistic. # for our purposes here it does not matter that they are the same even though it is unrealistic.
@ -88,7 +88,7 @@ class DecodeScriptTest(BitcoinTestFramework):
multisig_script_hash = sha256(bytes.fromhex(multisig_script)).hex() multisig_script_hash = sha256(bytes.fromhex(multisig_script)).hex()
assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm']) assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm'])
# 4) P2SH scriptPubKey self.log.info ("- P2SH")
# OP_HASH160 <Hash160(redeemScript)> OP_EQUAL. # OP_HASH160 <Hash160(redeemScript)> OP_EQUAL.
# push_public_key_hash here should actually be the hash of a redeem script. # push_public_key_hash here should actually be the hash of a redeem script.
# but this works the same for purposes of this test. # but this works the same for purposes of this test.
@ -97,7 +97,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# P2SH does not work in segwit secripts. decodescript should not return a result for it. # P2SH does not work in segwit secripts. decodescript should not return a result for it.
assert 'segwit' not in rpc_result assert 'segwit' not in rpc_result
# 5) null data scriptPubKey self.log.info("- null data")
# use a signature look-alike here to make sure that we do not decode random data as a signature. # use a signature look-alike here to make sure that we do not decode random data as a signature.
# this matters if/when signature sighash decoding comes along. # this matters if/when signature sighash decoding comes along.
# would want to make sure that no such decoding takes place in this case. # would want to make sure that no such decoding takes place in this case.
@ -106,7 +106,8 @@ class DecodeScriptTest(BitcoinTestFramework):
rpc_result = self.nodes[0].decodescript('6a' + signature_imposter) rpc_result = self.nodes[0].decodescript('6a' + signature_imposter)
assert_equal('OP_RETURN ' + signature_imposter[2:], rpc_result['asm']) assert_equal('OP_RETURN ' + signature_imposter[2:], rpc_result['asm'])
# 6) a CLTV redeem script. redeem scripts are in-effect scriptPubKey scripts, so adding a test here. self.log.info("- CLTV redeem script")
# redeem scripts are in-effect scriptPubKey scripts, so adding a test here.
# OP_NOP2 is also known as OP_CHECKLOCKTIMEVERIFY. # OP_NOP2 is also known as OP_CHECKLOCKTIMEVERIFY.
# just imagine that the pub keys used below are different. # just imagine that the pub keys used below are different.
# for our purposes here it does not matter that they are the same even though it is unrealistic. # for our purposes here it does not matter that they are the same even though it is unrealistic.
@ -126,7 +127,7 @@ class DecodeScriptTest(BitcoinTestFramework):
cltv_script_hash = sha256(bytes.fromhex(cltv_script)).hex() cltv_script_hash = sha256(bytes.fromhex(cltv_script)).hex()
assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm']) assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm'])
# 7) P2PK scriptPubKey self.log.info("- P2PK with uncompressed pubkey")
# <pubkey> OP_CHECKSIG # <pubkey> OP_CHECKSIG
rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac') rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac')
assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm']) assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm'])
@ -134,7 +135,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# decodescript should not return a P2WPKH equivalent. # decodescript should not return a P2WPKH equivalent.
assert 'segwit' not in rpc_result assert 'segwit' not in rpc_result
# 8) multisig scriptPubKey with an uncompressed pubkey self.log.info("- multisig with uncompressed pubkey")
# <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG # <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG
# just imagine that the pub keys used below are different. # just imagine that the pub keys used below are different.
# the purpose of this test is to check that a segwit script is not returned for bare multisig scripts # the purpose of this test is to check that a segwit script is not returned for bare multisig scripts
@ -145,7 +146,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# decodescript should not return a P2WPKH equivalent. # decodescript should not return a P2WPKH equivalent.
assert 'segwit' not in rpc_result assert 'segwit' not in rpc_result
# 9) P2WPKH scriptpubkey self.log.info("- P2WPKH")
# 0 <PubKeyHash> # 0 <PubKeyHash>
rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash) rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash)
assert_equal('0 ' + public_key_hash, rpc_result['asm']) assert_equal('0 ' + public_key_hash, rpc_result['asm'])
@ -153,7 +154,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# a nested segwit script should not be returned in the results. # a nested segwit script should not be returned in the results.
assert 'segwit' not in rpc_result assert 'segwit' not in rpc_result
# 10) P2WSH scriptpubkey self.log.info("- P2WSH")
# 0 <ScriptHash> # 0 <ScriptHash>
# even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter # even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter
# for the purpose of this test. # for the purpose of this test.
@ -169,7 +170,8 @@ class DecodeScriptTest(BitcoinTestFramework):
This test is in with the "decodescript" tests because they are testing the same "asm" script decodes. This test is in with the "decodescript" tests because they are testing the same "asm" script decodes.
""" """
# this test case uses a random plain vanilla mainnet transaction with a single P2PKH input and output self.log.info("- various mainnet txs")
# this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs.
tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000' tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000'
rpc_result = self.nodes[0].decoderawtransaction(tx) rpc_result = self.nodes[0].decoderawtransaction(tx)
assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm']) assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm'])
@ -185,11 +187,13 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
txSave = tx_from_hex(tx) txSave = tx_from_hex(tx)
self.log.info("- tx not passing DER signature checks")
# make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
rpc_result = self.nodes[0].decoderawtransaction(tx) rpc_result = self.nodes[0].decoderawtransaction(tx)
assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm']) assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm'])
self.log.info("- tx passing DER signature checks")
# verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks # verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks
tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000' tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000'
rpc_result = self.nodes[0].decoderawtransaction(tx) rpc_result = self.nodes[0].decoderawtransaction(tx)
@ -207,7 +211,7 @@ class DecodeScriptTest(BitcoinTestFramework):
push_signature_2 = '48' + signature_2 push_signature_2 = '48' + signature_2
signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]' signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
# 1) P2PK scriptSig self.log.info("- P2PK scriptSig")
txSave.vin[0].scriptSig = bytes.fromhex(push_signature) txSave.vin[0].scriptSig = bytes.fromhex(push_signature)
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex()) rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
@ -217,20 +221,23 @@ class DecodeScriptTest(BitcoinTestFramework):
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex()) rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 2) multisig scriptSig self.log.info("- multisig scriptSig")
txSave.vin[0].scriptSig = bytes.fromhex('00' + push_signature + push_signature_2) txSave.vin[0].scriptSig = bytes.fromhex('00' + push_signature + push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex()) rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 3) test a scriptSig that contains more than push operations. self.log.info("- scriptSig that contains more than push operations")
# in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it. # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
txSave.vin[0].scriptSig = bytes.fromhex('6a143011020701010101010101020601010101010101') txSave.vin[0].scriptSig = bytes.fromhex('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex()) rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm']) assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self): def run_test(self):
self.log.info("Test decoding of standard input scripts [scriptSig]")
self.decodescript_script_sig() self.decodescript_script_sig()
self.log.info("Test decoding of standard output scripts [scriptPubKey]")
self.decodescript_script_pub_key() self.decodescript_script_pub_key()
self.log.info("Test 'asm' script decoding of transactions")
self.decoderawtransaction_asm_sighashtype() self.decoderawtransaction_asm_sighashtype()
if __name__ == '__main__': if __name__ == '__main__':