This commit is contained in:
2022-02-03 23:45:47 -08:00
parent 42c2062cc4
commit 184ece190c
1438 changed files with 404064 additions and 0 deletions
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
# Copyright 2014 BitPay Inc.
# Copyright 2016-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test framework for agrarian utils.
Runs automatically during `make check`.
Can also be run manually."""
from __future__ import division,print_function,unicode_literals
import argparse
import binascii
try:
import configparser
except ImportError:
import ConfigParser as configparser
import difflib
import json
import logging
import os
import pprint
import subprocess
import sys
def main():
config = configparser.ConfigParser()
config.optionxform = str
config.read_file(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8"))
env_conf = dict(config.items('environment'))
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
verbose = args.verbose
if verbose:
level = logging.DEBUG
else:
level = logging.ERROR
formatter = '%(asctime)s - %(levelname)s - %(message)s'
# Add the format/level to the logger
logging.basicConfig(format=formatter, level=level)
bctester(os.path.join(env_conf["SRCDIR"], "test", "util", "data"), "bitcoin-util-test.json", env_conf)
def bctester(testDir, input_basename, buildenv):
""" Loads and parses the input file, runs all tests and reports results"""
input_filename = os.path.join(testDir, input_basename)
raw_data = open(input_filename, encoding="utf8").read()
input_data = json.loads(raw_data)
failed_testcases = []
for testObj in input_data:
try:
bctest(testDir, testObj, buildenv)
logging.info("PASSED: " + testObj["description"])
except:
logging.info("FAILED: " + testObj["description"])
failed_testcases.append(testObj["description"])
if failed_testcases:
error_message = "FAILED_TESTCASES:\n"
error_message += pprint.pformat(failed_testcases, width=400)
logging.error(error_message)
sys.exit(1)
else:
sys.exit(0)
def bctest(testDir, testObj, buildenv):
"""Runs a single test, comparing output and RC to expected output and RC.
Raises an error if input can't be read, executable fails, or output/RC
are not as expected. Error is caught by bctester() and reported.
"""
# Get the exec names and arguments
execprog = os.path.join(buildenv["BUILDDIR"], "src", testObj["exec"] + buildenv["EXEEXT"])
execargs = testObj['args']
execrun = [execprog] + execargs
# Read the input data (if there is any)
stdinCfg = None
inputData = None
if "input" in testObj:
filename = os.path.join(testDir, testObj["input"])
inputData = open(filename, encoding="utf8").read()
stdinCfg = subprocess.PIPE
# Read the expected output data (if there is any)
outputFn = None
outputData = None
outputType = None
if "output_cmp" in testObj:
outputFn = testObj['output_cmp']
outputType = os.path.splitext(outputFn)[1][1:] # output type from file extension (determines how to compare)
try:
outputData = open(os.path.join(testDir, outputFn), encoding="utf8").read()
except:
logging.error("Output file " + outputFn + " can not be opened")
raise
if not outputData:
logging.error("Output data missing for " + outputFn)
raise Exception
if not outputType:
logging.error("Output file %s does not have a file extension" % outputFn)
raise Exception
# Run the test
proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
try:
outs = proc.communicate(input=inputData)
except OSError:
logging.error("OSError, Failed to execute " + execprog)
raise
if outputData:
data_mismatch, formatting_mismatch = False, False
# Parse command output and expected output
try:
a_parsed = parse_output(outs[0], outputType)
except Exception as e:
logging.error('Error parsing command output as %s: %s' % (outputType, e))
raise
try:
b_parsed = parse_output(outputData, outputType)
except Exception as e:
logging.error('Error parsing expected output %s as %s: %s' % (outputFn, outputType, e))
raise
# Compare data
if a_parsed != b_parsed:
logging.error("Output data mismatch for " + outputFn + " (format " + outputType + ")")
data_mismatch = True
# Compare formatting
if outs[0] != outputData:
error_message = "Output formatting mismatch for " + outputFn + ":\n"
error_message += "".join(difflib.context_diff(outputData.splitlines(True),
outs[0].splitlines(True),
fromfile=outputFn,
tofile="returned"))
logging.error(error_message)
formatting_mismatch = True
assert not data_mismatch and not formatting_mismatch
# Compare the return code to the expected return code
wantRC = 0
if "return_code" in testObj:
wantRC = testObj['return_code']
if proc.returncode != wantRC:
logging.error("Return code mismatch for " + outputFn)
raise Exception
if "error_txt" in testObj:
want_error = testObj["error_txt"]
# Compare error text
# TODO: ideally, we'd compare the strings exactly and also assert
# That stderr is empty if no errors are expected. However, agrarian-tx
# emits DISPLAY errors when running as a windows application on
# linux through wine. Just assert that the expected error text appears
# somewhere in stderr.
if want_error not in outs[1]:
logging.error("Error mismatch:\n" + "Expected: " + want_error + "\nReceived: " + outs[1].rstrip())
raise Exception
def parse_output(a, fmt):
"""Parse the output according to specified format.
Raise an error if the output can't be parsed."""
if fmt == 'json': # json: compare parsed data
return json.loads(a)
elif fmt == 'hex': # hex: parse and compare binary data
return binascii.a2b_hex(a.strip())
else:
raise NotImplementedError("Don't know how to compare %s" % fmt)
if __name__ == '__main__':
main()
+148
View File
@@ -0,0 +1,148 @@
[
{ "exec": "./agrarian-tx",
"args": ["-create"],
"output_cmp": "blanktxv1.hex",
"description": "Creates a blank v1 transaction"
},
{ "exec": "./agrarian-tx",
"args": ["-json","-create", "nversion=1"],
"output_cmp": "blanktxv1.json",
"description": "Creates a blank v1 transaction (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["-"],
"input": "blanktxv1.hex",
"output_cmp": "blanktxv1.hex",
"description": "Creates a blank transaction when nothing is piped into agrarian-tx"
},
{ "exec": "./agrarian-tx",
"args": ["-", "delin=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delin1-out.hex",
"description": "Deletes a single input from a transaction"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "-", "delin=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delin1-out.json",
"description": "Deletes a single input from a transaction (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["-", "delin=31"],
"input": "tx394b54bb.hex",
"return_code": 1,
"error_txt": "error: Invalid TX input index '31'",
"description": "Attempts to delete an input with a bad index from a transaction. Expected to fail."
},
{ "exec": "./agrarian-tx",
"args": ["-", "delout=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delout1-out.hex",
"description": "Deletes a single output from a transaction"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "-", "delout=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delout1-out.json",
"description": "Deletes a single output from a transaction (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["-", "delout=2"],
"input": "tx394b54bb.hex",
"return_code": 1,
"error_txt": "error: Invalid TX output index '2'",
"description": "Attempts to delete an output with a bad index from a transaction. Expected to fail."
},
{ "exec": "./agrarian-tx",
"args": ["-", "locktime=317000"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-locktime317000-out.hex",
"description": "Adds an nlocktime to a transaction"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "-", "locktime=317000"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-locktime317000-out.json",
"description": "Adds an nlocktime to a transaction (output in json)"
},
{ "exec": "./agrarian-tx",
"args":
["-create",
"outaddr=1"],
"return_code": 1,
"error_txt": "error: TX output missing separator",
"description": "Malformed outaddr argument (no address specified). Expected to fail."
},
{ "exec": "./agrarian-tx",
"args":
["-create",
"outaddr=1:DPvuYbbib66zreC6HNNQgUKzF3jnMmxk71:garbage"],
"return_code": 1,
"error_txt": "error: invalid TX output address",
"description": "Malformed outaddr argument (too many separators). Expected to fail."
},
{ "exec": "./agrarian-tx",
"args":
["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
"in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
"outaddr=0.18:DPvuYbbib66zreC6HNNQgUKzF3jnMmxk71",
"outaddr=4:D72dLgywmL73JyTwQBfuU29CADz9yCJ99v"],
"output_cmp": "txcreate1.hex",
"description": "Creates a new transaction with three inputs and two outputs"
},
{ "exec": "./agrarian-tx",
"args":
["-json",
"-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
"in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
"outaddr=0.18:DPvuYbbib66zreC6HNNQgUKzF3jnMmxk71",
"outaddr=4:D72dLgywmL73JyTwQBfuU29CADz9yCJ99v"],
"output_cmp": "txcreate1.json",
"description": "Creates a new transaction with three inputs and two outputs (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex",
"description": "Creates a new transaction with a single empty output script"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "-create", "outscript=0:"],
"output_cmp": "txcreate2.json",
"description": "Creates a new transaction with a single empty output script (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["01000000000100000000000000000000000000"],
"output_cmp": "txcreate2.hex",
"description": "Parses a transaction with no inputs and a single output script"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "01000000000100000000000000000000000000"],
"output_cmp": "txcreate2.json",
"description": "Parses a transaction with no inputs and a single output script (output in json)"
},
{ "exec": "./agrarian-tx",
"args": ["-create", "outscript=0:OP_DROP", "nversion=1"],
"output_cmp": "txcreatescript1.hex",
"description": "Create a new transaction with a single output script (OP_DROP)"
},
{ "exec": "./agrarian-tx",
"args": ["-json", "-create", "outscript=0:OP_DROP", "nversion=1"],
"output_cmp": "txcreatescript1.json",
"description": "Create a new transaction with a single output script (OP_DROP) (output as json)"
},
{ "exec": "./agrarian-tx",
"args":
["-create",
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
"set=privatekeys:[\"891ns7GR4owBiozmFa8jDSaJWNZ2q4XoSYdUS2kSNuKJ9BaxLkC\"]",
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
"sign=ALL",
"outaddr=0.001:D72dLgywmL73JyTwQBfuU29CADz9yCJ99v"],
"output_cmp": "txcreatesign.hex",
"description": "Creates a new transaction with a single input and a single output, and then signs the transaction"
}
]
+1
View File
@@ -0,0 +1 @@
01000000000000000000
+11
View File
@@ -0,0 +1,11 @@
{
"txid": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43",
"version": 1,
"size": 10,
"locktime": 0,
"vin": [
],
"vout": [
],
"hex": "01000000000000000000"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a914ce1c388c454d63b21ebb202010bda79a3b165b4b88ac0084d717000000001976a91414b70d03a3536907a7843f9d9243ddca79d43e3888ac00000000
+64
View File
@@ -0,0 +1,64 @@
{
"txid": "bf8ee16a00913c0bacbf86a75f2c00c595e8048724c9f0db9f09ed71fce3c946",
"version": 1,
"size": 201,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
},
{
"txid": "bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c",
"vout": 18,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
},
{
"txid": "22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 ce1c388c454d63b21ebb202010bda79a3b165b4b OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914ce1c388c454d63b21ebb202010bda79a3b165b4b88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"DPvuYbbib66zreC6HNNQgUKzF3jnMmxk71"
]
}
},
{
"value": 4.00,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 14b70d03a3536907a7843f9d9243ddca79d43e38 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a91414b70d03a3536907a7843f9d9243ddca79d43e3888ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"D72dLgywmL73JyTwQBfuU29CADz9yCJ99v"
]
}
}
],
"hex": "01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a914ce1c388c454d63b21ebb202010bda79a3b165b4b88ac0084d717000000001976a91414b70d03a3536907a7843f9d9243ddca79d43e3888ac00000000"
}
+1
View File
@@ -0,0 +1 @@
01000000000100000000000000000000000000
+20
View File
@@ -0,0 +1,20 @@
{
"txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13",
"version": 1,
"size": 19,
"locktime": 0,
"vin": [
],
"vout": [
{
"value": 0.00,
"n": 0,
"scriptPubKey": {
"asm": "",
"hex": "",
"type": "nonstandard"
}
}
],
"hex": "01000000000100000000000000000000000000"
}
+1
View File
@@ -0,0 +1 @@
0100000000010000000000000000017500000000
+20
View File
@@ -0,0 +1,20 @@
{
"txid": "f0851b68202f736b792649cfc960259c2374badcb644ab20cac726b5f72f61c9",
"version": 1,
"size": 20,
"locktime": 0,
"vin": [
],
"vout": [
{
"value": 0.00,
"n": 0,
"scriptPubKey": {
"asm": "OP_DROP",
"hex": "75",
"type": "nonstandard"
}
}
],
"hex": "0100000000010000000000000000017500000000"
}
+1
View File
@@ -0,0 +1 @@
01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a91414b70d03a3536907a7843f9d9243ddca79d43e3888ac00000000
+36
View File
@@ -0,0 +1,36 @@
{
"txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af",
"hash": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af",
"version": 1,
"size": 224,
"vsize": 224,
"weight": 896,
"locktime": 0,
"vin": [
{
"txid": "4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485",
"vout": 0,
"scriptSig": {
"asm": "304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e2[ALL] 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
"hex": "48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.00100000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"
]
}
}
],
"hex": "01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000"
}
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test share/rpcauth/rpcauth.py
"""
import base64
import configparser
import hmac
import importlib
import os
import sys
import unittest
class TestRPCAuth(unittest.TestCase):
def setUp(self):
config = configparser.ConfigParser()
config_path = os.path.abspath(
os.path.join(os.sep, os.path.abspath(os.path.dirname(__file__)),
"../config.ini"))
with open(config_path, encoding="utf8") as config_file:
config.read_file(config_file)
sys.path.insert(0, os.path.dirname(config['environment']['RPCAUTH']))
self.rpcauth = importlib.import_module('rpcauth')
def test_generate_salt(self):
self.assertLessEqual(len(self.rpcauth.generate_salt()), 32)
self.assertGreaterEqual(len(self.rpcauth.generate_salt()), 16)
def test_generate_password(self):
password = self.rpcauth.generate_password()
expected_password = base64.urlsafe_b64encode(
base64.urlsafe_b64decode(password)).decode('utf-8')
self.assertEqual(expected_password, password)
def test_check_password_hmac(self):
salt = self.rpcauth.generate_salt()
password = self.rpcauth.generate_password()
password_hmac = self.rpcauth.password_to_hmac(salt, password)
m = hmac.new(bytearray(salt, 'utf-8'),
bytearray(password, 'utf-8'), 'SHA256')
expected_password_hmac = m.hexdigest()
self.assertEqual(expected_password_hmac, password_hmac)
if __name__ == '__main__':
unittest.main()