Skip to content
This repository has been archived by the owner on May 28, 2021. It is now read-only.

1116 init validation #1117

Closed
wants to merge 17 commits into from
Closed
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
104 changes: 52 additions & 52 deletions modules/apps/src/DepositApp/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,65 +52,65 @@ export const validateDepositApp = async (
);
}

if (!initialState.transfers[0].amount.isZero() || !initialState.transfers[1].amount.isZero()) {
throw new Error(
`Cannot install deposit app with nonzero initial balance: ${stringify(
initialState.transfers,
)}`,
);
}
// if (!initialState.transfers[0].amount.isZero() || !initialState.transfers[1].amount.isZero()) {
// throw new Error(
// `Cannot install deposit app with nonzero initial balance: ${stringify(
// initialState.transfers,
// )}`,
// );
// }

if (initialState.multisigAddress !== multisigAddress) {
throw new Error(
`Cannot install deposit app with invalid multisig address. Expected ${multisigAddress}, got ${initialState.multisigAddress}`,
);
}

if (
initialState.assetId !== getAddressFromAssetId(params.initiatorDepositAssetId) ||
initialState.assetId !== getAddressFromAssetId(params.responderDepositAssetId)
) {
throw new Error(
`Cannot install deposit app with invalid token address. Expected ${getAddressFromAssetId(
params.initiatorDepositAssetId,
)}, got ${initialState.assetId}`,
);
}

const startingMultisigBalance =
initialState.assetId === CONVENTION_FOR_ETH_ASSET_ID
? await provider.getBalance(multisigAddress)
: await new Contract(initialState.assetId, ERC20.abi as any, provider).functions.balanceOf(
multisigAddress,
);

const multisig = new Contract(multisigAddress, MinimumViableMultisig.abi as any, provider);
let startingTotalAmountWithdrawn;
try {
startingTotalAmountWithdrawn = await multisig.functions.totalAmountWithdrawn(
initialState.assetId,
);
} catch (e) {
const NOT_DEPLOYED_ERR = `contract not deployed (contractAddress="${multisigAddress}"`;
if (!e.message.includes(NOT_DEPLOYED_ERR)) {
throw new Error(e);
}
// multisig is deployed on withdrawal, if not
// deployed withdrawal amount is 0
startingTotalAmountWithdrawn = Zero;
}

if (!initialState.startingTotalAmountWithdrawn.eq(startingTotalAmountWithdrawn)) {
throw new Error(
`Cannot install deposit app with invalid totalAmountWithdrawn. Expected ${startingTotalAmountWithdrawn}, got ${initialState.startingTotalAmountWithdrawn}`,
);
}

if (!initialState.startingMultisigBalance.eq(startingMultisigBalance)) {
throw new Error(
`Cannot install deposit app with invalid startingMultisigBalance. Expected ${startingMultisigBalance}, got ${initialState.startingMultisigBalance}`,
);
}
// if (
// initialState.assetId !== getAddressFromAssetId(params.initiatorDepositAssetId) ||
// initialState.assetId !== getAddressFromAssetId(params.responderDepositAssetId)
// ) {
// throw new Error(
// `Cannot install deposit app with invalid token address. Expected ${getAddressFromAssetId(
// params.initiatorDepositAssetId,
// )}, got ${initialState.assetId}`,
// );
// }

// const startingMultisigBalance =
// initialState.assetId === CONVENTION_FOR_ETH_ASSET_ID
// ? await provider.getBalance(multisigAddress)
// : await new Contract(initialState.assetId, ERC20.abi as any, provider).functions.balanceOf(
// multisigAddress,
// );

// const multisig = new Contract(multisigAddress, MinimumViableMultisig.abi as any, provider);
// let startingTotalAmountWithdrawn;
// try {
// startingTotalAmountWithdrawn = await multisig.functions.totalAmountWithdrawn(
// initialState.assetId,
// );
// } catch (e) {
// const NOT_DEPLOYED_ERR = `contract not deployed (contractAddress="${multisigAddress}"`;
// if (!e.message.includes(NOT_DEPLOYED_ERR)) {
// throw new Error(e);
// }
// // multisig is deployed on withdrawal, if not
// // deployed withdrawal amount is 0
// startingTotalAmountWithdrawn = Zero;
// }

// if (!initialState.startingTotalAmountWithdrawn.eq(startingTotalAmountWithdrawn)) {
// throw new Error(
// `Cannot install deposit app with invalid totalAmountWithdrawn. Expected ${startingTotalAmountWithdrawn}, got ${initialState.startingTotalAmountWithdrawn}`,
// );
// }

// if (!initialState.startingMultisigBalance.eq(startingMultisigBalance)) {
// throw new Error(
// `Cannot install deposit app with invalid startingMultisigBalance. Expected ${startingMultisigBalance}, got ${initialState.startingMultisigBalance}`,
// );
// }
};

export const uninstallDepositMiddleware = async (
Expand Down
10 changes: 5 additions & 5 deletions modules/apps/src/HashLockTransferApp/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export const validateHashLockTransferApp = (
return transfer.to === responderSignerAddress;
})[0];

if (initialState.expiry.lt(blockNumber)) {
throw new Error(
`Cannot install an app with an expired expiry. Expiry in state: ${initialState.expiry}. Current block: ${blockNumber}`,
);
}
// if (initialState.expiry.lt(blockNumber)) {
// throw new Error(
// `Cannot install an app with an expired expiry. Expiry in state: ${initialState.expiry}. Current block: ${blockNumber}`,
// );
// }

