Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: refactor: reducing codebase by reusing existing solutions #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 0 additions & 64 deletions proof-data-provider/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -885,70 +885,6 @@ async function checkParamsUtype2(params) {

inputErrors.utype2 = checkParamsUtype2;

// Function for checking input params for method getProofByKey
async function checkParamsGp1(params) {
const result = {
error: false,
message: null
};
// check if the params have only two keys
if (Object.keys(params).length > 2) {
result.error = true;
result.message =
'Object "params" should have only two properties - "index" and "key".';
return result;
}
// check if the keys of params are index and key (can be improved with more detailed messages)
if (
!Object.prototype.hasOwnProperty.call(params, "index") ||
!Object.prototype.hasOwnProperty.call(params, "key")
) {
result.error = true;
result.message =
'There is no required properties "index" and/or "key" in object "params".';
return result;
}
// check data types of params keys
if (typeof params.index !== "number" || typeof params.key !== "string") {
if (typeof params.index === "number") {
result.error = true;
result.message = 'Invalid data type of "key". Must be a string.';
return result;
}
result.error = true;
result.message = 'Invalid data type of "index". Must be a number.';
return result;
}
// check if the item by input's index exist
const item = await managerDB.getItemByIndex(params.index);
if (!item) {
result.error = true;
result.message = `Invalid index. There is no tree with such ${params.index} index.`;
return result;
}

// check key value
const { depth } = item;
const maxnumber = BigInt(2 ** depth) - BigInt(1);

let bN;
try {
bN = BigInt(params.key);
} catch (e) {
result.error = true;
result.message = `This "${params.key}" key is not a number.`;
return result;
}
if (bN > maxnumber) {
result.error = true;
result.message = `This "${params.key}" key is out of range of the tree's depth.`;
return result;
}
return result;
}

inputErrors.gp1 = checkParamsGp1;

// Function for checking params for method getProofByKeys
async function checkParamsGp2(params) {
const result = {
Expand Down
62 changes: 62 additions & 0 deletions proof-data-provider/methods/getProofByKey.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const SmtLib = require("../helpers/SmtLib.js");
const managerDB = require("../db.js");
const { paramsSchema, validate, error } = require("./utils");

const schema = paramsSchema("getProofByKey", {
index: { type: "number", required: true },
key: { type: "string", required: true }
});

/**
* Option1. Function for getting one proof for one key.
* @function getProofByKey
* @param {Object} [params] Parameters from the request that was send by client(user)
* @param {Number} [params.index] The index of the existing item (tree), that user got when created a tree into provider's database.
* @param {String} [params.key] The sparse merkle tree's key(path) that proof is required.
* Key must be a number in a range of depth's amount of bits.
* @return {String} Returns a proof for the key in input as the result.
*/
// Example:
/*
let params = {
index: 1575009568558,
key : "0x77111aaabbbcccdddeeeeffff000002222233333"
}
*/
const handler = async params => {
const validationError = validate(schema, params);
if (validationError) return validationError;

const item = await managerDB.getItemByIndex(params.index);
if (!item) {
return error(
`Invalid index. There is no tree with such ${params.index} index.`
);
}

// check key value
const { depth } = item;
const maxnumber = BigInt(2 ** depth) - BigInt(1);

let bN;
try {
bN = BigInt(params.key);
} catch (e) {
return error(`This "${params.key}" key is not a number.`);
}

if (bN > maxnumber) {
return error(
`This "${params.key}" key is out of range of the tree's depth.`
);
}

if (item.config) {
await autoUpdate(params.index);
}
const tree = new SmtLib(item.depth, item.leaves);
const proof = tree.createMerkleProof(params.key);
return proof;
};

module.exports = handler;
33 changes: 33 additions & 0 deletions proof-data-provider/methods/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const Validator = require("jsonschema").Validator;
const validator = new Validator();

const paramsSchema = (name, properties) => {
const paramsSchemaId = `/${name}Params`;
const paramsSchema = {
id: paramsSchemaId,
type: "object",
properties: properties
};
return paramsSchema;
};

const error = (message) => ({
code: -32602,
message: "Invalid params",
data: message,
});

const validate = (schema, params) => {
const res = validator.validate(params, schema);
if (res.valid) return;

return {
code: -32602,
message: "Invalid params",
data: res.errors.map(
e => `parameter '${e.property.replace("instance.", "")}' ${e.message}`
)
};
};

module.exports = { validate, error, paramsSchema };
1 change: 1 addition & 0 deletions proof-data-provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"ethereumjs-util": "^6.2.0",
"jayson": "^3.2.0",
"jsbi": "^3.1.1",
"jsonschema": "^1.2.5",
"web3": "^1.2.4"
},
"devDependencies": {
Expand Down
154 changes: 24 additions & 130 deletions proof-data-provider/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,137 +3,31 @@ const config = require("config");
const jayson = require("jayson/promise");
const { errorHandler, methodHandler } = require("./handler_jayson");

const server = jayson.server({
addTreeManually: params => {
const error = errorHandler("ctype1", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("addTreeManually", params);
resolve(result);
});
});
},

addTreeFromContract: params => {
const error = errorHandler("ctype2", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
// server.error just returns {code: 32602, message: 'Internal error', data: 'specific input error'}
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("addTreeFromContract", params);
resolve(result);
});
});
},
updateTreeManually: params => {
const error = errorHandler("utype1", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("updateTreeManually", params);
resolve(result);
});
});
},
const checkAndCall = (methodName, errorHandlerName, params) => {
const error = errorHandler(errorHandlerName, params);
return error.then(err => {
if (err != null) {
return Promise.reject(server.error(err.code, err.message, err.data));
}
return Promise.resolve(methodHandler(methodName, params));
});
};

