Remove unmaintained example test script_test.py
This commit is contained in:
parent
e54ebbf600
commit
c800c95997
@ -106,7 +106,6 @@ testScriptsExt = [
|
||||
'keypool.py',
|
||||
'receivedby.py',
|
||||
# 'rpcbind_test.py', #temporary, bug in libevent, see #6655
|
||||
# 'script_test.py', #used for manual comparison of 2 binaries
|
||||
'smartfees.py',
|
||||
'maxblocksinflight.py',
|
||||
'invalidblockrequest.py',
|
||||
|
@ -1,259 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
'''
|
||||
Test notes:
|
||||
This test uses the script_valid and script_invalid tests from the unittest
|
||||
framework to do end-to-end testing where we compare that two nodes agree on
|
||||
whether blocks containing a given test script are valid.
|
||||
|
||||
We generally ignore the script flags associated with each test (since we lack
|
||||
the precision to test each script using those flags in this framework), but
|
||||
for tests with SCRIPT_VERIFY_P2SH, we can use a block time after the BIP16
|
||||
switchover date to try to test with that flag enabled (and for tests without
|
||||
that flag, we use a block time before the switchover date).
|
||||
|
||||
NOTE: This test is very slow and may take more than 40 minutes to run.
|
||||
'''
|
||||
|
||||
from test_framework.test_framework import ComparisonTestFramework
|
||||
from test_framework.util import *
|
||||
from test_framework.comptool import TestInstance, TestManager
|
||||
from test_framework.mininode import *
|
||||
from test_framework.blocktools import *
|
||||
from test_framework.script import *
|
||||
import logging
|
||||
import copy
|
||||
import json
|
||||
|
||||
script_valid_file = "../../src/test/data/script_valid.json"
|
||||
script_invalid_file = "../../src/test/data/script_invalid.json"
|
||||
|
||||
# Pass in a set of json files to open.
|
||||
class ScriptTestFile(object):
|
||||
|
||||
def __init__(self, files):
|
||||
self.files = files
|
||||
self.index = -1
|
||||
self.data = []
|
||||
|
||||
def load_files(self):
|
||||
for f in self.files:
|
||||
self.data.extend(json.loads(open(os.path.dirname(os.path.abspath(__file__))+"/"+f).read()))
|
||||
|
||||
# Skip over records that are not long enough to be tests
|
||||
def get_records(self):
|
||||
while (self.index < len(self.data)):
|
||||
if len(self.data[self.index]) >= 3:
|
||||
yield self.data[self.index]
|
||||
self.index += 1
|
||||
|
||||
|
||||
# Helper for parsing the flags specified in the .json files
|
||||
SCRIPT_VERIFY_NONE = 0
|
||||
SCRIPT_VERIFY_P2SH = 1
|
||||
SCRIPT_VERIFY_STRICTENC = 1 << 1
|
||||
SCRIPT_VERIFY_DERSIG = 1 << 2
|
||||
SCRIPT_VERIFY_LOW_S = 1 << 3
|
||||
SCRIPT_VERIFY_NULLDUMMY = 1 << 4
|
||||
SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5
|
||||
SCRIPT_VERIFY_MINIMALDATA = 1 << 6
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7
|
||||
SCRIPT_VERIFY_CLEANSTACK = 1 << 8
|
||||
|
||||
flag_map = {
|
||||
"": SCRIPT_VERIFY_NONE,
|
||||
"NONE": SCRIPT_VERIFY_NONE,
|
||||
"P2SH": SCRIPT_VERIFY_P2SH,
|
||||
"STRICTENC": SCRIPT_VERIFY_STRICTENC,
|
||||
"DERSIG": SCRIPT_VERIFY_DERSIG,
|
||||
"LOW_S": SCRIPT_VERIFY_LOW_S,
|
||||
"NULLDUMMY": SCRIPT_VERIFY_NULLDUMMY,
|
||||
"SIGPUSHONLY": SCRIPT_VERIFY_SIGPUSHONLY,
|
||||
"MINIMALDATA": SCRIPT_VERIFY_MINIMALDATA,
|
||||
"DISCOURAGE_UPGRADABLE_NOPS": SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
|
||||
"CLEANSTACK": SCRIPT_VERIFY_CLEANSTACK,
|
||||
}
|
||||
|
||||
def ParseScriptFlags(flag_string):
|
||||
flags = 0
|
||||
for x in flag_string.split(","):
|
||||
if x in flag_map:
|
||||
flags |= flag_map[x]
|
||||
else:
|
||||
print "Error: unrecognized script flag: ", x
|
||||
return flags
|
||||
|
||||
'''
|
||||
Given a string that is a scriptsig or scriptpubkey from the .json files above,
|
||||
convert it to a CScript()
|
||||
'''
|
||||
# Replicates behavior from core_read.cpp
|
||||
def ParseScript(json_script):
|
||||
script = json_script.split(" ")
|
||||
parsed_script = CScript()
|
||||
for x in script:
|
||||
if len(x) == 0:
|
||||
# Empty string, ignore.
|
||||
pass
|
||||
elif x.isdigit() or (len(x) >= 1 and x[0] == "-" and x[1:].isdigit()):
|
||||
# Number
|
||||
n = int(x, 0)
|
||||
if (n == -1) or (n >= 1 and n <= 16):
|
||||
parsed_script = CScript(bytes(parsed_script) + bytes(CScript([n])))
|
||||
else:
|
||||
parsed_script += CScriptNum(int(x, 0))
|
||||
elif x.startswith("0x"):
|
||||
# Raw hex data, inserted NOT pushed onto stack:
|
||||
for i in xrange(2, len(x), 2):
|
||||
parsed_script = CScript(bytes(parsed_script) + bytes(chr(int(x[i:i+2],16))))
|
||||
elif x.startswith("'") and x.endswith("'") and len(x) >= 2:
|
||||
# Single-quoted string, pushed as data.
|
||||
parsed_script += CScript([x[1:-1]])
|
||||
else:
|
||||
# opcode, e.g. OP_ADD or ADD:
|
||||
tryopname = "OP_" + x
|
||||
if tryopname in OPCODES_BY_NAME:
|
||||
parsed_script += CScriptOp(OPCODES_BY_NAME["OP_" + x])
|
||||
else:
|
||||
print "ParseScript: error parsing '%s'" % x
|
||||
return ""
|
||||
return parsed_script
|
||||
|
||||
class TestBuilder(object):
|
||||
def create_credit_tx(self, scriptPubKey, height):
|
||||
# self.tx1 is a coinbase transaction, modeled after the one created by script_tests.cpp
|
||||
# This allows us to reuse signatures created in the unit test framework.
|
||||
self.tx1 = create_coinbase(height) # this has a bip34 scriptsig,
|
||||
self.tx1.vin[0].scriptSig = CScript([0, 0]) # but this matches the unit tests
|
||||
self.tx1.vout[0].nValue = 0
|
||||
self.tx1.vout[0].scriptPubKey = scriptPubKey
|
||||
self.tx1.rehash()
|
||||
def create_spend_tx(self, scriptSig):
|
||||
self.tx2 = create_transaction(self.tx1, 0, CScript(), 0)
|
||||
self.tx2.vin[0].scriptSig = scriptSig
|
||||
self.tx2.vout[0].scriptPubKey = CScript()
|
||||
self.tx2.rehash()
|
||||
def rehash(self):
|
||||
self.tx1.rehash()
|
||||
self.tx2.rehash()
|
||||
|
||||
# This test uses the (default) two nodes provided by ComparisonTestFramework,
|
||||
# specified on the command line with --testbinary and --refbinary.
|
||||
# See comptool.py
|
||||
class ScriptTest(ComparisonTestFramework):
|
||||
|
||||
def run_test(self):
|
||||
# Set up the comparison tool TestManager
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
test.add_all_connections(self.nodes)
|
||||
|
||||
# Load scripts
|
||||
self.scripts = ScriptTestFile([script_valid_file, script_invalid_file])
|
||||
self.scripts.load_files()
|
||||
|
||||
# Some variables we re-use between test instances (to build blocks)
|
||||
self.tip = None
|
||||
self.block_time = None
|
||||
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
def generate_test_instance(self, pubkeystring, scriptsigstring):
|
||||
scriptpubkey = ParseScript(pubkeystring)
|
||||
scriptsig = ParseScript(scriptsigstring)
|
||||
|
||||
test = TestInstance(sync_every_block=False)
|
||||
test_build = TestBuilder()
|
||||
test_build.create_credit_tx(scriptpubkey, self.height)
|
||||
test_build.create_spend_tx(scriptsig)
|
||||
test_build.rehash()
|
||||
|
||||
block = create_block(self.tip, test_build.tx1, self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
self.height += 1
|
||||
test.blocks_and_transactions = [[block, True]]
|
||||
|
||||
for i in xrange(100):
|
||||
block = create_block(self.tip, create_coinbase(self.height), self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
self.height += 1
|
||||
test.blocks_and_transactions.append([block, True])
|
||||
|
||||
block = create_block(self.tip, create_coinbase(self.height), self.block_time)
|
||||
self.block_time += 1
|
||||
block.vtx.append(test_build.tx2)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test.blocks_and_transactions.append([block, None])
|
||||
return test
|
||||
|
||||
# This generates the tests for TestManager.
|
||||
def get_tests(self):
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.block_time = 1333230000 # before the BIP16 switchover
|
||||
self.height = 1
|
||||
|
||||
'''
|
||||
Create a new block with an anyone-can-spend coinbase
|
||||
'''
|
||||
block = create_block(self.tip, create_coinbase(self.height), self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
self.height += 1
|
||||
yield TestInstance(objects=[[block, True]])
|
||||
|
||||
'''
|
||||
Build out to 100 blocks total, maturing the coinbase.
|
||||
'''
|
||||
test = TestInstance(objects=[], sync_every_block=False, sync_every_tx=False)
|
||||
for i in xrange(100):
|
||||
b = create_block(self.tip, create_coinbase(self.height), self.block_time)
|
||||
b.solve()
|
||||
test.blocks_and_transactions.append([b, True])
|
||||
self.tip = b.sha256
|
||||
self.block_time += 1
|
||||
self.height += 1
|
||||
yield test
|
||||
|
||||
''' Iterate through script tests. '''
|
||||
counter = 0
|
||||
for script_test in self.scripts.get_records():
|
||||
''' Reset the blockchain to genesis block + 100 blocks. '''
|
||||
if self.nodes[0].getblockcount() > 101:
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(102))
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(102))
|
||||
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.height = 102
|
||||
|
||||
[scriptsig, scriptpubkey, flags] = script_test[0:3]
|
||||
flags = ParseScriptFlags(flags)
|
||||
|
||||
# We can use block time to determine whether the nodes should be
|
||||
# enforcing BIP16.
|
||||
#
|
||||
# We intentionally let the block time grow by 1 each time.
|
||||
# This forces the block hashes to differ between tests, so that
|
||||
# a call to invalidateblock doesn't interfere with a later test.
|
||||
if (flags & SCRIPT_VERIFY_P2SH):
|
||||
self.block_time = 1333238400 + counter # Advance to enforcing BIP16
|
||||
else:
|
||||
self.block_time = 1333230000 + counter # Before the BIP16 switchover
|
||||
|
||||
print "Script test: [%s]" % script_test
|
||||
|
||||
yield self.generate_test_instance(scriptpubkey, scriptsig)
|
||||
counter += 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
ScriptTest().main()
|
Loading…
Reference in New Issue
Block a user