Merge branch 'develop' into wallet-config

This commit is contained in:
Daniel Ternyak 2017-12-06 13:27:49 -08:00 committed by GitHub
commit 5841ca9e66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 125 additions and 83 deletions

View File

@ -2,22 +2,34 @@ dist: trusty
sudo: required
language: node_js
services:
- docker
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- docker pull dternyak/eth-priv-to-addr:latest
install:
- npm install --silent
jobs:
include:
- stage: test
script: npm run test
- stage: test
script: npm run test:int
- stage: test
script: npm run tslint
- stage: test
script: npm run tscheck
- stage: test
script: npm run freezer
- stage: test
script: npm run freezer:validate
notifications:
email:
on_success: never
on_failure: never
script:
- npm run test
- npm run tslint
- npm run tscheck
- npm run freezer
- npm run freezer:validate
on_failure: never

View File

@ -1,57 +0,0 @@
import assert from 'assert';
import { generate, IFullWallet } from 'ethereumjs-wallet';
const { exec } = require('child_process');
const ProgressBar = require('progress');
// FIXME pick a less magic number
const derivationRounds = 100;
const dockerImage = 'dternyak/eth-priv-to-addr';
const dockerTag = 'latest';
const bar = new ProgressBar(':percent :bar', { total: derivationRounds });
function promiseFromChildProcess(command): Promise<any> {
return new Promise((resolve, reject) => {
return exec(command, (err, stdout) => {
err ? reject(err) : resolve(stdout);
});
});
}
async function privToAddrViaDocker(privKeyWallet: IFullWallet) {
const command = `docker run -e key=${privKeyWallet.getPrivateKeyString()} ${
dockerImage
}:${dockerTag}`;
const dockerOutput = await promiseFromChildProcess(command);
const newlineStrippedDockerOutput = dockerOutput.replace(
/(\r\n|\n|\r)/gm,
''
);
return newlineStrippedDockerOutput;
}
async function testDerivation() {
const privKeyWallet = generate();
const privKeyWalletAddress = await privKeyWallet.getAddressString();
const dockerAddr = await privToAddrViaDocker(privKeyWallet);
// strip the checksum
const lowerCasedPrivKeyWalletAddress = privKeyWalletAddress.toLowerCase();
// ensure that pyethereum privToAddr derivation matches our (js based) derivation
assert.strictEqual(dockerAddr, lowerCasedPrivKeyWalletAddress);
}
async function testDerivationNTimes(n = derivationRounds) {
let totalRounds = 0;
while (totalRounds < n) {
await testDerivation();
bar.tick();
totalRounds += 1;
}
}
console.log('Starting testing...');
console.time('testDerivationNTimes');
testDerivationNTimes().then(() => {
console.timeEnd('testDerivationNTimes');
console.log(`Succeeded testing derivation ${derivationRounds} times :)`);
process.exit(0);
});

View File

@ -0,0 +1,22 @@
{
"rootDir": "../",
"transform": {
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|(\\.|/)(int))\\.(jsx?|tsx?)$",
"moduleDirectories": ["node_modules", "common"],
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/jest_config/__mocks__/fileMock.ts",
"\\.(css|scss|less)$": "<rootDir>/jest_config/__mocks__/styleMock.ts"
},
"testPathIgnorePatterns": ["<rootDir>/common/config"],
"setupFiles": [
"<rootDir>/jest_config/setupJest.js",
"<rootDir>/jest_config/__mocks__/localStorage.ts"
],
"automock": false,
"snapshotSerializers": ["enzyme-to-json/serializer"],
"browser": true
}

View File

@ -13,7 +13,7 @@
"bootstrap-sass": "3.3.7",
"classnames": "2.2.5",
"ethereum-blockies": "git+https://github.com/MyEtherWallet/blockies.git",
"ethereumjs-abi": "0.6.4",
"ethereumjs-abi": "0.6.5",
"ethereumjs-tx": "1.3.3",
"ethereumjs-util": "5.1.2",
"ethereumjs-wallet": "0.6.0",
@ -47,7 +47,7 @@
"@types/classnames": "2.2.3",
"@types/history": "4.6.2",
"@types/jest": "21.1.8",
"@types/lodash": "4.14.87",
"@types/lodash": "4.14.88",
"@types/qrcode": "0.8.0",
"@types/qrcode.react": "0.6.2",
"@types/react": "16.0.26",
@ -120,13 +120,14 @@
"build:demo": "BUILD_GH_PAGES=true webpack --config webpack_config/webpack.prod.js",
"prebuild:demo": "check-node-version --package",
"test": "jest --config=jest_config/jest.config.json --coverage",
"test:unit": "jest --config=jest_config/jest.config.json --coverage",
"test:int": "jest --config=jest_config/jest.int.config.json --coverage",
"updateSnapshot": "jest --config=jest_config/jest.config.json --updateSnapshot",
"pretest": "check-node-version --package",
"dev": "node webpack_config/server.js",
"predev": "check-node-version --package",
"dev:https": "HTTPS=true node webpack_config/server.js",
"predev:https": "check-node-version --package",
"derivation-checker": "webpack --config=./webpack_config/webpack.derivation-checker.js && node ./dist/derivation-checker.js",
"tslint": "tslint --project . --exclude common/vendor/**/*",
"tscheck": "tsc --noEmit",
"postinstall": "webpack --config=./webpack_config/webpack.dll.js",

