From 5af151ac3136e74244682b3af44a6c0121875ce9 Mon Sep 17 00:00:00 2001 From: kriii Date: Fri, 27 May 2022 11:29:00 +0900 Subject: [PATCH 01/11] Admin node param APIs --- common/result-code.js | 16 ++-- json_rpc/admin.js | 178 +++++++++++++++++++++++++++++++----------- json_rpc/constants.js | 7 +- 3 files changed, 146 insertions(+), 55 deletions(-) diff --git a/common/result-code.js b/common/result-code.js index 4d768dc85..f1606edf5 100644 --- a/common/result-code.js +++ b/common/result-code.js @@ -173,15 +173,15 @@ const JsonRpcApiResultCode = { BATCH_TX_MISSING_PROPERTIES: 30404, BATCH_TX_INVALID_FORMAT: 30405, BATCH_TX_INVALID_SIGNATURE: 30406, - // ain_addToDevClientApiIpWhitelist - INVALID_IP: 30501, - IP_ALREADY_IN_WHITELIST: 30502, - // ain_removeFromDevClientApiIpWhitelist - IP_NOT_IN_WHITELIST: 30601, + // Admin APIs + PARAM_INVALID: 30501, + VALUE_INCOMPATIBLE: 30502, + ALREADY_IN_WHITELIST: 30503, + NOT_IN_WHITELIST: 30504, // ain_validateAppName - INVALID_APP_NAME_FOR_STATE_LABEL: 30701, - INVALID_APP_NAME_FOR_SERVICE_NAME: 30702, - APP_NAME_ALREADY_IN_USE: 30703, + INVALID_APP_NAME_FOR_STATE_LABEL: 30601, + INVALID_APP_NAME_FOR_SERVICE_NAME: 30602, + APP_NAME_ALREADY_IN_USE: 30603, }; /** diff --git a/json_rpc/admin.js b/json_rpc/admin.js index bb85bc7fb..325492434 100644 --- a/json_rpc/admin.js +++ b/json_rpc/admin.js @@ -1,4 +1,3 @@ -const net = require('net'); const _ = require('lodash'); const { NodeConfigs, @@ -10,124 +9,215 @@ const CommonUtil = require('../common/common-util'); const JsonRpcUtil = require('./json-rpc-util'); const { JSON_RPC_METHODS } = require('./constants'); -module.exports = function getApiAccessApis(node) { +function checkCompatibility(valueA, valueB) { + if (CommonUtil.isBool(valueA)) { + return CommonUtil.isBool(valueB); + } else if (CommonUtil.isIntegerString(valueA) || CommonUtil.isFloatString(valueA)) { + return CommonUtil.isIntegerString(valueB) || CommonUtil.isFloatString(valueB); + } else if (CommonUtil.isArray(valueA) || CommonUtil.isWildcard(valueA)) { + return CommonUtil.isArray(valueB) || CommonUtil.isWildcard(valueB); + } else { + // TODO(kriii): Decide how to work on the object (e.g. TRAFFIC_STATS_PERIOD_SECS_LIST). + return false; + } +} + +module.exports = function getAdminApis(node) { return { - [JSON_RPC_METHODS.AIN_GET_DEV_CLIENT_API_IP_WHITELIST]: function(args, done) { + [JSON_RPC_METHODS.AIN_GET_NODE_PARAM]: function(args, done) { const beginTime = Date.now(); const verified = node.verifyNodeAccountSignature(args.message, args.signature); + if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_GET_NODE_PARAM || !verified) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done({ code: 403, message: 'Forbidden' }); + return; + } + + const param = args.message.param; const latency = Date.now() - beginTime; - trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_GET, latency); - if (_.get(args.message, 'method') === JSON_RPC_METHODS.AIN_GET_DEV_CLIENT_API_IP_WHITELIST && - verified) { - done(null, - JsonRpcUtil.addProtocolVersion({ result: NodeConfigs.DEV_CLIENT_API_IP_WHITELIST })); + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + if (NodeConfigs[param] === undefined) { + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not exist.` + } + })); } else { - done({ code: 403, message: 'Forbidden' }); + done(null, JsonRpcUtil.addProtocolVersion({ result: NodeConfigs[param] })); } }, - [JSON_RPC_METHODS.AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST]: function(args, done) { + [JSON_RPC_METHODS.AIN_SET_NODE_PARAM]: function(args, done) { const beginTime = Date.now(); const verified = node.verifyNodeAccountSignature(args.message, args.signature); - if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST || - !verified) { + if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_SET_NODE_PARAM || !verified) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done({ code: 403, message: 'Forbidden' }); return; } - if (CommonUtil.isWildcard(args.message.ip)) { - NodeConfigs.DEV_CLIENT_API_IP_WHITELIST = '*'; + + const param = args.message.param; + if (NodeConfigs[param] === undefined) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.SUCCESS, - message: `Added IP (${args.message.ip}) to whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not exists.` } })); return; } - if (!net.isIPv4(args.message.ip)) { + + if (!checkCompatibility(NodeConfigs[param], args.message.value)) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.INVALID_IP, - message: `Invalid IP: ${args.message.ip}` + code: JsonRpcApiResultCode.VALUE_INCOMPATIBLE, + message: `(${args.message.value}) is incompatible with param [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); return; } - if (!CommonUtil.isArray(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)) { - // NOTE(liayoo): if the whitelist was "*" previously, adding an IP will no longer "allow-all". - NodeConfigs.DEV_CLIENT_API_IP_WHITELIST = []; + + NodeConfigs[param] = args.message.value; + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.SUCCESS, + message: `Param [${param}] is now set as: ${JSON.stringify(NodeConfigs[param])}` + } + })); + }, + + [JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM]: function(args, done) { + const beginTime = Date.now(); + const verified = node.verifyNodeAccountSignature(args.message, args.signature); + if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM || !verified) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done({ code: 403, message: 'Forbidden' }); + return; } - if (NodeConfigs.DEV_CLIENT_API_IP_WHITELIST.includes(args.message.ip)) { + + const param = args.message.param; + if (NodeConfigs[param] === undefined) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.IP_ALREADY_IN_WHITELIST, - message: `IP (${args.message.ip}) already in whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not exists.` } })); - } else { - NodeConfigs.DEV_CLIENT_API_IP_WHITELIST.push(args.message.ip); + return; + } + if (!CommonUtil.isArray(NodeConfigs[param]) && + !CommonUtil.isWildcard(NodeConfigs[param])) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not whitelist` + } + })); + return; + } + + if (!CommonUtil.isArray(NodeConfigs[param])) { + // NOTE(liayoo): if the whitelist was "*" previously, adding an IP will no longer "allow-all". + NodeConfigs[param] = []; + } + if (NodeConfigs[param].includes(args.message.value)) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.SUCCESS, - message: `Added IP (${args.message.ip}) to whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + code: JsonRpcApiResultCode.ALREADY_IN_WHITELIST, + message: `(${args.message.value}) already in whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); + return; } + + if (CommonUtil.isWildcard(args.message.value)) { + NodeConfigs[param] = '*'; + } else { + NodeConfigs[param].push(args.message.value); + } + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.SUCCESS, + message: `Added (${args.message.value}) to whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` + } + })); }, - [JSON_RPC_METHODS.AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST]: function(args, done) { + [JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM]: function(args, done) { const beginTime = Date.now(); const verified = node.verifyNodeAccountSignature(args.message, args.signature); - if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST || - !verified) { + if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM || !verified) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done({ code: 403, message: 'Forbidden' }); return; } - if (CommonUtil.isWildcard(args.message.ip) - && CommonUtil.isWildcard(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)) { - NodeConfigs.DEV_CLIENT_API_IP_WHITELIST = []; + + const param = args.message.param; + if (NodeConfigs[param] === undefined) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.SUCCESS, - message: `Removed IP (${args.message.ip}) from whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not exists.` } })); return; } - if (!CommonUtil.isArray(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST) || - !NodeConfigs.DEV_CLIENT_API_IP_WHITELIST.includes(args.message.ip)) { + if (!CommonUtil.isArray(NodeConfigs[param]) && + !CommonUtil.isWildcard(NodeConfigs[param])) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.IP_NOT_IN_WHITELIST, - message: `IP (${args.message.ip}) not in whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + code: JsonRpcApiResultCode.PARAM_INVALID, + message: `Param [${param}] is not whitelist` } })); return; } - NodeConfigs.DEV_CLIENT_API_IP_WHITELIST = NodeConfigs.DEV_CLIENT_API_IP_WHITELIST - .filter((ip) => ip !== args.message.ip); + + if (CommonUtil.isWildcard(args.message.value)) { + NodeConfigs[param] = []; + } else if (!CommonUtil.isArray(NodeConfigs[param]) || + !NodeConfigs[param].includes(args.message.value)) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.NOT_IN_WHITELIST, + message: `(${args.message.value}) not in whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` + } + })); + return; + } else { + NodeConfigs[param] = NodeConfigs[param].filter((value) => value !== args.message.value); + } const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { code: JsonRpcApiResultCode.SUCCESS, - message: `Removed IP (${args.message.ip}) from whitelist: ${JSON.stringify(NodeConfigs.DEV_CLIENT_API_IP_WHITELIST)}` + message: `Removed (${args.message.value}) from whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); }, diff --git a/json_rpc/constants.js b/json_rpc/constants.js index 6193ffd13..f3bc541c4 100644 --- a/json_rpc/constants.js +++ b/json_rpc/constants.js @@ -1,5 +1,5 @@ const JSON_RPC_METHODS = { - AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST: 'ain_addToDevClientApiIpWhitelist', + AIN_ADD_TO_WHITELIST_NODE_PARAM: 'ain_addToWhitelistNodeParam', AIN_CHECK_PROTOCOL_VERSION: 'ain_checkProtocolVersion', AIN_EVAL_RULE: 'ain_evalRule', AIN_EVAL_OWNER: 'ain_evalOwner', @@ -13,11 +13,11 @@ const JSON_RPC_METHODS = { AIN_GET_BLOCK_TRANSACTION_COUNT_BY_HASH: 'ain_getBlockTransactionCountByHash', AIN_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER: 'ain_getBlockTransactionCountByNumber', AIN_GET_BOOTSTRAP_PUB_KEY: 'ain_getBootstrapPubKey', - AIN_GET_DEV_CLIENT_API_IP_WHITELIST: 'ain_getDevClientApiIpWhitelist', AIN_GET_EVENT_HANDLER_CHANNEL_INFO: 'ain_getEventHandlerChannelInfo', AIN_GET_EVENT_HANDLER_FILTER_INFO: 'ain_getEventHandlerFilterInfo', AIN_GET_LAST_BLOCK: 'ain_getLastBlock', AIN_GET_LAST_BLOCK_NUMBER: 'ain_getLastBlockNumber', + AIN_GET_NODE_PARAM: 'ain_getNodeParam', AIN_GET_NONCE: 'ain_getNonce', AIN_GET_PENDING_TRANSACTIONS: 'ain_getPendingTransactions', AIN_GET_PROOF_HASH: 'ain_getProofHash', @@ -41,9 +41,10 @@ const JSON_RPC_METHODS = { AIN_MATCH_FUNCTION: 'ain_matchFunction', AIN_MATCH_OWNER: 'ain_matchOwner', AIN_MATCH_RULE: 'ain_matchRule', - AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST: 'ain_removeFromDevClientApiIpWhitelist', + AIN_REMOVE_FROM_WHITELIST_NODE_PARAM: 'ain_removeFromWhitelistNodeParam', AIN_SEND_SIGNED_TRANSACTION: 'ain_sendSignedTransaction', AIN_SEND_SIGNED_TRANSACTION_BATCH: 'ain_sendSignedTransactionBatch', + AIN_SET_NODE_PARAM: 'ain_setNodeParam', AIN_VALIDATE_APP_NAME: 'ain_validateAppName', NET_CONSENSUS_STATUS: 'net_consensusStatus', NET_GET_CHAIN_ID: 'net_getChainId', From 59c70bd96ca9657c69f9e73e1b152d56f528e430 Mon Sep 17 00:00:00 2001 From: kriii Date: Fri, 27 May 2022 11:29:10 +0900 Subject: [PATCH 02/11] Fix tools --- tools/api-access/addToDevClientApiIpWhitelist.js | 13 +++++++------ tools/api-access/getDevClientApiIpWhitelist.js | 6 ++++-- .../api-access/removeFromDevClientApiIpWhitelist.js | 13 +++++++------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tools/api-access/addToDevClientApiIpWhitelist.js b/tools/api-access/addToDevClientApiIpWhitelist.js index 1bfed6702..f75a2ee8b 100644 --- a/tools/api-access/addToDevClientApiIpWhitelist.js +++ b/tools/api-access/addToDevClientApiIpWhitelist.js @@ -9,14 +9,15 @@ const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); async function sendAddToDevClientApiIpWhitelistRequest(endpointUrl, privateKey, chainId, ip) { const message = { timestamp: Date.now(), - method: JSON_RPC_METHODS.AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST, - ip, + method: JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM, + param: 'DEV_CLIENT_API_IP_WHITELIST', + value: ip, }; const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); return await axios.post( `${endpointUrl}/json-rpc`, { - method: JSON_RPC_METHODS.AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST, + method: JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM, params: { protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, message, @@ -61,9 +62,9 @@ async function processArguments() { function usage() { console.log('\nUsage:\n node addToDevClientApiIpWhitelist.js [] \n'); console.log('\nExamples:'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); + console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); + console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); + console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); process.exit(0); } diff --git a/tools/api-access/getDevClientApiIpWhitelist.js b/tools/api-access/getDevClientApiIpWhitelist.js index f1277bdd7..7fb66a2f5 100644 --- a/tools/api-access/getDevClientApiIpWhitelist.js +++ b/tools/api-access/getDevClientApiIpWhitelist.js @@ -4,17 +4,19 @@ const ainUtil = require('@ainblockchain/ain-util'); const stringify = require('fast-json-stable-stringify'); const { BlockchainConsts } = require('../../common/constants'); const { getAccountPrivateKey } = require('./util'); +const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); async function sendGetDevClientApiIpWhitelistRequest(endpointUrl, privateKey, chainId) { const message = { timestamp: Date.now(), - method: 'ain_getDevClientApiIpWhitelist', + method: JSON_RPC_METHODS.AIN_GET_NODE_PARAM, + param: 'DEV_CLIENT_API_IP_WHITELIST', }; const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); return await axios.post( `${endpointUrl}/json-rpc`, { - method: 'ain_getDevClientApiIpWhitelist', + method: JSON_RPC_METHODS.AIN_GET_NODE_PARAM, params: { protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, message, diff --git a/tools/api-access/removeFromDevClientApiIpWhitelist.js b/tools/api-access/removeFromDevClientApiIpWhitelist.js index 031c3da90..d974eb6e0 100644 --- a/tools/api-access/removeFromDevClientApiIpWhitelist.js +++ b/tools/api-access/removeFromDevClientApiIpWhitelist.js @@ -9,14 +9,15 @@ const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); async function sendRemoveFromToDevClientApiIpWhitelistRequest(endpointUrl, privateKey, chainId, ip) { const message = { timestamp: Date.now(), - method: JSON_RPC_METHODS.AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST, - ip, + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, + param: 'DEV_CLIENT_API_IP_WHITELIST', + value: ip, }; const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); return await axios.post( `${endpointUrl}/json-rpc`, { - method: JSON_RPC_METHODS.AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST, + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, params: { protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, message, @@ -61,9 +62,9 @@ async function processArguments() { function usage() { console.log('\nUsage:\n node removeFromDevClientApiIpWhitelist.js [] \n'); console.log('\nExamples:'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); + console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); + console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); + console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); process.exit(0); } From da411352cd1a28a9faa3e25de589cdc08116f578 Mon Sep 17 00:00:00 2001 From: kriii Date: Fri, 27 May 2022 23:19:43 +0900 Subject: [PATCH 03/11] Fix integration tests --- test/unit/db.test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/unit/db.test.js b/test/unit/db.test.js index cf1e19b56..c13487af9 100644 --- a/test/unit/db.test.js +++ b/test/unit/db.test.js @@ -6303,7 +6303,7 @@ describe("Util methods", () => { const appName = 'app/path'; assert.deepEqual(node.db.validateAppName(appName, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30701, + "code": 30601, "message": `Invalid app name for state label: ${appName}`, }); }); @@ -6315,7 +6315,7 @@ describe("Util methods", () => { } assert.deepEqual(node.db.validateAppName(appName, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30701, + "code": 30601, "message": `Invalid app name for state label: ${appName}`, }); }); @@ -6324,7 +6324,7 @@ describe("Util methods", () => { const appName = 'balance_total_sum'; assert.deepEqual(node.db.validateAppName(appName, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30702, + "code": 30602, "message": `Invalid app name for service name: ${appName}`, }); }); @@ -6333,21 +6333,21 @@ describe("Util methods", () => { const appName = 'appName'; assert.deepEqual(node.db.validateAppName(appName, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30702, + "code": 30602, "message": `Invalid app name for service name: ${appName}`, }); const appName2 = 'app-name'; assert.deepEqual(node.db.validateAppName(appName2, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30702, + "code": 30602, "message": `Invalid app name for service name: ${appName2}`, }); const appName3 = '0app'; assert.deepEqual(node.db.validateAppName(appName3, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30702, + "code": 30602, "message": `Invalid app name for service name: ${appName3}`, }); }); @@ -6355,7 +6355,7 @@ describe("Util methods", () => { it("app name in use", () => { assert.deepEqual(node.db.validateAppName(appNameInUse, 2, stateLabelLengthLimit), { "is_valid": false, - "code": 30703, + "code": 30603, "message": `App name already in use: ${appNameInUse}`, }); }); From ce3348664e4844c94f795a45b591a92be49a9b38 Mon Sep 17 00:00:00 2001 From: kriii Date: Fri, 27 May 2022 23:20:01 +0900 Subject: [PATCH 04/11] Fix json prc set method set --- json_rpc/constants.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/json_rpc/constants.js b/json_rpc/constants.js index f3bc541c4..73e8fd99b 100644 --- a/json_rpc/constants.js +++ b/json_rpc/constants.js @@ -58,13 +58,14 @@ const JSON_RPC_METHODS = { } const JSON_RPC_SET_METHOD_SET = new Set([ - JSON_RPC_METHODS.AIN_ADD_TO_DEV_CLIENT_API_IP_WHITELIST, + JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM, JSON_RPC_METHODS.AIN_INJECT_ACCOUNT_FROM_HD_WALLET, JSON_RPC_METHODS.AIN_INJECT_ACCOUNT_FROM_KEYSTORE, JSON_RPC_METHODS.AIN_INJECT_ACCOUNT_FROM_PRIVATE_KEY, - JSON_RPC_METHODS.AIN_REMOVE_FROM_DEV_CLIENT_API_IP_WHITELIST, + JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, JSON_RPC_METHODS.AIN_SEND_SIGNED_TRANSACTION, - JSON_RPC_METHODS.AIN_SEND_SIGNED_TRANSACTION_BATCH + JSON_RPC_METHODS.AIN_SEND_SIGNED_TRANSACTION_BATCH, + JSON_RPC_METHODS.AIN_SET_NODE_PARAM ]); module.exports = { From 9cea149f5faeed7619fb1a1c0c240ec37e4cdfcb Mon Sep 17 00:00:00 2001 From: kriii Date: Mon, 30 May 2022 10:19:25 +0900 Subject: [PATCH 05/11] Fix results --- common/result-code.js | 9 +++---- json_rpc/admin.js | 55 +++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/common/result-code.js b/common/result-code.js index f1606edf5..b79639312 100644 --- a/common/result-code.js +++ b/common/result-code.js @@ -174,10 +174,11 @@ const JsonRpcApiResultCode = { BATCH_TX_INVALID_FORMAT: 30405, BATCH_TX_INVALID_SIGNATURE: 30406, // Admin APIs - PARAM_INVALID: 30501, - VALUE_INCOMPATIBLE: 30502, - ALREADY_IN_WHITELIST: 30503, - NOT_IN_WHITELIST: 30504, + ADMIN_FORBIDDEN_REQUEST: 30501, + ADMIN_PARAM_INVALID: 30502, + ADMIN_VALUE_INCOMPATIBLE: 30503, + ADMIN_ALREADY_IN_WHITELIST: 30504, + ADMIN_NOT_IN_WHITELIST: 30505, // ain_validateAppName INVALID_APP_NAME_FOR_STATE_LABEL: 30601, INVALID_APP_NAME_FOR_SERVICE_NAME: 30602, diff --git a/json_rpc/admin.js b/json_rpc/admin.js index 325492434..c220a82c9 100644 --- a/json_rpc/admin.js +++ b/json_rpc/admin.js @@ -29,19 +29,24 @@ module.exports = function getAdminApis(node) { const verified = node.verifyNodeAccountSignature(args.message, args.signature); if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_GET_NODE_PARAM || !verified) { const latency = Date.now() - beginTime; - trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); - done({ code: 403, message: 'Forbidden' }); + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_GET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.ADMIN_FORBIDDEN_REQUEST, + message: `Forbidden request.` + } + })); return; } const param = args.message.param; const latency = Date.now() - beginTime; - trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_GET, latency); if (NodeConfigs[param] === undefined) { done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not exist.` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] does not exist.` } })); } else { @@ -55,7 +60,12 @@ module.exports = function getAdminApis(node) { if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_SET_NODE_PARAM || !verified) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); - done({ code: 403, message: 'Forbidden' }); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.ADMIN_FORBIDDEN_REQUEST, + message: `Forbidden request.` + } + })); return; } @@ -65,8 +75,8 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not exists.` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] does not exists.` } })); return; @@ -77,7 +87,7 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.VALUE_INCOMPATIBLE, + code: JsonRpcApiResultCode.ADMIN_VALUE_INCOMPATIBLE, message: `(${args.message.value}) is incompatible with param [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); @@ -101,7 +111,12 @@ module.exports = function getAdminApis(node) { if (_.get(args.message, 'method') !== JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM || !verified) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); - done({ code: 403, message: 'Forbidden' }); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.ADMIN_FORBIDDEN_REQUEST, + message: `Forbidden request.` + } + })); return; } @@ -111,8 +126,8 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not exists.` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] does not exists.` } })); return; @@ -123,8 +138,8 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not whitelist` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] is not a whitelist` } })); return; @@ -139,7 +154,7 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.ALREADY_IN_WHITELIST, + code: JsonRpcApiResultCode.ADMIN_ALREADY_IN_WHITELIST, message: `(${args.message.value}) already in whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); @@ -177,8 +192,8 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not exists.` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] does not exists.` } })); return; @@ -189,8 +204,8 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.PARAM_INVALID, - message: `Param [${param}] is not whitelist` + code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, + message: `Param [${param}] is not a whitelist` } })); return; @@ -204,7 +219,7 @@ module.exports = function getAdminApis(node) { trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.NOT_IN_WHITELIST, + code: JsonRpcApiResultCode.ADMIN_NOT_IN_WHITELIST, message: `(${args.message.value}) not in whitelist [${param}]: ${JSON.stringify(NodeConfigs[param])}` } })); From a1611e674c857d43dcc0da94f8dbbab18f7cadd9 Mon Sep 17 00:00:00 2001 From: kriii Date: Mon, 30 May 2022 10:38:19 +0900 Subject: [PATCH 06/11] Add wildcard example for tools --- tools/api-access/addToDevClientApiIpWhitelist.js | 1 + tools/api-access/getDevClientApiIpWhitelist.js | 1 + tools/api-access/removeFromDevClientApiIpWhitelist.js | 1 + 3 files changed, 3 insertions(+) diff --git a/tools/api-access/addToDevClientApiIpWhitelist.js b/tools/api-access/addToDevClientApiIpWhitelist.js index f75a2ee8b..f2e64e7a3 100644 --- a/tools/api-access/addToDevClientApiIpWhitelist.js +++ b/tools/api-access/addToDevClientApiIpWhitelist.js @@ -65,6 +65,7 @@ function usage() { console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); + console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file "*"'); process.exit(0); } diff --git a/tools/api-access/getDevClientApiIpWhitelist.js b/tools/api-access/getDevClientApiIpWhitelist.js index 7fb66a2f5..afcf1589b 100644 --- a/tools/api-access/getDevClientApiIpWhitelist.js +++ b/tools/api-access/getDevClientApiIpWhitelist.js @@ -53,6 +53,7 @@ function usage() { console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 private_key'); console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic'); console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file'); + console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore "*"'); process.exit(0); } diff --git a/tools/api-access/removeFromDevClientApiIpWhitelist.js b/tools/api-access/removeFromDevClientApiIpWhitelist.js index d974eb6e0..e23252f12 100644 --- a/tools/api-access/removeFromDevClientApiIpWhitelist.js +++ b/tools/api-access/removeFromDevClientApiIpWhitelist.js @@ -65,6 +65,7 @@ function usage() { console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); + console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file "*"'); process.exit(0); } From bb9dad0531b0cc69ba4c882b4fa24fe0a5e16d0d Mon Sep 17 00:00:00 2001 From: kriii Date: Tue, 31 May 2022 02:02:47 +0900 Subject: [PATCH 07/11] Change set methods value handling as like evironment variable-ish --- common/result-code.js | 2 +- json_rpc/admin.js | 49 +++++++++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/common/result-code.js b/common/result-code.js index b79639312..f2cad530b 100644 --- a/common/result-code.js +++ b/common/result-code.js @@ -176,7 +176,7 @@ const JsonRpcApiResultCode = { // Admin APIs ADMIN_FORBIDDEN_REQUEST: 30501, ADMIN_PARAM_INVALID: 30502, - ADMIN_VALUE_INCOMPATIBLE: 30503, + ADMIN_VALUE_NOT_A_STRING_TYPE: 30503, ADMIN_ALREADY_IN_WHITELIST: 30504, ADMIN_NOT_IN_WHITELIST: 30505, // ain_validateAppName diff --git a/json_rpc/admin.js b/json_rpc/admin.js index c220a82c9..90aa7f14a 100644 --- a/json_rpc/admin.js +++ b/json_rpc/admin.js @@ -9,16 +9,15 @@ const CommonUtil = require('../common/common-util'); const JsonRpcUtil = require('./json-rpc-util'); const { JSON_RPC_METHODS } = require('./constants'); -function checkCompatibility(valueA, valueB) { - if (CommonUtil.isBool(valueA)) { - return CommonUtil.isBool(valueB); - } else if (CommonUtil.isIntegerString(valueA) || CommonUtil.isFloatString(valueA)) { - return CommonUtil.isIntegerString(valueB) || CommonUtil.isFloatString(valueB); - } else if (CommonUtil.isArray(valueA) || CommonUtil.isWildcard(valueA)) { - return CommonUtil.isArray(valueB) || CommonUtil.isWildcard(valueB); +function convertValue(valueFromNodeParam, value) { + if (CommonUtil.isBool(valueFromNodeParam)) { + return CommonUtil.convertEnvVarInputToBool(value); + } else if (CommonUtil.isIntegerString(valueFromNodeParam) || CommonUtil.isFloatString(valueFromNodeParam)) { + return Number(value); + } else if (CommonUtil.isArray(valueFromNodeParam) || CommonUtil.isWildcard(valueFromNodeParam)) { + return CommonUtil.getWhitelistFromString(value); } else { - // TODO(kriii): Decide how to work on the object (e.g. TRAFFIC_STATS_PERIOD_SECS_LIST). - return false; + return value; } } @@ -82,19 +81,19 @@ module.exports = function getAdminApis(node) { return; } - if (!checkCompatibility(NodeConfigs[param], args.message.value)) { + if (!CommonUtil.isString(args.message.value)) { const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ result: { - code: JsonRpcApiResultCode.ADMIN_VALUE_INCOMPATIBLE, - message: `(${args.message.value}) is incompatible with param [${param}]: ${JSON.stringify(NodeConfigs[param])}` + code: JsonRpcApiResultCode.ADMIN_VALUE_NOT_A_STRING_TYPE, + message: `(${args.message.value}) is not a string type.)}` } })); return; } - NodeConfigs[param] = args.message.value; + NodeConfigs[param] = convertValue(NodeConfigs[param], args.message.value); const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({ @@ -145,6 +144,18 @@ module.exports = function getAdminApis(node) { return; } + if (!CommonUtil.isString(args.message.value)) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.ADMIN_VALUE_NOT_A_STRING_TYPE, + message: `(${args.message.value}) is not a string type.)}` + } + })); + return; + } + if (!CommonUtil.isArray(NodeConfigs[param])) { // NOTE(liayoo): if the whitelist was "*" previously, adding an IP will no longer "allow-all". NodeConfigs[param] = []; @@ -211,6 +222,18 @@ module.exports = function getAdminApis(node) { return; } + if (!CommonUtil.isString(args.message.value)) { + const latency = Date.now() - beginTime; + trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); + done(null, JsonRpcUtil.addProtocolVersion({ + result: { + code: JsonRpcApiResultCode.ADMIN_VALUE_NOT_A_STRING_TYPE, + message: `(${args.message.value}) is not a string type.)}` + } + })); + return; + } + if (CommonUtil.isWildcard(args.message.value)) { NodeConfigs[param] = []; } else if (!CommonUtil.isArray(NodeConfigs[param]) || From 5d140ef9729c29970d487d26e5583c728abe5507 Mon Sep 17 00:00:00 2001 From: kriii Date: Tue, 31 May 2022 02:03:10 +0900 Subject: [PATCH 08/11] Fix tool usages --- tools/api-access/addToDevClientApiIpWhitelist.js | 1 - tools/api-access/getDevClientApiIpWhitelist.js | 1 - tools/api-access/removeFromDevClientApiIpWhitelist.js | 1 - 3 files changed, 3 deletions(-) diff --git a/tools/api-access/addToDevClientApiIpWhitelist.js b/tools/api-access/addToDevClientApiIpWhitelist.js index f2e64e7a3..281e1a9cd 100644 --- a/tools/api-access/addToDevClientApiIpWhitelist.js +++ b/tools/api-access/addToDevClientApiIpWhitelist.js @@ -64,7 +64,6 @@ function usage() { console.log('\nExamples:'); console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); - console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); console.log('node tools/api-access/addToDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file "*"'); process.exit(0); } diff --git a/tools/api-access/getDevClientApiIpWhitelist.js b/tools/api-access/getDevClientApiIpWhitelist.js index afcf1589b..7fb66a2f5 100644 --- a/tools/api-access/getDevClientApiIpWhitelist.js +++ b/tools/api-access/getDevClientApiIpWhitelist.js @@ -53,7 +53,6 @@ function usage() { console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 private_key'); console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic'); console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file'); - console.log('node tools/api-access/getDevClientApiIpWhitelist.js http://localhost:8081 0 keystore "*"'); process.exit(0); } diff --git a/tools/api-access/removeFromDevClientApiIpWhitelist.js b/tools/api-access/removeFromDevClientApiIpWhitelist.js index e23252f12..275c34b74 100644 --- a/tools/api-access/removeFromDevClientApiIpWhitelist.js +++ b/tools/api-access/removeFromDevClientApiIpWhitelist.js @@ -64,7 +64,6 @@ function usage() { console.log('\nExamples:'); console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 private_key 127.0.0.1'); console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 mnemonic 127.0.0.1'); - console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file 127.0.0.1'); console.log('node tools/api-access/removeFromDevClientApiIpWhitelist.js http://localhost:8081 0 keystore /path/to/keystore/file "*"'); process.exit(0); } From b02b08de1af9dd453e402c112018a42a7eea20fb Mon Sep 17 00:00:00 2001 From: kriii Date: Tue, 31 May 2022 02:03:28 +0900 Subject: [PATCH 09/11] Add tools for new APIs --- tools/api-access/addToWhiteListNodeParam.js | 74 +++++++++++++++++++ tools/api-access/getNodeParam.js | 66 +++++++++++++++++ .../removeFromWhitelistNodeParam.js | 74 +++++++++++++++++++ tools/api-access/setNodeParam.js | 74 +++++++++++++++++++ 4 files changed, 288 insertions(+) create mode 100644 tools/api-access/addToWhiteListNodeParam.js create mode 100644 tools/api-access/getNodeParam.js create mode 100644 tools/api-access/removeFromWhitelistNodeParam.js create mode 100644 tools/api-access/setNodeParam.js diff --git a/tools/api-access/addToWhiteListNodeParam.js b/tools/api-access/addToWhiteListNodeParam.js new file mode 100644 index 000000000..0a824d64c --- /dev/null +++ b/tools/api-access/addToWhiteListNodeParam.js @@ -0,0 +1,74 @@ +const axios = require('axios'); +const _ = require('lodash'); +const ainUtil = require('@ainblockchain/ain-util'); +const stringify = require('fast-json-stable-stringify'); +const { BlockchainConsts } = require('../../common/constants'); +const { getAccountPrivateKey } = require('./util'); +const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); + +async function sendAddToWhiteListNodeParamRequest(endpointUrl, privateKey, chainId, param, value) { + const message = { + timestamp: Date.now(), + method: JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM, + param, + value, + }; + const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); + return await axios.post( + `${endpointUrl}/json-rpc`, + { + method: JSON_RPC_METHODS.AIN_ADD_TO_WHITELIST_NODE_PARAM, + params: { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + message, + signature, + }, + jsonrpc: '2.0', + id: 0 + } + ).then(function(resp) { + return _.get(resp, 'data.result.result'); + }); +} + +async function addToWhiteListNodeParam(endpointUrl, chainId, type, keystoreFilePath, param, value) { + const privateKey = await getAccountPrivateKey(type, keystoreFilePath); + const res = await sendAddToWhiteListNodeParamRequest(endpointUrl, privateKey, chainId, param, value); + console.log('Result:', res); +} + +async function processArguments() { + if (process.argv.length !== 7 && process.argv.length !== 8) { + usage(); + } + const endpointUrl = process.argv[2]; + const chainId = Number(process.argv[3]); + const accountType = process.argv[4]; + let keystoreFilePath = null; + let param = null; + let value = null; + if (accountType === 'keystore') { + keystoreFilePath = process.argv[5]; + param = process.argv[6]; + value = process.argv[7]; + } else { + param = process.argv[5]; + value = process.argv[6]; + } + if (!value) { + console.error('Please specify a value'); + usage(); + } + await addToWhiteListNodeParam(endpointUrl, chainId, accountType, keystoreFilePath, param, value); +} + +function usage() { + console.log('\nUsage:\n node addToWhiteListNodeParam.js [] \n'); + console.log('\nExamples:'); + console.log('node tools/api-access/addToWhiteListNodeParam.js http://localhost:8081 0 private_key DEV_CLIENT_API_IP_WHITELIST 127.0.0.1'); + console.log('node tools/api-access/addToWhiteListNodeParam.js http://localhost:8081 0 mnemonic DEV_CLIENT_API_IP_WHITELIST "*"'); + console.log('node tools/api-access/addToWhiteListNodeParam.js http://localhost:8081 0 keystore /path/to/kezystore/file CORS_WHITELIST "https://ainetwork\\.ai"'); + process.exit(0); +} + +processArguments(); diff --git a/tools/api-access/getNodeParam.js b/tools/api-access/getNodeParam.js new file mode 100644 index 000000000..44e026ac2 --- /dev/null +++ b/tools/api-access/getNodeParam.js @@ -0,0 +1,66 @@ +const axios = require('axios'); +const _ = require('lodash'); +const ainUtil = require('@ainblockchain/ain-util'); +const stringify = require('fast-json-stable-stringify'); +const { BlockchainConsts } = require('../../common/constants'); +const { getAccountPrivateKey } = require('./util'); +const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); + +async function sendGetNodeParamRequest(endpointUrl, privateKey, chainId, param) { + const message = { + timestamp: Date.now(), + method: JSON_RPC_METHODS.AIN_GET_NODE_PARAM, + param, + }; + const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); + return await axios.post( + `${endpointUrl}/json-rpc`, + { + method: JSON_RPC_METHODS.AIN_GET_NODE_PARAM, + params: { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + message, + signature, + }, + jsonrpc: '2.0', + id: 0 + } + ).then(function(resp) { + return _.get(resp, 'data.result.result'); + }); +} + +async function getNodeParam(endpointUrl, chainId, type, keystoreFilePath, param) { + const privateKey = await getAccountPrivateKey(type, keystoreFilePath); + const res = await sendGetNodeParamRequest(endpointUrl, privateKey, chainId, param); + console.log('Result:', res); +} + +async function processArguments() { + if (process.argv.length !== 6 && process.argv.length !== 7) { + usage(); + } + const endpointUrl = process.argv[2]; + const chainId = Number(process.argv[3]); + const accountType = process.argv[4]; + let keystoreFilePath = null; + let param = null; + if (accountType === 'keystore') { + keystoreFilePath = process.argv[5]; + param = process.argv[6]; + } else { + param = process.argv[5]; + } + await getNodeParam(endpointUrl, chainId, accountType, keystoreFilePath, param); +} + +function usage() { + console.log('\nUsage:\n node getNodeParam.js [] \n'); + console.log('\nExamples:'); + console.log('node tools/api-access/getNodeParam.js http://localhost:8081 0 private_key DEV_CLIENT_API_IP_WHITELIST'); + console.log('node tools/api-access/getNodeParam.js http://localhost:8081 0 mnemonic P2P_MESSAGE_TIMEOUT_MS'); + console.log('node tools/api-access/getNodeParam.js http://localhost:8081 0 keystore /path/to/keystore/file SYNC_MODE'); + process.exit(0); +} + +processArguments(); diff --git a/tools/api-access/removeFromWhitelistNodeParam.js b/tools/api-access/removeFromWhitelistNodeParam.js new file mode 100644 index 000000000..042a5f9dc --- /dev/null +++ b/tools/api-access/removeFromWhitelistNodeParam.js @@ -0,0 +1,74 @@ +const axios = require('axios'); +const _ = require('lodash'); +const ainUtil = require('@ainblockchain/ain-util'); +const stringify = require('fast-json-stable-stringify'); +const { BlockchainConsts } = require('../../common/constants'); +const { getAccountPrivateKey } = require('./util'); +const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); + +async function sendRemoveFromWhiteListNodeParamRequest(endpointUrl, privateKey, chainId, param, value) { + const message = { + timestamp: Date.now(), + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, + param, + value, + }; + const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); + return await axios.post( + `${endpointUrl}/json-rpc`, + { + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, + params: { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + message, + signature, + }, + jsonrpc: '2.0', + id: 0 + } + ).then(function(resp) { + return _.get(resp, 'data.result.result'); + }); +} + +async function removeFromWhiteListNodeParam(endpointUrl, chainId, type, keystoreFilePath, param, value) { + const privateKey = await getAccountPrivateKey(type, keystoreFilePath); + const res = await sendRemoveFromWhiteListNodeParamRequest(endpointUrl, privateKey, chainId, param, value); + console.log('Result:', res); +} + +async function processArguments() { + if (process.argv.length !== 7 && process.argv.length !== 8) { + usage(); + } + const endpointUrl = process.argv[2]; + const chainId = Number(process.argv[3]); + const accountType = process.argv[4]; + let keystoreFilePath = null; + let param = null; + let value = null; + if (accountType === 'keystore') { + keystoreFilePath = process.argv[5]; + param = process.argv[6]; + value = process.argv[7]; + } else { + param = process.argv[5]; + value = process.argv[6]; + } + if (!value) { + console.error('Please specify a value'); + usage(); + } + await removeFromWhiteListNodeParam(endpointUrl, chainId, accountType, keystoreFilePath, param, value); +} + +function usage() { + console.log('\nUsage:\n node removeFromWhiteListNodeParam.js [] \n'); + console.log('\nExamples:'); + console.log('node tools/api-access/removeFromWhiteListNodeParam.js http://localhost:8081 0 private_key DEV_CLIENT_API_IP_WHITELIST 127.0.0.1'); + console.log('node tools/api-access/removeFromWhiteListNodeParam.js http://localhost:8081 0 mnemonic DEV_CLIENT_API_IP_WHITELIST "*"'); + console.log('node tools/api-access/removeFromWhiteListNodeParam.js http://localhost:8081 0 keystore /path/to/kezystore/file CORS_WHITELIST "https://ainetwork\\.ai"'); + process.exit(0); +} + +processArguments(); diff --git a/tools/api-access/setNodeParam.js b/tools/api-access/setNodeParam.js new file mode 100644 index 000000000..5424a5b47 --- /dev/null +++ b/tools/api-access/setNodeParam.js @@ -0,0 +1,74 @@ +const axios = require('axios'); +const _ = require('lodash'); +const ainUtil = require('@ainblockchain/ain-util'); +const stringify = require('fast-json-stable-stringify'); +const { BlockchainConsts } = require('../../common/constants'); +const { getAccountPrivateKey } = require('./util'); +const { JSON_RPC_METHODS } = require('../../json_rpc/constants'); + +async function sendSetNodeParamRequest(endpointUrl, privateKey, chainId, param, value) { + const message = { + timestamp: Date.now(), + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, + param, + value, + }; + const signature = ainUtil.ecSignMessage(stringify(message), Buffer.from(privateKey, 'hex'), chainId); + return await axios.post( + `${endpointUrl}/json-rpc`, + { + method: JSON_RPC_METHODS.AIN_REMOVE_FROM_WHITELIST_NODE_PARAM, + params: { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + message, + signature, + }, + jsonrpc: '2.0', + id: 0 + } + ).then(function(resp) { + return _.get(resp, 'data.result.result'); + }); +} + +async function setNodeParam(endpointUrl, chainId, type, keystoreFilePath, param, value) { + const privateKey = await getAccountPrivateKey(type, keystoreFilePath); + const res = await sendSetNodeParamRequest(endpointUrl, privateKey, chainId, param, value); + console.log('Result:', res); +} + +async function processArguments() { + if (process.argv.length !== 7 && process.argv.length !== 8) { + usage(); + } + const endpointUrl = process.argv[2]; + const chainId = Number(process.argv[3]); + const accountType = process.argv[4]; + let keystoreFilePath = null; + let param = null; + let value = null; + if (accountType === 'keystore') { + keystoreFilePath = process.argv[5]; + param = process.argv[6]; + value = process.argv[7]; + } else { + param = process.argv[5]; + value = process.argv[6]; + } + if (!value) { + console.error('Please specify a value'); + usage(); + } + await setNodeParam(endpointUrl, chainId, accountType, keystoreFilePath, param, value); +} + +function usage() { + console.log('\nUsage:\n node setNodeParam.js [] \n'); + console.log('\nExamples:'); + console.log('node tools/api-access/setNodeParam.js http://localhost:8081 0 private_key DEV_CLIENT_API_IP_WHITELIST "*"'); + console.log('node tools/api-access/setNodeParam.js http://localhost:8081 0 mnemonic P2P_MESSAGE_TIMEOUT_MS 200000'); + console.log('node tools/api-access/setNodeParam.js http://localhost:8081 0 keystore /path/to/kezystore/file SYNC_MODE peer'); + process.exit(0); +} + +processArguments(); From 43434cdcc7ed5c98c280051da7ddeadeba4b590c Mon Sep 17 00:00:00 2001 From: kriii Date: Tue, 31 May 2022 11:38:22 +0900 Subject: [PATCH 10/11] Fix typo --- json_rpc/admin.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json_rpc/admin.js b/json_rpc/admin.js index 90aa7f14a..b1636fcb6 100644 --- a/json_rpc/admin.js +++ b/json_rpc/admin.js @@ -75,7 +75,7 @@ module.exports = function getAdminApis(node) { done(null, JsonRpcUtil.addProtocolVersion({ result: { code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, - message: `Param [${param}] does not exists.` + message: `Param [${param}] does not exist.` } })); return; @@ -126,7 +126,7 @@ module.exports = function getAdminApis(node) { done(null, JsonRpcUtil.addProtocolVersion({ result: { code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, - message: `Param [${param}] does not exists.` + message: `Param [${param}] does not exist.` } })); return; @@ -204,7 +204,7 @@ module.exports = function getAdminApis(node) { done(null, JsonRpcUtil.addProtocolVersion({ result: { code: JsonRpcApiResultCode.ADMIN_PARAM_INVALID, - message: `Param [${param}] does not exists.` + message: `Param [${param}] does not exist.` } })); return; From cea30fd8874e1189124dcf546c2eb37a89fa6664 Mon Sep 17 00:00:00 2001 From: kriii Date: Tue, 31 May 2022 12:38:45 +0900 Subject: [PATCH 11/11] Add TODO --- json_rpc/admin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/json_rpc/admin.js b/json_rpc/admin.js index b1636fcb6..716ac5907 100644 --- a/json_rpc/admin.js +++ b/json_rpc/admin.js @@ -94,6 +94,7 @@ module.exports = function getAdminApis(node) { } NodeConfigs[param] = convertValue(NodeConfigs[param], args.message.value); + // TODO(kriii): Add a refresher for some params. const latency = Date.now() - beginTime; trafficStatsManager.addEvent(TrafficEventTypes.ACCESS_CONTROL_SET, latency); done(null, JsonRpcUtil.addProtocolVersion({