From 44f268a7ee57e3353cf5362bd2541cbc1ee43d9b Mon Sep 17 00:00:00 2001 From: Michael Zhu Date: Tue, 5 Nov 2019 11:08:58 -0800 Subject: [PATCH] decouple state (SimulationEnvironment) and Simulation --- contracts/integrations/test/actors/base.ts | 8 +++---- .../integrations/test/actors/pool_operator.ts | 2 +- contracts/integrations/test/actors/staker.ts | 23 ++++++++++--------- .../simulation/pool_management_fuzz_test.ts | 21 ++++++++++------- .../test/simulation/simulation.ts | 11 +++++---- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/contracts/integrations/test/actors/base.ts b/contracts/integrations/test/actors/base.ts index 128aedc854..82eb28a73e 100644 --- a/contracts/integrations/test/actors/base.ts +++ b/contracts/integrations/test/actors/base.ts @@ -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 = 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>; } = {}; @@ -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, diff --git a/contracts/integrations/test/actors/pool_operator.ts b/contracts/integrations/test/actors/pool_operator.ts index 30189c7348..96152f8cbc 100644 --- a/contracts/integrations/test/actors/pool_operator.ts +++ b/contracts/integrations/test/actors/pool_operator.ts @@ -44,7 +44,7 @@ export function PoolOperatorMixin(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, diff --git a/contracts/integrations/test/actors/staker.ts b/contracts/integrations/test/actors/staker.ts index 74747e75c0..a9cb163e2b 100644 --- a/contracts/integrations/test/actors/staker.ts +++ b/contracts/integrations/test/actors/staker.ts @@ -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(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(Base: TBase): TBase & Con } } - private async *_validStake(simulation: Simulation): AsyncIterableIterator { + private async *_validStake(balanceStore: BlockchainBalanceStore): AsyncIterableIterator { 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 { + private async *_validUnstake(balanceStore: BlockchainBalanceStore): AsyncIterableIterator { 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, diff --git a/contracts/integrations/test/simulation/pool_management_fuzz_test.ts b/contracts/integrations/test/simulation/pool_management_fuzz_test.ts index 91e03c4c23..210af43132 100644 --- a/contracts/integrations/test/simulation/pool_management_fuzz_test.ts +++ b/contracts/integrations/test/simulation/pool_management_fuzz_test.ts @@ -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 { - 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(); }); }); diff --git a/contracts/integrations/test/simulation/simulation.ts b/contracts/integrations/test/simulation/simulation.ts index 8643180881..7032caebbb 100644 --- a/contracts/integrations/test/simulation/simulation.ts +++ b/contracts/integrations/test/simulation/simulation.ts @@ -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 { await this._generator.next();