Skip to content

Commit

Permalink
fix(RREL-17): use rpc accounts for dev purposes only (#117)
Browse files Browse the repository at this point in the history
* fix(RREL-17): use rpc accounts for dev purposes only

* test: enable all tests

* test: fix test descriptions
  • Loading branch information
antomor authored Jul 25, 2023
1 parent 51d682c commit d02d144
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 29 deletions.
41 changes: 41 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"register": "ts-node src/commands/Register.ts",
"start": "ts-node src/commands/Start.ts",
"tdd": "npm run test -- --watch --watch-files src,test",
"test": "ALLOW_CONFIG_MUTATIONS=true npx mocha -r ts-node/register --extensions ts 'test/**/*.{test,spec}.ts'"
"test": "ALLOW_CONFIG_MUTATIONS=true npx mocha -r ts-node/register -r tsconfig-paths/register --extensions ts 'test/**/*.{test,spec}.ts'"
},
"lint-staged": {
"*": "npx embedme \"*.md\"",
Expand Down Expand Up @@ -121,6 +121,7 @@
"prettier": "^2.8.3",
"sinon": "^15.0.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "4.8.2"
}
}
31 changes: 3 additions & 28 deletions src/commands/Register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BigNumber, constants, Signer, utils, Wallet } from 'ethers';
import log from 'loglevel';
import { getServerConfig, RegisterConfig } from '../ServerConfigParams';
import { isSameAddress, sleep } from '../Utils';
import { findWealthyAccount } from './findWealthyAccount';

//TODO: This is almost the same type as RegisterConfig from /ServerConfigParams
type RegisterOptions = {
Expand All @@ -18,32 +19,6 @@ type RegisterOptions = {
unstakeDelay: BigNumber;
};

const findWealthyAccount = async (
rpcProvider: JsonRpcProvider,
requiredBalance: BigNumber = utils.parseUnits('2', 'ether')
): Promise<Signer> => {
let accounts: string[] = [];
try {
accounts = await rpcProvider.listAccounts();
for (let i = 0; i < accounts.length; i++) {
const signer = rpcProvider.getSigner(i);
const balance = await signer.getBalance();
if (balance.gte(requiredBalance)) {
log.info(`Found funded account ${await signer.getAddress()}`);

return signer;
}
}
} catch (error) {
log.error('Failed to retrieve accounts and balances:', error);
}
throw new Error(
`could not find unlocked account with sufficient balance; all accounts:\n - ${accounts.join(
'\n - '
)}`
);
};

const waitForRelay = async (
httpClient: HttpClient,
relayUrl: string,
Expand Down Expand Up @@ -164,7 +139,7 @@ const register = async (
log.info('Executed Transactions', transactions);
};

const retreiveSigner = async (
const retrieveSigner = async (
rpcProvider: JsonRpcProvider,
privateKey?: string,
mnemonic?: string
Expand Down Expand Up @@ -204,7 +179,7 @@ const executeRegister = async (): Promise<void> => {
await register(rpcProvider, {
relayHub: relayHub || contracts.relayHubAddress,
relayUrl: serverUrl,
signer: await retreiveSigner(rpcProvider, privateKey, mnemonic),
signer: await retrieveSigner(rpcProvider, privateKey, mnemonic),
stake: utils.parseEther(stake.toString()),
funds: utils.parseEther(funds.toString()),
unstakeDelay: BigNumber.from(unstakeDelay),
Expand Down
36 changes: 36 additions & 0 deletions src/commands/findWealthyAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { JsonRpcProvider } from '@ethersproject/providers';
import { BigNumber, Signer, utils } from 'ethers';
import log from 'loglevel';

export const REGTEST_CHAIN_ID = 33;

export const findWealthyAccount = async (
rpcProvider: JsonRpcProvider,
requiredBalance: BigNumber = utils.parseUnits('2', 'ether')
): Promise<Signer> => {
const { chainId } = await rpcProvider.getNetwork();
if (chainId !== REGTEST_CHAIN_ID) {
throw new Error('Unlocked accounts are allowed for testing purposes only');
}

let accounts: string[] = [];
try {
accounts = await rpcProvider.listAccounts();
for (let i = 0; i < accounts.length; i++) {
const signer = rpcProvider.getSigner(i);
const balance = await signer.getBalance();
if (balance.gte(requiredBalance)) {
log.info(`Found funded account ${await signer.getAddress()}`);

return signer;
}
}
} catch (error) {
log.error('Failed to retrieve accounts and balances:', error);
}
throw new Error(
`could not find unlocked account with sufficient balance; all accounts:\n - ${accounts.join(
'\n - '
)}`
);
};
56 changes: 56 additions & 0 deletions test/unit/findWealthAccounts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { expect, use } from 'chai';
import { utils, type providers } from 'ethers';
import {
REGTEST_CHAIN_ID,
findWealthyAccount,
} from 'src/commands/findWealthyAccount';
import chaiAsPromised from 'chai-as-promised';

use(chaiAsPromised);

const TESTNET_CHAIN_ID = 31;
const MAINNET_CHAIN_ID = 30;

describe('findWealthAccounts', function () {
const expectedSigner = {
getAddress: () => '0x123abc',
getBalance: () => Promise.resolve(utils.parseUnits('2', 'ether')),
};

const getMockedProvider = (expectedChainId: number) =>
({
getNetwork: () => ({ chainId: expectedChainId }),
listAccounts: () => [1, 2, 3],
getSigner: () => expectedSigner,
} as unknown as providers.JsonRpcProvider);

const expectFindWealthyAccountToFail = async (chainId: number) => {
const mockRpcProvider = getMockedProvider(chainId);
await expect(findWealthyAccount(mockRpcProvider)).to.rejectedWith(
'Unlocked accounts are allowed for testing purposes only'
);
};

it('should not raise an error if it is used for dev purposes', async function () {
const mockRpcProvider = getMockedProvider(REGTEST_CHAIN_ID);
const account = await findWealthyAccount(mockRpcProvider);
expect(account).to.be.eq(expectedSigner);
});

it('should raise an error if it is used on Testnet', async function () {
await expectFindWealthyAccountToFail(TESTNET_CHAIN_ID);
});

it('should raise an error if it is used on Mainnet', async function () {
await expectFindWealthyAccountToFail(MAINNET_CHAIN_ID);
});

it('should raise an error if no accounts are found with enough balance', async function () {
const mockRpcProvider = getMockedProvider(REGTEST_CHAIN_ID);
await expect(
findWealthyAccount(mockRpcProvider, utils.parseUnits('3', 'ether'))
).to.rejectedWith(
'could not find unlocked account with sufficient balance;'
);
});
});

0 comments on commit d02d144

Please sign in to comment.