extraUpdateTreeFromContract: params => {
const error = errorHandler("utype2", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("extraUpdateTreeFromContract", params);
resolve(result);
});
});
},

getProofByKey: params => {
const error = errorHandler("gp1", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("getProofByKey", params);
resolve(result);
});
});
},
getProofByKeys: params => {
const error = errorHandler("gp2", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("getProofByKeys", params);
resolve(result);
});
});
},
getProofByKeyWithCondition: params => {
const error = errorHandler("gp3", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("getProofByKeyWithCondition", params);
resolve(result);
});
});
},
getProofByKeysWithCondition: params => {
const error = errorHandler("gp4", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("getProofByKeysWithCondition", params);
resolve(result);
});
});
},
getRoot: params => {
const error = errorHandler("gR", params);
return error.then(err => {
if (err != null) {
return new Promise((resolve, reject) => {
reject(server.error(err.code, err.message, err.data));
});
}
return new Promise(resolve => {
const result = methodHandler("getRoot", params);
resolve(result);
});
});
}
const server = jayson.server({
addTreeManually: params => checkAndCall("addTreeManually", "ctype1", params),
addTreeFromContract: params =>
checkAndCall("addTreeFromContract", "ctype2", params),
updateTreeManually: params =>
checkAndCall("updateTreeManually", "utype1", params),
extraUpdateTreeFromContract: params =>
checkAndCall("extraUpdateTreeFromContract", "utype2", params),
getProofByKey: async params => await require("./methods/getProofByKey")(params),
getProofByKeys: params => checkAndCall("getProofByKeys", "gp2", params),
getProofByKeyWithCondition: params =>
checkAndCall("getProofByKeyWithCondition", "gp3", params),
getProofByKeysWithCondition: params =>
checkAndCall("getProofByKeysWithCondition", "gp4", params),
getRoot: params => checkAndCall("getRoot", "gR", params)
});

server.http().listen(config.get("endpoint.options.port"));
5 changes: 5 additions & 0 deletions proof-data-provider/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2014,6 +2014,11 @@ jsonparse@^1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=

jsonschema@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.5.tgz#bab69d97fa28946aec0a56a9cc266d23fe80ae61"
integrity sha512-kVTF+08x25PQ0CjuVc0gRM9EUPb0Fe9Ln/utFOgcdxEIOHuU7ooBk/UPTd7t1M91pP35m0MU1T8M5P7vP1bRRw==

jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
Expand Down