unidirectionalCoinTransferValidation(
initiatorDeposit,
Expand Down
6 changes: 3 additions & 3 deletions modules/apps/src/SimpleLinkedTransferApp/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const validateSimpleLinkedTransferApp = (
responderTransfer,
);

if (!initialState.amount.eq(initiatorDeposit)) {
throw new Error(`Payment amount bust be the same as initiator deposit ${stringify(params)}`);
}
// if (!initialState.amount.eq(initiatorDeposit)) {
// throw new Error(`Payment amount bust be the same as initiator deposit ${stringify(params)}`);
// }
};
40 changes: 20 additions & 20 deletions modules/apps/src/WithdrawApp/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export const validateWithdrawApp = async (
responderTransfer,
);

if (initialState.finalized) {
throw new Error(`Cannot install a withdraw app with a finalized state. State: ${initialState}`);
}
// if (initialState.finalized) {
// throw new Error(`Cannot install a withdraw app with a finalized state. State: ${initialState}`);
// }

if (initialState.signatures[1] !== HashZero) {
throw new Error(
`Cannot install a withdraw app with a populated signatures[1] field. Signatures[1]: ${initialState.signatures[1]}`,
);
}
// if (initialState.signatures[1] !== HashZero) {
// throw new Error(
// `Cannot install a withdraw app with a populated signatures[1] field. Signatures[1]: ${initialState.signatures[1]}`,
// );
// }

if (
initialState.signers[0] !== initiatorSignerAddress ||
Expand All @@ -44,18 +44,18 @@ export const validateWithdrawApp = async (
);
}

if (!initialState.transfers[1].amount.eq(Zero)) {
throw new Error(
`Cannot install a withdraw app with nonzero recipient amount. ${initialState.transfers[1].amount.toString()}`,
);
}
// if (!initialState.transfers[1].amount.eq(Zero)) {
// throw new Error(
// `Cannot install a withdraw app with nonzero recipient amount. ${initialState.transfers[1].amount.toString()}`,
// );
// }

let recovered = await recoverAddressFromChannelMessage(initialState.data, initialState.signatures[0]);
// let recovered = await recoverAddressFromChannelMessage(initialState.data, initialState.signatures[0]);

if (recovered !== initialState.signers[0]) {
throw new Error(
`Cannot install withdraw app - incorrect signer recovered from initiator sig on data.
Recovered: ${recovered}, Expected: ${initialState.signers[0]}`,
);
}
// if (recovered !== initialState.signers[0]) {
// throw new Error(
// `Cannot install withdraw app - incorrect signer recovered from initiator sig on data.
// Recovered: ${recovered}, Expected: ${initialState.signers[0]}`,
// );
// }
};
29 changes: 27 additions & 2 deletions modules/cf-core/src/protocol/propose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
ProtocolParams,
ProtocolRoles,
CONVENTION_FOR_ETH_ASSET_ID,
JsonRpcProvider,
Contract,
} from "@connext/types";
import { getSignerAddressFromPublicIdentifier, logTime, toBN, stringify } from "@connext/utils";
import { defaultAbiCoder, keccak256 } from "ethers/utils";
Expand All @@ -18,6 +20,7 @@ import { Context, PersistAppType, ProtocolExecutionFlow } from "../types";
import { appIdentityToHash } from "../utils";

import { assertIsValidSignature, stateChannelClassFromStoreByMultisig } from "./utils";
import { CounterfactualApp } from "@connext/contracts";

const protocol = ProtocolNames.propose;
const { OP_SIGN, OP_VALIDATE, IO_SEND, IO_SEND_AND_WAIT, PERSIST_APP_INSTANCE } = Opcode;
Expand All @@ -28,7 +31,7 @@ const { OP_SIGN, OP_VALIDATE, IO_SEND, IO_SEND_AND_WAIT, PERSIST_APP_INSTANCE }
*/
export const PROPOSE_PROTOCOL: ProtocolExecutionFlow = {
0 /* Initiating */: async function* (context: Context) {
const { message, store } = context;
const { message, store, network } = context;
const log = context.log.newContext("CF-ProposeProtocol");
const start = Date.now();
let substart = start;
Expand Down Expand Up @@ -86,6 +89,10 @@ export const PROPOSE_PROTOCOL: ProtocolExecutionFlow = {
meta,
};

// Validate initial state using contract init() fn
await validateInitialState(appInstanceProposal, network.provider);

// Injectable validators
yield [
OP_VALIDATE,
protocol,
Expand Down Expand Up @@ -185,7 +192,7 @@ export const PROPOSE_PROTOCOL: ProtocolExecutionFlow = {
},

1 /* Responding */: async function* (context: Context) {
const { message, store } = context;
const { message, store, network } = context;
const { params, processID } = message;
const log = context.log.newContext("CF-ProposeProtocol");
const start = Date.now();
Expand Down Expand Up @@ -247,6 +254,10 @@ export const PROPOSE_PROTOCOL: ProtocolExecutionFlow = {
responderDepositAssetId: responderDepositAssetId || CONVENTION_FOR_ETH_ASSET_ID,
};

// Validate initial state using init() validators in appDefinition
await validateInitialState(appInstanceProposal, network.provider);

// Any other injectable validators
yield [
OP_VALIDATE,
protocol,
Expand Down Expand Up @@ -334,3 +345,17 @@ export const PROPOSE_PROTOCOL: ProtocolExecutionFlow = {
logTime(log, start, `[${processID}] Response finished`);
},
};

async function validateInitialState(
proposal: AppInstanceProposal,
provider: JsonRpcProvider
): Promise<void> {
// Validate init function
const app = new Contract(proposal.appDefinition, CounterfactualApp.abi, provider);
const initialState = defaultAbiCoder.encode([proposal.abiEncodings.stateEncoding], [proposal.initialState])
try {
await app.functions.init(initialState);
} catch (e) {
throw e;
}
}
Loading