mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 23:18:14 +01:00
Add script manipulation tools for use in mininode testing framework
script.py is modified from the code in python-bitcoinlib, and provides tools for manipulating and creating CScript objects. bignum.py is a dependency for script.py script_test.py is an example test that uses the script tools for running a test that compares the behavior of two nodes, in a comptool- style test, for each of the test cases in the bitcoin unit test script files, script_valid.json and script_invalid.json. (This test is very slow to run, but is a proof of concept for how we can write tests to compare consensus-critical behavior between different versions of bitcoind.) bipdersig-p2p.py is another example test in the comptool framework, which tests deployment of BIP DERSIG for a single node. It uses the script.py tools for manipulating signatures to be non-DER compliant.
This commit is contained in:
102
qa/rpc-tests/bignum.py
Normal file
102
qa/rpc-tests/bignum.py
Normal file
@@ -0,0 +1,102 @@
|
||||
#
|
||||
#
|
||||
# bignum.py
|
||||
#
|
||||
# This file is copied from python-bitcoinlib.
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
"""Bignum routines"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
# generic big endian MPI format
|
||||
|
||||
def bn_bytes(v, have_ext=False):
|
||||
ext = 0
|
||||
if have_ext:
|
||||
ext = 1
|
||||
return ((v.bit_length()+7)//8) + ext
|
||||
|
||||
def bn2bin(v):
|
||||
s = bytearray()
|
||||
i = bn_bytes(v)
|
||||
while i > 0:
|
||||
s.append((v >> ((i-1) * 8)) & 0xff)
|
||||
i -= 1
|
||||
return s
|
||||
|
||||
def bin2bn(s):
|
||||
l = 0
|
||||
for ch in s:
|
||||
l = (l << 8) | ch
|
||||
return l
|
||||
|
||||
def bn2mpi(v):
|
||||
have_ext = False
|
||||
if v.bit_length() > 0:
|
||||
have_ext = (v.bit_length() & 0x07) == 0
|
||||
|
||||
neg = False
|
||||
if v < 0:
|
||||
neg = True
|
||||
v = -v
|
||||
|
||||
s = struct.pack(b">I", bn_bytes(v, have_ext))
|
||||
ext = bytearray()
|
||||
if have_ext:
|
||||
ext.append(0)
|
||||
v_bin = bn2bin(v)
|
||||
if neg:
|
||||
if have_ext:
|
||||
ext[0] |= 0x80
|
||||
else:
|
||||
v_bin[0] |= 0x80
|
||||
return s + ext + v_bin
|
||||
|
||||
def mpi2bn(s):
|
||||
if len(s) < 4:
|
||||
return None
|
||||
s_size = bytes(s[:4])
|
||||
v_len = struct.unpack(b">I", s_size)[0]
|
||||
if len(s) != (v_len + 4):
|
||||
return None
|
||||
if v_len == 0:
|
||||
return 0
|
||||
|
||||
v_str = bytearray(s[4:])
|
||||
neg = False
|
||||
i = v_str[0]
|
||||
if i & 0x80:
|
||||
neg = True
|
||||
i &= ~0x80
|
||||
v_str[0] = i
|
||||
|
||||
v = bin2bn(v_str)
|
||||
|
||||
if neg:
|
||||
return -v
|
||||
return v
|
||||
|
||||
# bitcoin-specific little endian format, with implicit size
|
||||
def mpi2vch(s):
|
||||
r = s[4:] # strip size
|
||||
r = r[::-1] # reverse string, converting BE->LE
|
||||
return r
|
||||
|
||||
def bn2vch(v):
|
||||
return bytes(mpi2vch(bn2mpi(v)))
|
||||
|
||||
def vch2mpi(s):
|
||||
r = struct.pack(b">I", len(s)) # size
|
||||
r += s[::-1] # reverse string, converting LE->BE
|
||||
return r
|
||||
|
||||
def vch2bn(s):
|
||||
return mpi2bn(vch2mpi(s))
|
||||
|
||||
Reference in New Issue
Block a user