Create dev-utils with blockchainLifecycle in it
This commit is contained in:
26
packages/dev-utils/src/blockchain_lifecycle.ts
Normal file
26
packages/dev-utils/src/blockchain_lifecycle.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import {RPC} from './rpc';
|
||||
|
||||
export class BlockchainLifecycle {
|
||||
private rpc: RPC;
|
||||
private snapshotIdsStack: number[];
|
||||
constructor(url: string) {
|
||||
this.rpc = new RPC(url);
|
||||
this.snapshotIdsStack = [];
|
||||
}
|
||||
// TODO: In order to run these tests on an actual node, we should check if we are running against
|
||||
// TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
|
||||
public async startAsync(): Promise<void> {
|
||||
const snapshotId = await this.rpc.takeSnapshotAsync();
|
||||
this.snapshotIdsStack.push(snapshotId);
|
||||
}
|
||||
public async revertAsync(): Promise<void> {
|
||||
const snapshotId = this.snapshotIdsStack.pop() as number;
|
||||
const didRevert = await this.rpc.revertSnapshotAsync(snapshotId);
|
||||
if (!didRevert) {
|
||||
throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
|
||||
}
|
||||
}
|
||||
public async mineABlock(): Promise<void> {
|
||||
await this.rpc.mineBlockAsync();
|
||||
}
|
||||
}
|
2
packages/dev-utils/src/index.ts
Normal file
2
packages/dev-utils/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export {RPC} from './rpc';
|
||||
export {BlockchainLifecycle} from './blockchain_lifecycle';
|
61
packages/dev-utils/src/rpc.ts
Normal file
61
packages/dev-utils/src/rpc.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as request from 'request-promise-native';
|
||||
|
||||
export class RPC {
|
||||
private url: string;
|
||||
private port: number;
|
||||
private id: number;
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
this.id = 0;
|
||||
}
|
||||
public async takeSnapshotAsync(): Promise<number> {
|
||||
const method = 'evm_snapshot';
|
||||
const params: any[] = [];
|
||||
const payload = this.toPayload(method, params);
|
||||
const snapshotIdHex = await this.sendAsync(payload);
|
||||
const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
|
||||
return snapshotId;
|
||||
}
|
||||
public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
|
||||
const method = 'evm_revert';
|
||||
const params = [snapshotId];
|
||||
const payload = this.toPayload(method, params);
|
||||
const didRevert = await this.sendAsync(payload);
|
||||
return didRevert;
|
||||
}
|
||||
public async increaseTimeAsync(time: number) {
|
||||
const method = 'evm_increaseTime';
|
||||
const params = [time];
|
||||
const payload = this.toPayload(method, params);
|
||||
return this.sendAsync(payload);
|
||||
}
|
||||
public async mineBlockAsync(): Promise<void> {
|
||||
const method = 'evm_mine';
|
||||
const params: any[] = [];
|
||||
const payload = this.toPayload(method, params);
|
||||
await this.sendAsync(payload);
|
||||
}
|
||||
private toPayload(method: string, params: any[] = []): string {
|
||||
const payload = JSON.stringify({
|
||||
id: this.id,
|
||||
method,
|
||||
params,
|
||||
});
|
||||
this.id += 1;
|
||||
return payload;
|
||||
}
|
||||
private async sendAsync(payload: string): Promise<any> {
|
||||
const opts = {
|
||||
method: 'POST',
|
||||
uri: this.url,
|
||||
body: payload,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
};
|
||||
const bodyString = await request(opts);
|
||||
const body = JSON.parse(bodyString);
|
||||
return body.result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user