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

Added validation for invalid command and params #175

Merged
merged 21 commits into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
13 changes: 11 additions & 2 deletions src/Directory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ export default class Directory {
}

return path.join(
Directory.projectRoot,
'chains',
Directory.getProjectChainsDirectory,
originChain,
auxiliaryChainId,
);
Expand Down Expand Up @@ -162,6 +161,16 @@ export default class Directory {
);
}

/**
* This method return project chains directory.
*/
public static get getProjectChainsDirectory(): string {
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
return path.join(
Directory.projectRoot,
'chains',
);
}

/**
* Returns the full path of GatewayConfig for a given origin, auxiliary and gatewayAddress.
*
Expand Down
15 changes: 10 additions & 5 deletions src/NewChain/AuxiliaryChainInteract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ export default class AuxiliaryChainInteract {
constructor(
private initConfig: InitConfig,
private chainId: string,
private originChainId: string,
private originChain: string,
private nodeDescription: NodeDescription,
) {
this.chainDir = path.join(nodeDescription.mosaicDir, originChainId, this.chainId);
this.chainDir = path.join(nodeDescription.mosaicDir, originChain, this.chainId);
}

/**
Expand Down Expand Up @@ -163,6 +163,8 @@ export default class AuxiliaryChainInteract {
* lock for the origin stake.
* @param proofData The proof data of the origin stake. Will be used to proof the stake against an
* available origin state root on auxiliary.
* @param originChainId Chain ID of origin chain is used to set remote chain Id in anchor.
* It's required because originChain in the constructor can be a string like ropsten.
*/
public async initializeContracts(
originOstGatewayAddress: string,
Expand All @@ -171,6 +173,7 @@ export default class AuxiliaryChainInteract {
stakeMessageNonce: string,
hashLockSecret: string,
proofData: Proof,
originChainId?: string,
): Promise<{
anchorOrganization: ContractInteract.Organization;
anchor: ContractInteract.Anchor;
Expand All @@ -194,6 +197,7 @@ export default class AuxiliaryChainInteract {
originOstGatewayAddress,
originHeight,
originStateRoot,
originChainId,
);

await this.transferAllOstIntoOstPrime(ostPrime.address);
Expand Down Expand Up @@ -482,6 +486,7 @@ export default class AuxiliaryChainInteract {
originOstGatewayAddress: string,
originHeight: string,
originStateRoot: string,
originChainId?: string,
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
): Promise<{
anchorOrganization: ContractInteract.Organization;
anchor: ContractInteract.Anchor;
Expand All @@ -503,7 +508,7 @@ export default class AuxiliaryChainInteract {
this.anchorOrganizationDeploymentNonce,
);
const anchor = await this.deployAnchor(
this.originChainId,
originChainId || this.originChain,
originHeight,
originStateRoot,
anchorOrganization.address,
Expand Down Expand Up @@ -652,7 +657,7 @@ export default class AuxiliaryChainInteract {
* to connect.
*/
private copyStateToChainsDir(): void {
fs.ensureDirSync(Directory.getProjectUtilityChainDir(this.originChainId, this.chainId));
fs.ensureDirSync(Directory.getProjectUtilityChainDir(this.originChain, this.chainId));

this.copy('geth');
this.copy('genesis.json');
Expand All @@ -664,7 +669,7 @@ export default class AuxiliaryChainInteract {
private copy(file: string): void {
const source: string = path.join(this.chainDir, file);
const destination: string = path.join(
Directory.getProjectUtilityChainDir(this.originChainId, this.chainId),
Directory.getProjectUtilityChainDir(this.originChain, this.chainId),
file,
);
this.logInfo('copying chains state to utility chains directory', { source, destination });
Expand Down
4 changes: 3 additions & 1 deletion src/NewChain/ChainVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import MosaicConfig, { ContractAddresses } from '../Config/MosaicConfig';
import Logger from '../Logger';

import Web3 = require('web3');
import BN = require('bn.js');

/**
* Chain verifier does verification of newly created auxiliary chains.
Expand Down Expand Up @@ -340,7 +341,8 @@ export default class ChainVerifier {
);

const remoteChainId = await anchorInstance.methods.getRemoteChainId().call();
if (remoteChainId !== this.mosaicConfig.originChain.chain) {
const originChainId = await this.originWeb3.eth.net.getId();
if (!new BN(remoteChainId).eq(new BN(originChainId))) {
const errMsg = 'AuxiliaryAnchor: Invalid remoteChainId!!!';
Logger.error(errMsg);
throw new Error(errMsg);
Expand Down
5 changes: 4 additions & 1 deletion src/NewChain/Initialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export default class Initialization {
);
Logger.info('Origin contracts deployed');
const originContracts = auxiliaryChain.contractAddresses.origin;
originContracts.baseTokenAddress = Utils.toChecksumAddress(mosaicConfig.originChain.contractAddresses.valueTokenAddress)
originContracts.baseTokenAddress = Utils.toChecksumAddress(mosaicConfig.originChain.contractAddresses.valueTokenAddress);
originContracts.anchorOrganizationAddress = Utils.toChecksumAddress(originAnchorOrganization.address);
originContracts.anchorAddress = Utils.toChecksumAddress(originAnchor.address);
originContracts.gatewayOrganizationAddress = Utils.toChecksumAddress(ostGatewayOrganization.address);
Expand Down Expand Up @@ -179,6 +179,8 @@ export default class Initialization {
Logger.info('Generated Proof for Stake & mint');

Logger.info('Deploying auxiliary contract.');
// Origin chain Id is used to set remote chain while deploying anchor.
const originChainId = (await (originChainInteract.getWeb3().eth.net.getId())).toString();
const {
anchorOrganization: auxiliaryAnchorOrganization,
anchor: auxiliaryAnchor,
Expand All @@ -195,6 +197,7 @@ export default class Initialization {
stakeMessageNonce,
hashLockSecret,
proofData,
originChainId,
);

await Initialization.setCoAnchors(
Expand Down
8 changes: 5 additions & 3 deletions src/Node/ChainInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ export const PARITY_CLIENT = 'parity';
* Builds node based on the given chain id.
*/
export default class ChainInfo {

/**
* array of supported origin chains.
*/
public static get chainsSupportedByParity(): string[] {
return [
'ethereum',
'ropsten',
'goerli'
'goerli',
];
}

Expand Down Expand Up @@ -76,7 +75,10 @@ export default class ChainInfo {
* @param chain Chain name.
*/
public static isDevChain(chain: string): boolean {
return (ChainInfo.devChainInfo[chain] !== undefined);
const setOfChain = new Set(
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
[...Object.keys(ChainInfo.devChainInfo),
...Object.values(ChainInfo.devChainInfo)]);
return setOfChain.has(chain);
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Node/GethNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ export default class GethNode extends Node {
return [
'--testnet',
'--bootnodes',
'enode://a60baadd908740e1fed9690ec399db6cbec47244acecd845a3585ec560f89d9ab96400004412b4dbf59c4e56758824e606ded5be97376ffc012a62869877f9af@155.138.211.79:30303,' +
'enode://3869e363263a54cd930960d485338a7ef1b5b6cd61a4484c81b31f48a2b68200783472a2e7f89c31a86f087e377050720a91cfa82903bd8d45456b6a5e0ffe5f@54.149.176.240:30303,' +
'enode://24cabc9618a4bd4ef3ccfb124b885ddfc352b87bd9f30c4f98f4791b6e81d58824f2c8b451bbdbac25a1b6311b9e12e50775ee49cdb1847c3132b4abfa7842c2@54.39.102.3:30302,' +
'enode://eecaf5852a9f0973d20fd9cb20b480ab0e47fe4a53a2395394e8fe618e8c9e5cb058fd749bf8f0b8483d7dc14c2948e18433490f7dd6182455e3f046d2225a8c@52.221.19.47:30303'
'enode://a60baadd908740e1fed9690ec399db6cbec47244acecd845a3585ec560f89d9ab96400004412b4dbf59c4e56758824e606ded5be97376ffc012a62869877f9af@155.138.211.79:30303,'
+ 'enode://3869e363263a54cd930960d485338a7ef1b5b6cd61a4484c81b31f48a2b68200783472a2e7f89c31a86f087e377050720a91cfa82903bd8d45456b6a5e0ffe5f@54.149.176.240:30303,'
+ 'enode://24cabc9618a4bd4ef3ccfb124b885ddfc352b87bd9f30c4f98f4791b6e81d58824f2c8b451bbdbac25a1b6311b9e12e50775ee49cdb1847c3132b4abfa7842c2@54.39.102.3:30302,'
+ 'enode://eecaf5852a9f0973d20fd9cb20b480ab0e47fe4a53a2395394e8fe618e8c9e5cb058fd749bf8f0b8483d7dc14c2948e18433490f7dd6182455e3f046d2225a8c@52.221.19.47:30303',
];
case 'ethereum':
return ['--networkid', '1'];
Expand Down
76 changes: 76 additions & 0 deletions src/bin/Validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as web3Utils from 'web3-utils';
import * as fs from 'fs';
import * as path from 'path';
import ChainInfo from '../Node/ChainInfo';
import Directory from '../Directory';
import MosaicConfig from '../Config/MosaicConfig';

import Web3 = require('web3');

/**
* This class contains methods to validate commandline arguments.
*/
export default class Validator {
/**
* This method validates an ethereum address.
* @param value Ethereum address.
*/
public static isValidAddress(value: string): boolean {
return web3Utils.isAddress(value);
}

/**
* This method validates an origin chain.
* @param value Chain identifier.
*/
public static isValidOriginChain(value: string): boolean {
return !!ChainInfo.publicOriginChainNameToIdMap[value] || ChainInfo.isDevChain(value);
}

/**
* This method validates an aux chain.
* @param auxChain Chain identifier.
* @param originChainId Origin chain identifier.
*/
public static isValidAuxChain(auxChain: string, originChainId: string): boolean {
if (MosaicConfig.exists(originChainId)) {
const mosaicConfig = MosaicConfig.fromChain(originChainId);
if (mosaicConfig.auxiliaryChains[auxChain]) {
return true;
}
}
if (ChainInfo.isDevChain(auxChain)) {
return true;
}
let validAuxChain = false;
const chainDir = Directory.getProjectChainsDirectory;
const originChainDirectories = Validator.getDirectories(chainDir);
originChainDirectories.forEach((originChain) => {
const auxDirectory = Directory.getProjectUtilityChainDir(originChain, auxChain);
if (fs.existsSync(auxDirectory)) {
validAuxChain = true;
}
});
return validAuxChain;
}

public static async isValidWeb3EndPoint(web3EndPoint: string): Promise<boolean> {
const web3 = new Web3(web3EndPoint);
// https://web3js.readthedocs.io/en/v1.2.0/web3-net.html#islistening
return web3.eth.net.isListening();
}

/**
* This function returns directories inside a folder.
* @param folderPath Path of folder.
*/
private static getDirectories(folderPath) {
return fs.readdirSync(folderPath)
.map(file => ({
fullPath: path.join(folderPath, file),
name: file,
}))
.filter(dir => fs.statSync(dir.fullPath).isDirectory())
.map(dir => dir.name);
}
}
8 changes: 2 additions & 6 deletions src/bin/mosaic-attach.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import Shell from '../Shell';
import Node from '../Node/Node';
import NodeFactory from '../Node/NodeFactory';
import NodeDescription from '../Node/NodeDescription';
import DevChainOptions from './DevChainOptions';

mosaic
.arguments('<chain>')
// Chain can't be validated as origin chain id is not received for aux chain.
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
.action((chain: string) => {
let chainInput = chain;
if (DevChainOptions.isDevChain(chain)) {
chainInput = DevChainOptions.getDevChainParams(chain).chain;
}
const node: Node = NodeFactory.create(new NodeDescription(chainInput));
const node: Node = NodeFactory.create(new NodeDescription(chain));

const args = [
'run',
Expand Down
5 changes: 5 additions & 0 deletions src/bin/mosaic-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Initialization from '../NewChain/Initialization';
import NodeOptions from './NodeOptions';
import NodeDescription from '../Node/NodeDescription';
import Directory from '../Directory';
import Validator from './Validator';

let mosaic = commander
.arguments('<new-chain-id> <origin-websocket> <password-file>');
Expand All @@ -17,6 +18,10 @@ mosaic.action(
passwordFile: string,
options,
) => {
const isValidWeb3Connection = await Validator.isValidWeb3EndPoint(originWebsocket);
if (!isValidWeb3Connection) {
Logger.error('Could not connect to origin node with web3');
}
const nodeOptions: NodeOptions = NodeOptions.parseOptions(options, newChainId);
if (nodeOptions.originChain === '') {
Logger.error('Unknown origin, please provide --origin');
Expand Down
14 changes: 14 additions & 0 deletions src/bin/mosaic-libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import OriginChainInteract from '../NewChain/OriginChainInteract';
import MosaicConfig from '../Config/MosaicConfig';
import PublishMosaicConfig from '../Config/PublishMosaicConfig';
import Utils from '../Utils';
import Validator from './Validator';

import Web3 = require('web3');

Expand All @@ -18,6 +19,19 @@ mosaic.action(
originWebsocket: string,
deployer: string,
) => {
const isValidWeb3Connection = await Validator.isValidWeb3EndPoint(originWebsocket);
if (!isValidWeb3Connection) {
Logger.error('Could not connect to origin node with web3');
}

if (!Validator.isValidOriginChain(chain)) {
Logger.error(`Invalid origin chain identifier: ${chain}`);
process.exit(1);
}
if (!Validator.isValidAddress(deployer)) {
Logger.error(`Invalid deployer address: ${deployer}`);
process.exit(1);
}
try {
// Publishes mosaic configs for existing chains
PublishMosaicConfig.tryPublish(chain);
Expand Down
8 changes: 2 additions & 6 deletions src/bin/mosaic-logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import Shell from '../Shell';
import Node from '../Node/Node';
import NodeDescription from '../Node/NodeDescription';
import NodeFactory from '../Node/NodeFactory';
import DevChainOptions from './DevChainOptions';

mosaic
.arguments('<chain>')
.action((chain: string) => {
let chainInput = chain;
if (DevChainOptions.isDevChain(chain)) {
chainInput = DevChainOptions.getDevChainParams(chain).chain;
}
const node: Node = NodeFactory.create(new NodeDescription(chainInput));
// Chain can't be validated as origin chain id is not received for aux chain.
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
const node: Node = NodeFactory.create(new NodeDescription(chain));
const args = [
'logs',
'-f',
Expand Down
32 changes: 32 additions & 0 deletions src/bin/mosaic-setup-redeem-pool.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as commander from 'commander';
import Logger from '../Logger';
import setupRedeemPool from '../lib/RedeemPool';
import Validator from './Validator';

import Web3 = require('web3');

const mosaic = commander
.arguments('<originChain> <auxiliaryChain> <auxChainWeb3EndPoint> <deployer> <organizationOwner> <organizationAdmin>');
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -13,6 +16,35 @@ mosaic.action(
organizationOwner: string,
organizationAdmin: string,
) => {
const isValidWeb3Connection = await Validator.isValidWeb3EndPoint(auxChainWeb3EndPoint);
if (!isValidWeb3Connection) {
Logger.error('Could not connect to aux node with web3');
}

if (!Validator.isValidOriginChain(originChain)) {
Logger.error(`Invalid origin chain identifier: ${originChain}`);
process.exit(1);
}

if (!Validator.isValidAuxChain(auxiliaryChain, originChain)) {
Logger.error(`Invalid aux chain identifier: ${auxiliaryChain}`);
process.exit(1);
}

if (!Validator.isValidAddress(deployer)) {
Logger.error(`Invalid deployer address: ${deployer}`);
process.exit(1);
}
if (!Validator.isValidAddress(organizationOwner)) {
Logger.error(`Invalid organization owner address: ${organizationOwner}`);
process.exit(1);
}

if (!Validator.isValidAddress(organizationAdmin)) {
abhayks1 marked this conversation as resolved.
Show resolved Hide resolved
Logger.error(`Invalid organization admin address: ${organizationAdmin}`);
process.exit(1);
}

try {
await setupRedeemPool(
originChain,
Expand Down
Loading