Better validate ZeroExConfig on public networks

This commit is contained in:
Leonid Logvinov 2018-02-08 18:01:53 +01:00
parent 18e1c2dea5
commit f3e6ef0fa9
No known key found for this signature in database
GPG Key ID: 0DD294BFDE8C95D4
6 changed files with 100 additions and 36 deletions

View File

@ -13,6 +13,8 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr
import { TokenWrapper } from './contract_wrappers/token_wrapper'; import { TokenWrapper } from './contract_wrappers/token_wrapper';
import { OrderStateWatcher } from './order_watcher/order_state_watcher'; import { OrderStateWatcher } from './order_watcher/order_state_watcher';
import { zeroExConfigSchema } from './schemas/zero_ex_config_schema'; import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema';
import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema';
import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types'; import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types';
import { assert } from './utils/assert'; import { assert } from './utils/assert';
import { constants } from './utils/constants'; import { constants } from './utils/constants';
@ -20,6 +22,9 @@ import { decorators } from './utils/decorators';
import { signatureUtils } from './utils/signature_utils'; import { signatureUtils } from './utils/signature_utils';
import { utils } from './utils/utils'; import { utils } from './utils/utils';
assert.schemaValidator.addSchema(zeroExPrivateNetworkConfigSchema);
assert.schemaValidator.addSchema(zeroExPublicNetworkConfigSchema);
/** /**
* The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality * The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality
* and all calls to the library should be made through a ZeroEx instance. * and all calls to the library should be made through a ZeroEx instance.

View File

@ -1,27 +1,5 @@
export const zeroExConfigSchema = { export const zeroExConfigSchema = {
id: '/ZeroExConfig', id: '/ZeroExConfig',
properties: { oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }],
networkId: {
type: 'number',
minimum: 0,
},
gasPrice: { $ref: '/Number' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object', type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: ['networkId'],
}; };

View File

@ -0,0 +1,35 @@
export const zeroExPrivateNetworkConfigSchema = {
id: '/ZeroExPrivateNetworkConfig',
properties: {
networkId: {
type: 'number',
minimum: 1,
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: [
'networkId',
'zrxContractAddress',
'exchangeContractAddress',
'tokenRegistryContractAddress',
'tokenTransferProxyContractAddress',
],
};

View File

@ -0,0 +1,29 @@
export const zeroExPublicNetworkConfigSchema = {
id: '/ZeroExPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
enum: [1, 3, 4, 42, 50],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: ['networkId'],
};

View File

@ -9,6 +9,10 @@ import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/g
import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token'; import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token';
export enum ZeroExError { export enum ZeroExError {
ZRXAddressRequired = 'ZRX_ADDREESS_REQUIRED',
ExchangeAddressRequired = 'EXCHANGE_ADDREESS_REQUIRED',
TokenRegistryAddressRequired = 'TOKEN_REGISTRY_ADDREESS_REQUIRED',
TokenTransferProxyAddressRequired = 'TOKEN_TRANSFER_PROXY_ADDREESS_REQUIRED',
ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST', ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST', EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
@ -195,17 +199,8 @@ export interface OrderStateWatcherConfig {
cleanupJobIntervalMs?: number; cleanupJobIntervalMs?: number;
} }
/* export interface ZeroExPublicNetworkConfig {
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc) networkId: 1 | 3 | 4 | 42 | 50;
* gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use
* zrxContractAddress: The address of the ZRX contract to use
* tokenRegistryContractAddress: The address of a token registry contract to use
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher
*/
export interface ZeroExConfig {
networkId: number;
gasPrice?: BigNumber; gasPrice?: BigNumber;
exchangeContractAddress?: string; exchangeContractAddress?: string;
zrxContractAddress?: string; zrxContractAddress?: string;
@ -214,6 +209,27 @@ export interface ZeroExConfig {
orderWatcherConfig?: OrderStateWatcherConfig; orderWatcherConfig?: OrderStateWatcherConfig;
} }
export interface ZeroExPrivateNetworkConfig {
networkId: number;
gasPrice?: BigNumber;
exchangeContractAddress: string;
zrxContractAddress: string;
tokenRegistryContractAddress: string;
tokenTransferProxyContractAddress: string;
orderWatcherConfig?: OrderStateWatcherConfig;
}
/*
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc)
* gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use
* zrxContractAddress: The address of the ZRX contract to use
* tokenRegistryContractAddress: The address of a token registry contract to use
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher
*/
export type ZeroExConfig = ZeroExPublicNetworkConfig | ZeroExPrivateNetworkConfig;
export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken'; export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken';
export interface Artifact { export interface Artifact {

View File

@ -4,8 +4,10 @@ import * as _ from 'lodash';
import * as validUrl from 'valid-url'; import * as validUrl from 'valid-url';
const HEX_REGEX = /^0x[0-9A-F]*$/i; const HEX_REGEX = /^0x[0-9A-F]*$/i;
const schemaValidator = new SchemaValidator();
export const assert = { export const assert = {
schemaValidator,
isBigNumber(variableName: string, value: BigNumber): void { isBigNumber(variableName: string, value: BigNumber): void {
const isBigNumber = _.isObject(value) && (value as any).isBigNumber; const isBigNumber = _.isObject(value) && (value as any).isBigNumber;
this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value)); this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value));
@ -67,8 +69,7 @@ export const assert = {
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
}, },
doesConformToSchema(variableName: string, value: any, schema: Schema): void { doesConformToSchema(variableName: string, value: any, schema: Schema): void {
const schemaValidator = new SchemaValidator(); const validationResult = assert.schemaValidator.validate(value, schema);
const validationResult = schemaValidator.validate(value, schema);
const hasValidationErrors = validationResult.errors.length > 0; const hasValidationErrors = validationResult.errors.length > 0;
const msg = `Expected ${variableName} to conform to schema ${schema.id} const msg = `Expected ${variableName} to conform to schema ${schema.id}
Encountered: ${JSON.stringify(value, null, '\t')} Encountered: ${JSON.stringify(value, null, '\t')}