Add CScriptNum decode python implementation in functional suite

This commit is contained in:
Gregory Sanders 2018-11-27 10:06:19 -05:00
parent a4eaaa6ac5
commit 2012d4df23
2 changed files with 26 additions and 2 deletions

View file

@ -25,7 +25,7 @@ from test_framework.util import (
assert_raises_rpc_error, assert_raises_rpc_error,
bytes_to_hex_str as b2x, bytes_to_hex_str as b2x,
) )
from test_framework.script import CScriptNum
def assert_template(node, block, expect, rehash=True): def assert_template(node, block, expect, rehash=True):
if rehash: if rehash:
@ -65,11 +65,19 @@ class MiningTest(BitcoinTestFramework):
assert 'proposal' in tmpl['capabilities'] assert 'proposal' in tmpl['capabilities']
assert 'coinbasetxn' not in tmpl assert 'coinbasetxn' not in tmpl
coinbase_tx = create_coinbase(height=int(tmpl["height"]) + 1) next_height = int(tmpl["height"])
coinbase_tx = create_coinbase(height=next_height)
# sequence numbers must not be max for nLockTime to have effect # sequence numbers must not be max for nLockTime to have effect
coinbase_tx.vin[0].nSequence = 2 ** 32 - 2 coinbase_tx.vin[0].nSequence = 2 ** 32 - 2
coinbase_tx.rehash() coinbase_tx.rehash()
# round-trip the encoded bip34 block height commitment
assert_equal(CScriptNum.decode(coinbase_tx.vin[0].scriptSig), next_height)
# round-trip negative and multi-byte CScriptNums to catch python regression
assert_equal(CScriptNum.decode(CScriptNum.encode(CScriptNum(1500))), 1500)
assert_equal(CScriptNum.decode(CScriptNum.encode(CScriptNum(-1500))), -1500)
assert_equal(CScriptNum.decode(CScriptNum.encode(CScriptNum(-1))), -1)
block = CBlock() block = CBlock()
block.nVersion = tmpl["version"] block.nVersion = tmpl["version"]
block.hashPrevBlock = int(tmpl["previousblockhash"], 16) block.hashPrevBlock = int(tmpl["previousblockhash"], 16)

View file

@ -385,6 +385,22 @@ class CScriptNum:
r[-1] |= 0x80 r[-1] |= 0x80
return bytes([len(r)]) + r return bytes([len(r)]) + r
@staticmethod
def decode(vch):
result = 0
# We assume valid push_size and minimal encoding
value = vch[1:]
if len(value) == 0:
return result
for i, byte in enumerate(value):
result |= int(byte) << 8*i
if value[-1] >= 0x80:
# Mask for all but the highest result bit
num_mask = (2**(len(value)*8) - 1) >> 1
result &= num_mask
result *= -1
return result
class CScript(bytes): class CScript(bytes):
"""Serialized script """Serialized script