Skip to content
This repository has been archived by the owner on Dec 13, 2019. It is now read-only.

WIP [node] Unobtrusive deposits #2464

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 38 additions & 73 deletions packages/local-ganache-server/src/contract-deployments.jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,102 +25,67 @@ export type NetworkContextForTestSuite = NetworkContext & {
SimpleTransferApp: string;
};

export async function deployTestArtifactsToChain(wallet: Wallet) {
const coinBalanceRefundContract = await new ContractFactory(
CoinBalanceRefundApp.abi,
CoinBalanceRefundApp.evm.bytecode,
export async function deployed(artifacts: any, wallet: Wallet) {
const contract = await new ContractFactory(
artifacts.abi,
artifacts.evm.bytecode,
wallet
).deploy();

const dolphinCoin = await new ContractFactory(
DolphinCoin.abi,
DolphinCoin.evm.bytecode,
wallet
).deploy();
await contract.deployed();
return contract;
}

const identityApp = await new ContractFactory(
IdentityApp.abi,
IdentityApp.evm.bytecode,
export async function deployTestArtifactsToChain(wallet: Wallet) {
const coinBalanceRefundContract = await deployed(
CoinBalanceRefundApp,
wallet
).deploy();
);

const mvmContract = await new ContractFactory(
MinimumViableMultisig.abi,
MinimumViableMultisig.evm.bytecode,
wallet
).deploy();
const dolphinCoin = await deployed(DolphinCoin, wallet);

const proxyFactoryContract = await new ContractFactory(
ProxyFactory.abi,
ProxyFactory.evm.bytecode,
wallet
).deploy();
const identityApp = await deployed(IdentityApp, wallet);

const coinTransferETHInterpreter = await new ContractFactory(
MultiAssetMultiPartyCoinTransferInterpreter.abi,
MultiAssetMultiPartyCoinTransferInterpreter.evm.bytecode,
wallet
).deploy();
const mvmContract = await deployed(MinimumViableMultisig, wallet);

const twoPartyFixedOutcomeInterpreter = await new ContractFactory(
TwoPartyFixedOutcomeInterpreter.abi,
TwoPartyFixedOutcomeInterpreter.evm.bytecode,
wallet
).deploy();
const proxyFactoryContract = await deployed(ProxyFactory, wallet);

const challengeRegistry = await new ContractFactory(
ChallengeRegistry.abi,
ChallengeRegistry.evm.bytecode,
const coinTransferETHInterpreter = await deployed(
MultiAssetMultiPartyCoinTransferInterpreter,
wallet
).deploy();
);

const conditionalTransactionDelegateTarget = await new ContractFactory(
ConditionalTransactionDelegateTarget.abi,
ConditionalTransactionDelegateTarget.evm.bytecode,
const twoPartyFixedOutcomeInterpreter = await deployed(
TwoPartyFixedOutcomeInterpreter,
wallet
).deploy();
);

const twoPartyFixedOutcomeFromVirtualAppETHInterpreter = await new ContractFactory(
TwoPartyFixedOutcomeFromVirtualAppInterpreter.abi,
TwoPartyFixedOutcomeFromVirtualAppInterpreter.evm.bytecode,
wallet
).deploy();
const challengeRegistry = await deployed(ChallengeRegistry, wallet);

const tttContract = await new ContractFactory(
TicTacToeApp.abi,
TicTacToeApp.evm.bytecode,
const conditionalTransactionDelegateTarget = await deployed(
ConditionalTransactionDelegateTarget,
wallet
).deploy();
);

const transferContract = await new ContractFactory(
UnidirectionalTransferApp.abi,
UnidirectionalTransferApp.evm.bytecode,
const twoPartyFixedOutcomeFromVirtualAppETHInterpreter = await deployed(
TwoPartyFixedOutcomeFromVirtualAppInterpreter,
wallet
).deploy();
);

const simpleTransferContract = await new ContractFactory(
SimpleTransferApp.abi,
SimpleTransferApp.evm.bytecode,
wallet
).deploy();
const tttContract = await deployed(TicTacToeApp, wallet);

const linkContract = await new ContractFactory(
UnidirectionalLinkedTransferApp.abi,
UnidirectionalLinkedTransferApp.evm.bytecode,
wallet
).deploy();
const transferContract = await deployed(UnidirectionalTransferApp, wallet);

const timeLockedPassThrough = await new ContractFactory(
TimeLockedPassThrough.abi,
TimeLockedPassThrough.evm.bytecode,
wallet
).deploy();
const simpleTransferContract = await deployed(SimpleTransferApp, wallet);

const singleAssetTwoPartyCoinTransferInterpreter = await new ContractFactory(
SingleAssetTwoPartyCoinTransferInterpreter.abi,
SingleAssetTwoPartyCoinTransferInterpreter.evm.bytecode,
const linkContract = await deployed(UnidirectionalLinkedTransferApp, wallet);

const timeLockedPassThrough = await deployed(TimeLockedPassThrough, wallet);

const singleAssetTwoPartyCoinTransferInterpreter = await deployed(
SingleAssetTwoPartyCoinTransferInterpreter,
wallet
).deploy();
);

return {
ChallengeRegistry: challengeRegistry.address,
Expand Down
5 changes: 4 additions & 1 deletion packages/local-ganache-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ export class LocalGanacheServer {
this.server = ganache.server({
accounts,
gasLimit: 17592186044415, // 0xfffffffffff
gasPrice: "0x01"
gasPrice: "0x01",
blockTime: process.env.GANACHE_BLOCK_TIME
? parseInt(process.env.GANACHE_BLOCK_TIME!, 10)
: undefined
});

this.server.listen(parseInt(process.env.GANACHE_PORT!, 10));
Expand Down
1 change: 1 addition & 0 deletions packages/node/.env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ FIREBASE_MESSAGING_SERVER_KEY="messageKey"
FIREBASE_STORE_SERVER_KEY="storeKey"
FIREBASE_STORE_PREFIX_KEY="dev-store"
GANACHE_PORT="8545"
GANACHE_BLOCK_TIME=""
POSTGRES_USER="postgres"
POSTGRES_HOST="localhost"
POSTGRES_DATABASE="postgres"
Expand Down
1 change: 1 addition & 0 deletions packages/node/.env.schema
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ FIREBASE_MESSAGING_SERVER_KEY=
FIREBASE_STORE_SERVER_KEY=
FIREBASE_STORE_PREFIX_KEY=
GANACHE_PORT=
GANACHE_BLOCK_TIME=
101 changes: 101 additions & 0 deletions packages/node/test/integration/unobtrusive-collateralize.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { NetworkContextForTestSuite } from "@counterfactual/local-ganache-server";
import { One } from "ethers/constants";
import { parseEther } from "ethers/utils";

import { Node } from "../../src";
import { CONVENTION_FOR_ETH_TOKEN_ADDRESS } from "../../src/constants";
import { NODE_EVENTS, ProposeMessage, InstallMessage } from "../../src/types";
import { toBeLt } from "../machine/integration/bignumber-jest-matcher";

import { setup, SetupContext } from "./setup";
import {
collateralizeChannel,
createChannel,
deposit,
makeInstallCall,
makeProposeCall
} from "./utils";

expect.extend({ toBeLt });

jest.setTimeout(45000);

const { TicTacToeApp } = global["networkContext"] as NetworkContextForTestSuite;

/**
* This should be tested without using automine! GANACHE_BLOCK_TIME variable
* should be defined and >= 1
*/
describe("Should be able to update the free balance app (deposit/withdraw) without interrupting flow of other apps (install/uninstall)", () => {
let multisigAddress: string;
let nodeA: Node;
let nodeB: Node;
beforeEach(async () => {
// create channel
const context: SetupContext = await setup(global);
console.log(`setup complete`);
nodeA = context["A"].node;
nodeB = context["B"].node;

multisigAddress = await createChannel(nodeA, nodeB);

// add some initial balance
await collateralizeChannel(multisigAddress, nodeA, nodeB, parseEther("2"));
});

it("should be able to deposit additional collateral into channel while installing an app", async done => {
let completedEvents = 0;
let nonDepositAppId;

const verifyAndExit = () => {
completedEvents += 1;
if (completedEvents === 2) {
done();
}
};

nodeB.on(NODE_EVENTS.PROPOSE_INSTALL, async (msg: ProposeMessage) => {
console.log(`installing non-deposit app`);
nonDepositAppId = msg.data.appInstanceId;
await makeInstallCall(nodeB, msg.data.appInstanceId);
});

nodeA.on(NODE_EVENTS.INSTALL, (msg: InstallMessage) => {
if (msg.data.params.appInstanceId !== nonDepositAppId) {
// is the deposit app, dont count in the completed
console.log(`installed deposit app`);
return;
}
console.log(`installed non-deposit app`);
verifyAndExit();
});

nodeB.on(NODE_EVENTS.DEPOSIT_STARTED, () => {
console.log(`deposit started`);
});

nodeA.on(NODE_EVENTS.DEPOSIT_CONFIRMED, () => {
console.log(`deposit finished`);
if (!nonDepositAppId) {
// still hasnt tried installing channel app,
// force test failure
expect(`Could not install app with deposit in progress`).toBeNull();
}
verifyAndExit();
});

const installRpc = makeProposeCall(
nodeB,
TicTacToeApp,
undefined,
One,
CONVENTION_FOR_ETH_TOKEN_ADDRESS,
One,
CONVENTION_FOR_ETH_TOKEN_ADDRESS
);

// wait for deposit to progress
await deposit(nodeB, multisigAddress);
nodeA.rpcRouter.dispatch(installRpc);
});
});