View File

@ -55,9 +55,7 @@ function testRpcRequests(node: RPCNode, service: string) {
it(
`RPC: ${testType} ${service}`,
() => {
return RPCTests[testType](node).then(d =>
expect(d.valid).toBeTruthy()
);
return RPCTests[testType](node).then(d => expect(d.valid).toBeTruthy());
},
10000
);
@ -69,24 +67,15 @@ const mapNodeEndpoints = (nodes: { [key: string]: NodeConfig }) => {
const { RpcNodes, EtherscanNodes, InfuraNodes } = RpcNodeTestConfig;
RpcNodes.forEach(n => {
testRpcRequests(
nodes[n].lib as RPCNode,
`${nodes[n].service} ${nodes[n].network}`
);
testRpcRequests(nodes[n].lib as RPCNode, `${nodes[n].service} ${nodes[n].network}`);
});
EtherscanNodes.forEach(n => {
testRpcRequests(
nodes[n].lib as EtherscanNode,
`${nodes[n].service} ${nodes[n].network}`
);
testRpcRequests(nodes[n].lib as EtherscanNode, `${nodes[n].service} ${nodes[n].network}`);
});
InfuraNodes.forEach(n => {
testRpcRequests(
nodes[n].lib as InfuraNode,
`${nodes[n].service} ${nodes[n].network}`
);
testRpcRequests(nodes[n].lib as InfuraNode, `${nodes[n].service} ${nodes[n].network}`);
});
};

View File

@ -0,0 +1,75 @@
import { generate, IFullWallet } from 'ethereumjs-wallet';
import { stripHexPrefix } from '../../common/libs/values';
const { exec } = require('child_process');
// FIXME pick a less magic number
const derivationRounds = 500;
const dockerImage = 'dternyak/eth-priv-to-addr';
const dockerTag = 'latest';
function promiseFromChildProcess(command: string): Promise<any> {
return new Promise((resolve, reject) => {
return exec(command, (err, stdout) => {
err ? reject(err) : resolve(stdout);
});
});
}
function getCleanPrivateKey(privKeyWallet: IFullWallet): string {
return stripHexPrefix(privKeyWallet.getPrivateKeyString());
}
function makeCommaSeparatedPrivateKeys(privKeyWallets: IFullWallet[]): string {
const privateKeys = privKeyWallets.map(getCleanPrivateKey);
return privateKeys.join(',');
}
async function privToAddrViaDocker(privKeyWallets: IFullWallet[]): Promise<string> {
const command = `docker run -e key=${makeCommaSeparatedPrivateKeys(
privKeyWallets
)} ${dockerImage}:${dockerTag}`;
const dockerOutput = await promiseFromChildProcess(command);
const newlineStrippedDockerOutput = dockerOutput.replace(/(\r\n|\n|\r)/gm, '');
return newlineStrippedDockerOutput;
}
function makeWallets(): IFullWallet[] {
const wallets: IFullWallet[] = [];
let i = 0;
while (i < derivationRounds) {
const privKeyWallet = generate();
wallets.push(privKeyWallet);
i += 1;
}
return wallets;
}
async function getNormalizedAddressFromWallet(wallet: IFullWallet): Promise<string> {
const privKeyWalletAddress = await wallet.getAddressString();
// strip checksum
return privKeyWalletAddress.toLowerCase();
}
async function getNormalizedAddressesFromWallets(wallets: IFullWallet[]): Promise<string[]> {
return Promise.all(wallets.map(getNormalizedAddressFromWallet));
}
async function testDerivation(): Promise<true> {
const wallets = makeWallets();
const walletAddrs = await getNormalizedAddressesFromWallets(wallets);
const dockerAddrsCS = await privToAddrViaDocker(wallets);
const dockerAddrs = dockerAddrsCS.split(',');
expect(walletAddrs).toEqual(dockerAddrs);
return true;
}
describe('Derivation Checker', () => {
beforeEach(() => {
// increase timer to prevent early timeout
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
});
it(`should derive identical addresses ${derivationRounds} times`, () => {
return testDerivation().then(expect);
});
});