2017-12-06 06:24:40 +00:00
|
|
|
import { generate, IFullWallet } from 'ethereumjs-wallet';
|
2018-06-18 01:53:00 +00:00
|
|
|
|
|
|
|
import { stripHexPrefix } from '../../common/libs/formatters';
|
|
|
|
|
2017-12-06 06:24:40 +00:00
|
|
|
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) => {
|
2018-03-07 23:36:05 +00:00
|
|
|
return exec(command, (err: string, stdout: string) => {
|
2017-12-06 06:24:40 +00:00
|
|
|
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> {
|
2018-01-01 19:08:12 +00:00
|
|
|
const command = `docker run -e key=${makeCommaSeparatedPrivateKeys(
|
|
|
|
privKeyWallets
|
|
|
|
)} ${dockerImage}:${dockerTag}`;
|
2017-12-06 06:24:40 +00:00
|
|
|
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);
|
|
|
|
});
|
|
|
|
});
|