import { NetworkContextForTestSuite } from "@counterfactual/local-ganache-server" ; import { parseEther } from "ethers/utils" ; import { Node } from "../../src" ; import { InstallVirtualMessage , NODE_EVENTS , UpdateStateMessage } from "../../src/types" ; import { toBeLt } from "../engine/integration/bignumber-jest-matcher" ; import { setup , SetupContext } from "./setup" ; import { validAction } from "./tic-tac-toe" ; import { collateralizeChannel , constructTakeActionRpc , createChannel , installVirtualApp } from "./utils" ; expect . extend ( { toBeLt } ) ; jest . setTimeout ( 15000 ) ; const { TicTacToeApp } = global [ "networkContext" ] as NetworkContextForTestSuite ; describe ( "Concurrently taking action on virtual apps without issue" , ( ) => { let multisigAddressAB ; let multisigAddressBC ; let nodeA ; let nodeB ; let nodeC ; beforeEach ( async ( ) => { const context = await setup ( global , true ) ; nodeA = context [ "A" ] . node ; nodeB = context [ "B" ] . node ; nodeC = context [ "C" ] . node ; multisigAddressAB = await createChannel ( nodeA , nodeB ) ; multisigAddressBC = await createChannel ( nodeB , nodeC ) ; await collateralizeChannel ( multisigAddressAB , nodeA , nodeB , parseEther ( "2" ) ) ; await collateralizeChannel ( multisigAddressBC , nodeB , nodeC , parseEther ( "2" ) ) ; } ) ; it ( "can handle two concurrent TTT virtual app take actions" , async ( done ) => { const INSTALLED_APPS = 2 ; const appIds = [ ] ; nodeA . on ( NODE_EVENTS . INSTALL_VIRTUAL , ( msg ) => { expect ( msg . data . params . appInstanceId ) . toBeTruthy ( ) ; appIds . push ( msg . data . params . appInstanceId ) ; } ) ; for ( const i of Array ( INSTALLED_APPS ) ) { await installVirtualApp ( nodeA , nodeB , nodeC , TicTacToeApp ) ; } while ( appIds . length !== INSTALLED_APPS ) { await new Promise ( resolve => setTimeout ( resolve , 20 ) ) ; } let appsTakenActionOn = 0 ; nodeC . on ( NODE_EVENTS . UPDATE_STATE , ( ) => { appsTakenActionOn += 1 ; if ( appsTakenActionOn === 2 ) done ( ) ; } ) ; const takeActionReq = ( appId ) => constructTakeActionRpc ( appId , validAction ) ; nodeA . rpcRouter . dispatch ( takeActionReq ( appIds [ 0 ] ) ) ; nodeA . rpcRouter . dispatch ( takeActionReq ( appIds [ 1 ] ) ) ; } ) ; } ) ;