aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoichi Hirai <i@yoichihirai.com>2017-08-23 01:03:11 +0800
committerGitHub <noreply@github.com>2017-08-23 01:03:11 +0800
commit3c8e613c12a363b570fb8453c5955f5a0699b863 (patch)
tree79d40b8b8902d96325a706aaacc77243a70d9e45
parent76c6d463525f21dcded3bd62176934901f118012 (diff)
parent28ccaf0bbd9d02cb63095da08feedd927021622d (diff)
downloaddexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar.gz
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar.bz2
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar.lz
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar.xz
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.tar.zst
dexon-tests-3c8e613c12a363b570fb8453c5955f5a0699b863.zip
Merge pull request #213 from jwasinger/issue-204
JSON schema for state tests
-rw-r--r--.travis.yml9
-rw-r--r--JSONSchema/filler-schema.json268
-rw-r--r--JSONSchema/schema.json339
-rwxr-xr-xJSONSchema/validate.js73
4 files changed, 688 insertions, 1 deletions
diff --git a/.travis.yml b/.travis.yml
index dbced1cd9..d9d7c58fb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,15 @@
language: python
-python: 2.7
+python:
+ - "2.7"
+node_js:
+ - "8"
sudo: false
+install: "npm install jsonschema"
script:
# won't fail, but print problems
- find . -name "*.json" -not -name "*Filler.json" -exec echo {} \; -exec python -mjson.tool {} /dev/null \; 2>&1 | grep -v -B 1 "^\./" | cat
# will fail, if linting fails
- find . -name "*.json" -not -name "*Filler.json" -print0 | xargs -I file -n1 -0 python -mjson.tool file /dev/null
+# run schema tests against GeneralStateTests
+- echo -e "$(find GeneralStateTests -name '*.json')" | node JSONSchema/validate.js JSONSchema/schema.json
+- echo -e "$(find src/GeneralStateTestsFiller -name '*.json')" | node JSONSchema/validate.js JSONSchema/filler-schema.json \ No newline at end of file
diff --git a/JSONSchema/filler-schema.json b/JSONSchema/filler-schema.json
new file mode 100644
index 000000000..da9f2fea6
--- /dev/null
+++ b/JSONSchema/filler-schema.json
@@ -0,0 +1,268 @@
+{
+ "definitions": {
+ "EmptyString": {
+ "type": "string",
+ "pattern": "^$"
+ },
+ "HexData": {
+ "description": "Hex data. see https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding",
+ "pattern": "^0x([0-9a-fA-F][0-9a-fA-F])*$",
+ "type": "string"
+ },
+ "HexQuantity": {
+ "description": "Hex quantity. see https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding",
+ "pattern": "(^0x0$)|(^0x[1-9a-fA-F][0-9a-fA-F]*$)",
+ "type": "string"
+ },
+ "ConfusedHexType": {
+ "anyOf": [
+ { "$ref": "#/definitions/HexData" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "HexDataOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexData" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "HexNoPrefix" : {
+ "pattern": "^([0-9a-fA-F][0-9a-fA-F])+$",
+ "type": "string"
+ },
+ "HexMaybePrefix": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexNoPrefix" },
+ { "$ref": "#/definitions/HexData" }
+ ]
+ },
+ "HexMaybePrefixOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexMaybePrefix" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "IntegerString": {
+ "pattern": "^[0-9]+$",
+ "type": "string"
+ },
+ "IntegerOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "IntegerOrNumber": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "type": "number" }
+ ]
+ },
+ "IntegerOrNumberOrConfusedHex": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrNumber" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "IntegerOrEmptyOrHexQuantity": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrEmpty" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "IntegerOrHexQuantity": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "IntegerOrConfusedHex": {
+ "anyOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "IntegerOrEmptyOrConfusedHex": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrEmpty" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "PreStateAccount": {
+ "type": "object",
+ "additionalproperties": true,
+ "properties": {
+ "balance": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "code": { "type": "string" },
+ "nonce": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "storage": {
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^0x[0-9a-f]+": {
+ "description": "storage key with 0x prefix, just the prefix `0x` is null and thus not permitted, a hex quantity is permitted. for the storage value, only hex data is permitted.",
+ "$ref": "#/definitions/HexData"
+ }
+ }
+ }
+ },
+ "required": [
+ "balance",
+ "code",
+ "nonce"
+ ]
+ },
+ "TxSigR": {
+ "oneOf": [
+ { "enum" : [ "0" ] }
+ ]
+ },
+ "TxSigS": {
+ "oneOf": [
+ { "enum" : [ "0" ] }
+ ]
+ },
+ "TxSigV": {
+ "description": "a value of 0 is an invalid chainId, but used in a test case",
+ "oneOf": [
+ { "enum" : [ "0", "1" ] }
+ ]
+ },
+ "HexLen40": {
+ "pattern": "^0x[0-9a-fA-F]{40}$",
+ "type": "string"
+ },
+ "HexNoPrefixLen40": {
+ "pattern": "^[0-9a-fA-F]{40}$",
+ "type": "string"
+ },
+ "AddressMaybePrefixOrEmpty" : {
+ "oneOf": [
+ { "$ref": "#/definitions/HexLen40" },
+ { "$ref": "#/definitions/HexNoPrefixLen40" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "Transaction": {
+ "type": "object",
+ "additionalProperties": true,
+ "not": {
+ "required": ["r, s, v"]
+ },
+ "properties": {
+ "data": {
+ "items": { "$ref": "#/definitions/HexDataOrEmpty" },
+ "type": "array"
+ },
+ "gasLimit": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ },
+ "gasPrice": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "nonce": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "secretKey": { "$ref": "#/definitions/HexMaybePrefix" },
+ "to": { "$ref": "#/definitions/AddressMaybePrefixOrEmpty"},
+ "value": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ }
+ },
+ "required": [
+ "data",
+ "gasLimit",
+ "gasPrice",
+ "nonce",
+ "secretKey",
+ "to",
+ "value"
+ ]
+ },
+ "NullSenderTransaction": {
+ "type": "object",
+ "additionalProperties": true,
+ "not": {
+ "required": ["secretKey"]
+ },
+ "properties": {
+ "data": {
+ "items": { "$ref": "#/definitions/HexMaybePrefixOrEmpty" },
+ "type": "array"
+ },
+ "gasLimit": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ },
+ "gasPrice": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "nonce": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "r": { "$ref": "#/definitions/TxSigR" },
+ "s": { "$ref": "#/definitions/TxSigS" },
+ "to": { "$ref": "#/definitions/AddressMaybePrefixOrEmpty"},
+ "v": { "$ref": "#/definitions/TxSigV" },
+ "value": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ }
+ },
+ "required": [
+ "data",
+ "gasLimit",
+ "gasPrice",
+ "nonce",
+ "r",
+ "s",
+ "v",
+ "to",
+ "value"
+ ]
+ }
+ },
+ "patternProperties": {
+ "^.*$": {
+ "properties": {
+ "env": {
+ "additionalproperties": false,
+ "properties": {
+ "currentCoinbase": { "$ref": "#/definitions/HexMaybePrefix" },
+ "currentDifficulty": { "$ref": "#/definitions/IntegerOrConfusedHex" },
+ "currentGasLimit": { "$ref": "#/definitions/IntegerOrConfusedHex" },
+ "currentNumber": { "$ref": "#/definitions/IntegerOrConfusedHex" },
+ "currentTimestamp": { "$ref": "#/definitions/IntegerOrNumberOrConfusedHex" },
+ "previousHash": { "$ref": "#/definitions/HexMaybePrefix" }
+ },
+ "required": [
+ "currentCoinbase",
+ "currentDifficulty",
+ "currentGasLimit",
+ "currentNumber",
+ "currentTimestamp",
+ "previousHash"
+ ],
+ "type": "object"
+ },
+ "expect": {},
+ "pre": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[0-9a-fA-F]{40}": {
+ "description": "filler prestate addresses without 0x prefix",
+ "$ref": "#/definitions/PreStateAccount"
+ },
+ "^0x[0-9a-fA-F]{40}": {
+ "description": "filler prestate addresses with 0x prefix",
+ "$ref": "#/definitions/PreStateAccount"
+ }
+ },
+ "type": "object"
+ },
+ "transaction": {
+ "oneOf": [
+ { "$ref": "#/definitions/Transaction" },
+ { "$ref": "#/definitions/NullSenderTransaction" }
+ ]
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+}
diff --git a/JSONSchema/schema.json b/JSONSchema/schema.json
new file mode 100644
index 000000000..7b1536dae
--- /dev/null
+++ b/JSONSchema/schema.json
@@ -0,0 +1,339 @@
+{
+ "definitions": {
+ "EmptyString": {
+ "type": "string",
+ "pattern": "^$"
+ },
+ "HexData": {
+ "description": "Hex data. see https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding",
+ "pattern": "^0x([0-9a-fA-F][0-9a-fA-F])*$",
+ "type": "string"
+ },
+ "HexQuantity": {
+ "description": "Hex quantity. see https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding",
+ "pattern": "(^0x0$)|(^0x[1-9a-fA-F][0-9a-fA-F]*$)",
+ "type": "string"
+ },
+ "ConfusedHexType": {
+ "anyOf": [
+ { "$ref": "#/definitions/HexData" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "HexDataOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexData" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "HexNoPrefix" : {
+ "pattern": "^([0-9a-fA-F][0-9a-fA-F])+$",
+ "type": "string"
+ },
+ "HexMaybePrefix": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexNoPrefix" },
+ { "$ref": "#/definitions/HexData" }
+ ]
+ },
+ "HexMaybePrefixOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/HexMaybePrefix" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "IntegerString": {
+ "pattern": "^[0-9]+$",
+ "type": "string"
+ },
+ "IntegerOrEmpty": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "IntegerOrNumber": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "type": "number" }
+ ]
+ },
+ "IntegerOrNumberOrConfusedHex": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrNumber" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "IntegerOrEmptyOrHexQuantity": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrEmpty" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "IntegerOrHexQuantity": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/HexQuantity" }
+ ]
+ },
+ "IntegerOrConfusedHex": {
+ "anyOf": [
+ { "$ref": "#/definitions/IntegerString" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "IntegerOrEmptyOrConfusedHex": {
+ "oneOf": [
+ { "$ref": "#/definitions/IntegerOrEmpty" },
+ { "$ref": "#/definitions/ConfusedHexType" }
+ ]
+ },
+ "PreStateAccount": {
+ "type": "object",
+ "additionalproperties": true,
+ "properties": {
+ "balance": { "$ref": "#/definitions/ConfusedHexType" },
+ "code": { "$ref": "#/definitions/HexMaybePrefixOrEmpty" },
+ "nonce": { "$ref": "#/definitions/ConfusedHexType" },
+ "storage": {
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^0x[0-9a-f]+": {
+ "description": "storage key with 0x. data is HexData",
+ "$ref": "#/definitions/HexData"
+ }
+ }
+ }
+ },
+ "required": [
+ "balance",
+ "code",
+ "nonce"
+ ]
+ },
+ "TxSigR": {
+ "oneOf": [
+ { "enum" : [ "0x00" ] }
+ ]
+ },
+ "TxSigS": {
+ "oneOf": [
+ { "enum" : [ "0x00" ] }
+ ]
+ },
+ "TxSigV": {
+ "description": "a value of 0 is an invalid chainId, but used in a test case",
+ "oneOf": [
+ { "enum" : [ "0x00", "0x01" ] }
+ ]
+ },
+ "HexLen40": {
+ "pattern": "^0x[0-9a-fA-F]{40}$",
+ "type": "string"
+ },
+ "HexNoPrefixLen40": {
+ "pattern": "^[0-9a-fA-F]{40}$",
+ "type": "string"
+ },
+ "AddressMaybePrefixOrEmpty" : {
+ "oneOf": [
+ { "$ref": "#/definitions/HexLen40" },
+ { "$ref": "#/definitions/HexNoPrefixLen40" },
+ { "$ref": "#/definitions/EmptyString" }
+ ]
+ },
+ "Transaction": {
+ "type": "object",
+ "additionalProperties": true,
+ "not": {
+ "required": ["r, s, v"]
+ },
+ "properties": {
+ "data": {
+ "items": { "$ref": "#/definitions/HexDataOrEmpty" },
+ "type": "array"
+ },
+ "gasLimit": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ },
+ "gasPrice": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "nonce": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "secretKey": { "$ref": "#/definitions/HexMaybePrefix" },
+ "to": { "$ref": "#/definitions/AddressMaybePrefixOrEmpty"},
+ "value": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ }
+ },
+ "required": [
+ "data",
+ "gasLimit",
+ "gasPrice",
+ "nonce",
+ "secretKey",
+ "to",
+ "value"
+ ]
+ },
+ "NullSenderTransaction": {
+ "type": "object",
+ "additionalProperties": true,
+ "not": {
+ "required": ["secretKey"]
+ },
+ "properties": {
+ "data": {
+ "items": { "$ref": "#/definitions/HexMaybePrefixOrEmpty" },
+ "type": "array"
+ },
+ "gasLimit": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ },
+ "gasPrice": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "nonce": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "r": { "$ref": "#/definitions/TxSigR" },
+ "s": { "$ref": "#/definitions/TxSigS" },
+ "to": { "$ref": "#/definitions/AddressMaybePrefixOrEmpty"},
+ "v": { "$ref": "#/definitions/TxSigV" },
+ "value": {
+ "items": { "$ref": "#/definitions/IntegerOrEmptyOrConfusedHex" },
+ "type": "array"
+ }
+ },
+ "required": [
+ "data",
+ "gasLimit",
+ "gasPrice",
+ "nonce",
+ "r",
+ "s",
+ "v",
+ "to",
+ "value"
+ ]
+ },
+ "TransactionResults": {
+ "items": {
+ "additionalProperties": false,
+ "properties": {
+ "hash": {
+ "$ref": "#/definitions/HexData"
+ },
+ "logs": {},
+ "indexes": {
+ "additionalProperties": false,
+ "properties": {
+ "data": {
+ "type": "integer"
+ },
+ "gas": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "data",
+ "gas",
+ "value"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "hash",
+ "indexes"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "patternProperties": {
+ "^.*$": {
+ "properties": {
+ "env": {
+ "additionalproperties": false,
+ "properties": {
+ "currentCoinbase": {
+ "$ref": "#/definitions/HexData"
+ },
+ "currentDifficulty": {
+ "$ref": "#/definitions/ConfusedHexType"
+ },
+ "currentGasLimit": {
+ "$ref": "#/definitions/ConfusedHexType"
+ },
+ "currentNumber": {
+ "$ref": "#/definitions/ConfusedHexType"
+ },
+ "currentTimestamp": {
+ "$ref": "#/definitions/ConfusedHexType"
+ },
+ "previousHash": {
+ "$ref": "#/definitions/HexData"
+ }
+ },
+ "required": [
+ "currentCoinbase",
+ "currentDifficulty",
+ "currentGasLimit",
+ "currentNumber",
+ "currentTimestamp",
+ "previousHash"
+ ],
+ "type": "object"
+ },
+ "explanation": {
+ "type": "string"
+ },
+ "post": {
+ "additionalProperties": false,
+ "properties": {
+ "EIP150": {
+ "$ref": "#/definitions/TransactionResults"
+ },
+ "EIP158": {
+ "$ref": "#/definitions/TransactionResults"
+ },
+ "Frontier": {
+ "$ref": "#/definitions/TransactionResults"
+ },
+ "Homestead": {
+ "$ref": "#/definitions/TransactionResults"
+ },
+ "Byzantium": {
+ "$ref": "#/definitions/TransactionResults"
+ },
+ "Constantinople": {
+ "$ref": "#/definitions/TransactionResults"
+ }
+ },
+ "type": "object"
+ },
+ "pre": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^0x[0-9a-f]*": {
+ "description": "prestate account address with 0x prefix",
+ "$ref": "#/definitions/PreStateAccount"
+ }
+ },
+ "type": "object"
+ },
+ "transaction": {
+ "oneOf": [
+ { "$ref": "#/definitions/Transaction" },
+ { "$ref": "#/definitions/NullSenderTransaction" }
+ ]
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+}
diff --git a/JSONSchema/validate.js b/JSONSchema/validate.js
new file mode 100755
index 000000000..1a1a605db
--- /dev/null
+++ b/JSONSchema/validate.js
@@ -0,0 +1,73 @@
+#! /bin/env node
+
+var fs = require('fs');
+var validate = require('jsonschema').validate;
+var readline = require('readline');
+
+var schemaFile = process.argv[2];
+var schema = '';
+var testCode = '';
+var success = true;
+var numFiles = 0;
+var numFailed = 0;
+var numSucceeded = 0;
+var fileNames = [];
+
+var rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ terminal: false
+});
+
+rl.on('line', function(line) {
+ fileNames.push(line);
+});
+
+rl.on('close', function() {
+ schema = JSON.parse(fs.readFileSync(schemaFile));
+
+ //sort file names alphabetically so that log output ordering is consistent
+ fileNames.sort(function(a,b) {
+ if(a<b) {
+ return -1;
+ } else {
+ return 1;
+ }
+
+ return 0;
+ });
+
+ for (var i = 0; i < fileNames.length; i++) {
+ try {
+ testCode = JSON.parse(fs.readFileSync(fileNames[i]));
+ } catch(e) {
+ console.log('error on file:', fileNames[i])
+ console.log(e);
+ numFailed++;
+ }
+
+ try {
+ var x = validate(testCode, schema);
+
+ if (x.errors.length > 0) {
+ numFailed++;
+ console.log(fileNames[i]+ ':\n');
+ for (var j = 0; j < x.errors.length; j++) {
+ console.log(' ' + x.errors[j] + '\n')
+ }
+ } else {
+ numSucceeded++;
+ }
+ } catch (e) {
+ console.log(e);
+ numFailed++;
+ }
+ }
+
+ console.log("Valid: "+numSucceeded+"\n");
+ console.log("Failed: "+numFailed+"\n");
+
+ if(numFailed > 0) {
+ process.exit(-1);
+ }
+});