decouple state (SimulationEnvironment) and Simulation
This commit is contained in:
@@ -5,7 +5,7 @@ import { SignatureType, SignedZeroExTransaction, ZeroExTransaction } from '@0x/t
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Simulation } from '../simulation/simulation';
|
||||
import { SimulationEnvironment } from '../simulation/simulation';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
|
||||
@@ -14,7 +14,7 @@ export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
export interface ActorConfig {
|
||||
name?: string;
|
||||
deployment: DeploymentManager;
|
||||
simulation?: Simulation;
|
||||
simulationEnvironment?: SimulationEnvironment;
|
||||
[mixinProperty: string]: any;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class Actor {
|
||||
public readonly name: string;
|
||||
public readonly privateKey: Buffer;
|
||||
public readonly deployment: DeploymentManager;
|
||||
public readonly simulation?: Simulation;
|
||||
public readonly simulationEnvironment?: SimulationEnvironment;
|
||||
public simulationActions: {
|
||||
[action: string]: (...args: any[]) => Promise<IteratorResult<AssertionResult | void>>;
|
||||
} = {};
|
||||
@@ -36,7 +36,7 @@ export class Actor {
|
||||
this.name = config.name || this.address;
|
||||
this.deployment = config.deployment;
|
||||
this.privateKey = constants.TESTRPC_PRIVATE_KEYS[config.deployment.accounts.indexOf(this.address)];
|
||||
this.simulation = config.simulation;
|
||||
this.simulationEnvironment = config.simulationEnvironment;
|
||||
this._transactionFactory = new TransactionFactory(
|
||||
this.privateKey,
|
||||
config.deployment.exchange.address,
|
||||
|
@@ -44,7 +44,7 @@ export function PoolOperatorMixin<TBase extends Constructor>(Base: TBase): TBase
|
||||
this.actor = (this as any) as Actor;
|
||||
|
||||
// Register this mixin's assertion generators
|
||||
if (this.actor.simulation !== undefined) {
|
||||
if (this.actor.simulationEnvironment !== undefined) {
|
||||
this.actor.simulationActions = {
|
||||
...this.actor.simulationActions,
|
||||
validCreateStakingPool: this._validCreateStakingPool().next,
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
|
||||
import { StakeInfo, StakeStatus } from '@0x/contracts-staking';
|
||||
import { getRandomInteger } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { validStakeAssertion, validUnstakeAssertion } from '../function-assertions';
|
||||
import { Simulation } from '../simulation/simulation';
|
||||
import { AssertionResult } from '../utils/function_assertions';
|
||||
|
||||
import { Actor, Constructor } from './base';
|
||||
@@ -31,11 +31,12 @@ export function StakerMixin<TBase extends Constructor>(Base: TBase): TBase & Con
|
||||
this.actor = (this as any) as Actor;
|
||||
|
||||
// Register this mixin's assertion generators
|
||||
if (this.actor.simulation !== undefined) {
|
||||
if (this.actor.simulationEnvironment !== undefined) {
|
||||
const { balanceStore } = this.actor.simulationEnvironment;
|
||||
this.actor.simulationActions = {
|
||||
...this.actor.simulationActions,
|
||||
validStake: this._validStake(this.actor.simulation).next,
|
||||
validUnstake: this._validUnstake(this.actor.simulation).next,
|
||||
validStake: this._validStake(balanceStore).next,
|
||||
validUnstake: this._validUnstake(balanceStore).next,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -59,25 +60,25 @@ export function StakerMixin<TBase extends Constructor>(Base: TBase): TBase & Con
|
||||
}
|
||||
}
|
||||
|
||||
private async *_validStake(simulation: Simulation): AsyncIterableIterator<AssertionResult> {
|
||||
private async *_validStake(balanceStore: BlockchainBalanceStore): AsyncIterableIterator<AssertionResult> {
|
||||
const { zrx } = this.actor.deployment.tokens;
|
||||
const assertion = validStakeAssertion(this.actor.deployment, simulation.balanceStore);
|
||||
const assertion = validStakeAssertion(this.actor.deployment, balanceStore);
|
||||
|
||||
while (true) {
|
||||
await simulation.balanceStore.updateErc20BalancesAsync();
|
||||
const zrxBalance = simulation.balanceStore.balances.erc20[this.actor.address][zrx.address];
|
||||
await balanceStore.updateErc20BalancesAsync();
|
||||
const zrxBalance = balanceStore.balances.erc20[this.actor.address][zrx.address];
|
||||
const amount = getRandomInteger(0, zrxBalance);
|
||||
console.log(`stake(${amount})`);
|
||||
yield assertion.executeAsync(amount, { from: this.actor.address });
|
||||
}
|
||||
}
|
||||
|
||||
private async *_validUnstake(simulation: Simulation): AsyncIterableIterator<AssertionResult> {
|
||||
private async *_validUnstake(balanceStore: BlockchainBalanceStore): AsyncIterableIterator<AssertionResult> {
|
||||
const { stakingWrapper } = this.actor.deployment.staking;
|
||||
const assertion = validUnstakeAssertion(this.actor.deployment, simulation.balanceStore);
|
||||
const assertion = validUnstakeAssertion(this.actor.deployment, balanceStore);
|
||||
|
||||
while (true) {
|
||||
await simulation.balanceStore.updateErc20BalancesAsync();
|
||||
await balanceStore.updateErc20BalancesAsync();
|
||||
const undelegatedStake = await stakingWrapper.getOwnerStakeByStatus.callAsync(
|
||||
this.actor.address,
|
||||
StakeStatus.Undelegated,
|
||||
|
@@ -6,19 +6,24 @@ import { PoolOperator, Staker } from '../actors';
|
||||
import { DeploymentManager } from '../utils/deployment_manager';
|
||||
import { AssertionResult } from '../utils/function_assertions';
|
||||
|
||||
import { Simulation } from './simulation';
|
||||
import { Simulation, SimulationEnvironment } from './simulation';
|
||||
|
||||
class PoolManagementSimulation extends Simulation {
|
||||
constructor(balanceStore: BlockchainBalanceStore, deployment: DeploymentManager) {
|
||||
super(balanceStore, deployment);
|
||||
constructor(environment: SimulationEnvironment) {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult> {
|
||||
const staker = new Staker({ name: 'Staker', deployment: this._deployment, simulation: this });
|
||||
await staker.configureERC20TokenAsync(this._deployment.tokens.zrx);
|
||||
this.balanceStore.registerTokenOwner(staker.address, staker.name);
|
||||
const { deployment, balanceStore } = this.environment;
|
||||
const staker = new Staker({ name: 'Staker', deployment, simulationEnvironment: this.environment });
|
||||
await staker.configureERC20TokenAsync(deployment.tokens.zrx);
|
||||
balanceStore.registerTokenOwner(staker.address, staker.name);
|
||||
|
||||
const operator = new PoolOperator({ name: 'Operator', deployment: this._deployment, simulation: this });
|
||||
const operator = new PoolOperator({
|
||||
name: 'Operator',
|
||||
deployment,
|
||||
simulationEnvironment: this.environment,
|
||||
});
|
||||
|
||||
const actions = [
|
||||
staker.simulationActions.validStake,
|
||||
@@ -49,7 +54,7 @@ blockchainTests.only('Pool management fuzz test', env => {
|
||||
{ erc20: { ZRX: deployment.tokens.zrx } },
|
||||
);
|
||||
|
||||
const sim = new PoolManagementSimulation(balanceStore, deployment);
|
||||
const sim = new PoolManagementSimulation({ balanceStore, deployment });
|
||||
return sim.fuzzAsync();
|
||||
});
|
||||
});
|
||||
|
@@ -4,14 +4,15 @@ import * as _ from 'lodash';
|
||||
import { DeploymentManager } from '../utils/deployment_manager';
|
||||
import { AssertionResult } from '../utils/function_assertions';
|
||||
|
||||
export interface SimulationEnvironment {
|
||||
balanceStore: BlockchainBalanceStore;
|
||||
deployment: DeploymentManager;
|
||||
}
|
||||
|
||||
export abstract class Simulation {
|
||||
public poolIds = [];
|
||||
private readonly _generator = this._assertionGenerator();
|
||||
|
||||
protected constructor(
|
||||
public readonly balanceStore: BlockchainBalanceStore,
|
||||
protected readonly _deployment: DeploymentManager,
|
||||
) {}
|
||||
protected constructor(public readonly environment: SimulationEnvironment) {}
|
||||
|
||||
public async stepAsync(): Promise<void> {
|
||||
await this._generator.next();
|
||||
|
Reference in New Issue
Block a user