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

[node] Add multisig deployed bytecode check #2187

Merged
merged 6 commits into from
Aug 15, 2019
Merged
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
2 changes: 1 addition & 1 deletion packages/apps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"devDependencies": {
"@counterfactual/cf-adjudicator-contracts": "0.0.1",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@types/chai": "4.2.0",
"@types/mocha": "5.2.7",
"chai": "4.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/cf-adjudicator-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"solidity"
],
"devDependencies": {
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@counterfactual/typescript-typings": "0.1.0",
"@types/chai": "4.2.0",
"@types/node": "12.7.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/cf-funding-protocol-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
],
"devDependencies": {
"@counterfactual/cf-adjudicator-contracts": "0.0.1",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@counterfactual/typescript-typings": "0.1.0",
"@types/chai": "4.2.0",
"@types/node": "12.7.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/cf-wallet.js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"dependencies": {
"@counterfactual/node-provider": "0.1.2",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"ethers": "4.0.33",
"eventemitter3": "^4.0.0",
"global": "^4.3.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/cf.js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"dependencies": {
"@counterfactual/node-provider": "0.2.0",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"ethers": "4.0.33",
"eventemitter3": "^4.0.0",
"rpc-server": "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/firebase-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"lint": "tslint -c tslint.json -p ."
},
"devDependencies": {
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@firebase/app-types": "0.4.0",
"@firebase/util": "0.2.25",
"@types/firebase": "3.2.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/local-ganache-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {
"@counterfactual/cf-funding-protocol-contracts": "0.0.1",
"@counterfactual/cf-adjudicator-contracts": "0.0.1",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@counterfactual/apps": "0.1.4",
"ganache-core": "2.6.1",
"ethers": "4.0.33"
Expand Down
2 changes: 1 addition & 1 deletion packages/node-provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"postinstall": "patch-package"
},
"devDependencies": {
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"@types/jest": "24.0.15",
"@types/node": "12.7.1",
"@types/web3": "1.0.19",
Expand Down
8 changes: 4 additions & 4 deletions packages/node/docs/source/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ Params:

- `owners: string[]`
- the addresses who should be the owners of the multisig
- `retryCount?: number`
- the number of times to retry _deploying the multisig_ using an expontential backoff period between each successive retry, starting with 1 second. This defaults to 3 if no retry count is provided.

Result:

Expand Down Expand Up @@ -346,8 +348,7 @@ Error(s):

### Method: `getFreeBalance`

Gets the free balance AppInstance of the specified channel for the specified
token. Defaults to ETH if no token is specified.
Gets the free balance AppInstance of the specified channel for the specified token. Defaults to ETH if no token is specified.

Params:

Expand All @@ -364,8 +365,7 @@ Result:

Returns a mapping from address to balance in wei. The address of a node with public identifier `publicIdentifier` is defined as `fromExtendedKey(publicIdentifier).derivePath("0").address`.

Note: calling this a specific token address will return Zero even if the channel
has never had any deposits/withdrawals of that token.
Note: calling this with a specific token address will return Zero even if the channel has never had any deposits/withdrawals of that token.

### Method: `getTokenIndexedFreeBalanceStates`

Expand Down
4 changes: 2 additions & 2 deletions packages/node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@counterfactual/node",
"version": "0.2.46",
"version": "0.2.47",
"main": "dist/index.js",
"iife": "dist/index.iife.js",
"types": "dist/src/index.d.ts",
Expand Down Expand Up @@ -58,7 +58,7 @@
"@counterfactual/cf-funding-protocol-contracts": "0.0.1",
"@counterfactual/cf.js": "0.2.3",
"@counterfactual/firebase-client": "0.0.3",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"ethers": "4.0.33",
"eventemitter3": "^4.0.0",
"loglevel": "^1.6.1",
Expand Down
6 changes: 6 additions & 0 deletions packages/node/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ export const CONVENTION_FOR_ETH_TOKEN_ADDRESS = AddressZero;

// 25446 is 0x6366... or "cf" in ascii, for "Counterfactual".
export const CF_PATH = "m/44'/60'/0'/25446";

// When the source code of the contract changes, the deployed bytecode will
// also change and the tests will fail as the deplyed bytecode checking
// in the create channel call will fail.
export const MULTISIG_DEPLOYED_BYTECODE =
"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415603d573d6000fd5b3d6000f3fea265627a7a723058202b014062fac5bbf2f3a320134dac5811a29f916a0f071e16e4493bf4a28fe8a064736f6c634300050a0032";
55 changes: 49 additions & 6 deletions packages/node/src/methods/state-channel/create/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import MinimumViableMultisig from "@counterfactual/cf-funding-protocol-contracts
import ProxyFactory from "@counterfactual/cf-funding-protocol-contracts/build/ProxyFactory.json";
import { NetworkContext, Node } from "@counterfactual/types";
import { Contract, Signer } from "ethers";
import { TransactionResponse } from "ethers/providers";
import { Provider, TransactionResponse } from "ethers/providers";
import { Interface } from "ethers/utils";
import Queue from "p-queue";
import { jsonRpcMethod } from "rpc-server";

import { MULTISIG_DEPLOYED_BYTECODE } from "../../../constants";
import { xkeysToSortedKthAddresses } from "../../../machine";
import { RequestHandler } from "../../../request-handler";
import { CreateChannelMessage, NODE_EVENTS } from "../../../types";
import { getCreate2MultisigAddress, prettyPrintObject } from "../../../utils";
import {
getCreate2MultisigAddress,
prettyPrintObject,
sleep
} from "../../../utils";
import { NodeController } from "../../controller";
import {
CHANNEL_CREATION_FAILED,
Expand Down Expand Up @@ -47,7 +52,7 @@ export default class CreateChannelController extends NodeController {
requestHandler: RequestHandler,
params: Node.CreateChannelParams
): Promise<Node.CreateChannelTransactionResult> {
const { owners } = params;
const { owners, retryCount } = params;
const { wallet, networkContext } = requestHandler;

const multisigAddress = getCreate2MultisigAddress(
Expand All @@ -56,7 +61,12 @@ export default class CreateChannelController extends NodeController {
networkContext.MinimumViableMultisig
);

const tx = await this.sendMultisigDeployTx(wallet, owners, networkContext);
const tx = await this.sendMultisigDeployTx(
wallet,
owners,
networkContext,
retryCount
);

this.handleDeployedMultisigOnChain(multisigAddress, requestHandler, params);

Expand Down Expand Up @@ -103,7 +113,8 @@ export default class CreateChannelController extends NodeController {
private async sendMultisigDeployTx(
signer: Signer,
owners: string[],
networkContext: NetworkContext
networkContext: NetworkContext,
retryCount: number = 3
): Promise<TransactionResponse> {
const proxyFactory = new Contract(
networkContext.ProxyFactory,
Expand All @@ -112,10 +123,10 @@ export default class CreateChannelController extends NodeController {
);

let error;
const retryCount = 3;
for (let tryCount = 0; tryCount < retryCount; tryCount += 1) {
try {
const extraGasLimit = tryCount * 1e6;

const tx: TransactionResponse = await proxyFactory.functions.createProxyWithNonce(
networkContext.MinimumViableMultisig,
new Interface(MinimumViableMultisig.abi).functions.setup.encode([
Expand All @@ -136,6 +147,19 @@ export default class CreateChannelController extends NodeController {
);
}

if (
!(await checkForCorrectDeployedByteCode(
tx!,
signer.provider!,
owners,
networkContext
))
) {
error = `Could not confirm the deployed multisig contract has the expected bytecode`;
await sleep(1000 * tryCount ** 2);
continue;
}

return tx;
} catch (e) {
error = e;
Expand All @@ -147,3 +171,22 @@ export default class CreateChannelController extends NodeController {
throw Error(`${CHANNEL_CREATION_FAILED}: ${prettyPrintObject(error)}`);
}
}

async function checkForCorrectDeployedByteCode(
tx: TransactionResponse,
provider: Provider,
owners: string[],
networkContext: NetworkContext
): Promise<boolean> {
const multisigAddress = getCreate2MultisigAddress(
owners,
networkContext.ProxyFactory,
networkContext.MinimumViableMultisig
);

const multisigDeployedBytecode = await provider.getCode(
multisigAddress,
tx.blockHash
);
return MULTISIG_DEPLOYED_BYTECODE === multisigDeployedBytecode;
}
4 changes: 4 additions & 0 deletions packages/node/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,7 @@ export function signaturesToBytesSortedBySignerAddress(
export function prettyPrintObject(object: any) {
return JSON.stringify(object, null, JSON_STRINGIFY_SPACE);
}

export async function sleep(timeInMilliseconds: number) {
return new Promise(resolve => setTimeout(resolve, timeInMilliseconds));
}
4 changes: 0 additions & 4 deletions packages/node/test/integration/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,6 @@ export function constructUninstallVirtualRpc(
});
}

export async function sleep(timeInMilliseconds: number) {
return new Promise(resolve => setTimeout(resolve, timeInMilliseconds));
}

export async function collateralizeChannel(
node1: Node,
node2: Node,
Expand Down
2 changes: 1 addition & 1 deletion packages/postgresql-node-connector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"dependencies": {
"pg": "7.12.1",
"@counterfactual/types": "0.0.34",
"@counterfactual/types": "0.0.35",
"reflect-metadata": "0.1.13",
"typeorm": "0.2.18"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/simple-hub-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
},
"dependencies": {
"@counterfactual/firebase-client": "0.0.3",
"@counterfactual/node": "0.2.46",
"@counterfactual/types": "0.0.34",
"@counterfactual/node": "0.2.47",
"@counterfactual/types": "0.0.35",
"@counterfactual/typescript-typings": "0.1.0",
"@ebryn/jsonapi-ts": "0.1.17",
"@koa/cors": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/types/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@counterfactual/types",
"version": "0.0.34",
"version": "0.0.35",
"description": "TypeScript typings for common Counterfactual types",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export namespace Node {

export type CreateChannelParams = {
owners: string[];
retryCount?: number;
};

export type CreateChannelResult = {
Expand Down