Skip to content

Commit

Permalink
feat(cli): add retries to deploy (#1766)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Oct 13, 2023
1 parent e667ee8 commit e1dc88e
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 78 deletions.
5 changes: 5 additions & 0 deletions .changeset/wise-cheetahs-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/cli": minor
---

Transactions sent via deploy will now be retried a few times before giving up. This hopefully helps with large deploys on some chains.
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"glob": "^8.0.3",
"nice-grpc-web": "^2.0.1",
"openurl": "^1.1.1",
"p-retry": "^5.1.2",
"path": "^0.12.7",
"rxjs": "7.5.5",
"throttle-debounce": "^5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { deployWorld } from "./deployWorld";
import { ensureTables } from "./ensureTables";
import { Config, ConfigInput, WorldDeploy, supportedStoreVersions, supportedWorldVersions } from "./common";
import { ensureSystems } from "./ensureSystems";
import { getTransactionReceipt, waitForTransactionReceipt } from "viem/actions";
import { waitForTransactionReceipt } from "viem/actions";
import { getWorldDeploy } from "./getWorldDeploy";
import { ensureFunctions } from "./ensureFunctions";
import { ensureModules } from "./ensureModules";
Expand Down
23 changes: 18 additions & 5 deletions packages/cli/src/deploy/ensureContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { deployer } from "./ensureDeployer";
import { salt } from "./common";
import { sendTransaction } from "@latticexyz/common";
import { debug } from "./debug";
import pRetry from "p-retry";
import { wait } from "@latticexyz/common/utils";

export async function ensureContract({
client,
Expand All @@ -24,10 +26,21 @@ export async function ensureContract({

debug("deploying", label, "at", address);
return [
await sendTransaction(client, {
chain: client.chain ?? null,
to: deployer,
data: concatHex([salt, bytecode]),
}),
await pRetry(
() =>
sendTransaction(client, {
chain: client.chain ?? null,
to: deployer,
data: concatHex([salt, bytecode]),
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to deploy ${label}, retrying in ${delay}ms...`);
await wait(delay);
},
}
),
];
}
56 changes: 40 additions & 16 deletions packages/cli/src/deploy/ensureFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { hexToResource, writeContract } from "@latticexyz/common";
import { WorldDeploy, WorldFunction, worldAbi } from "./common";
import { debug } from "./debug";
import { getFunctions } from "./getFunctions";
import pRetry from "p-retry";
import { wait } from "@latticexyz/common/utils";

export async function ensureFunctions({
client,
Expand Down Expand Up @@ -40,23 +42,45 @@ export async function ensureFunctions({
toAdd.map((func) => {
const { namespace } = hexToResource(func.systemId);
if (namespace === "") {
return writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerRootFunctionSelector",
args: [func.systemId, func.systemFunctionSignature, func.systemFunctionSelector],
});
return pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerRootFunctionSelector",
args: [func.systemId, func.systemFunctionSignature, func.systemFunctionSelector],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to register function ${func.signature}, retrying in ${delay}ms...`);
await wait(delay);
},
}
);
}
return writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerFunctionSelector",
args: [func.systemId, func.systemFunctionSignature],
});
return pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerFunctionSelector",
args: [func.systemId, func.systemFunctionSignature],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to register function ${func.signature}, retrying in ${delay}ms...`);
await wait(delay);
},
}
);
})
);
}
57 changes: 40 additions & 17 deletions packages/cli/src/deploy/ensureModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { writeContract } from "@latticexyz/common";
import { Module, WorldDeploy, worldAbi } from "./common";
import { ensureContract } from "./ensureContract";
import { debug } from "./debug";
import { uniqueBy } from "@latticexyz/common/utils";
import { uniqueBy, wait } from "@latticexyz/common/utils";
import pRetry from "p-retry";

export async function ensureModules({
client,
Expand All @@ -28,22 +29,44 @@ export async function ensureModules({
const installTxs = await Promise.all(
modules.map((mod) =>
mod.installAsRoot
? writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "installRootModule",
args: [mod.address, mod.installData],
})
: writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "installModule",
args: [mod.address, mod.installData],
})
? pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "installRootModule",
args: [mod.address, mod.installData],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to install root module ${mod.name}, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
: pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "installModule",
args: [mod.address, mod.installData],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to install module ${mod.name}, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
)
);

Expand Down
80 changes: 57 additions & 23 deletions packages/cli/src/deploy/ensureSystems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { debug } from "./debug";
import { resourceLabel } from "./resourceLabel";
import { getSystems } from "./getSystems";
import { getResourceAccess } from "./getResourceAccess";
import { uniqueBy } from "@latticexyz/common/utils";
import { uniqueBy, wait } from "@latticexyz/common/utils";
import pRetry from "p-retry";

export async function ensureSystems({
client,
Expand Down Expand Up @@ -54,22 +55,44 @@ export async function ensureSystems({

const accessTxs = await Promise.all([
...accessToRemove.map((access) =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
functionName: "revokeAccess",
args: [access.resourceId, access.address],
})
pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
functionName: "revokeAccess",
args: [access.resourceId, access.address],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to revoke access, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
),
...accessToAdd.map((access) =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
functionName: "grantAccess",
args: [access.resourceId, access.address],
})
pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
functionName: "grantAccess",
args: [access.resourceId, access.address],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to grant access, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
),
]);

Expand Down Expand Up @@ -114,14 +137,25 @@ export async function ensureSystems({
// then start registering systems
const registerTxs = await Promise.all(
missingSystems.map((system) =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerSystem",
args: [system.systemId, system.address, system.allowAll],
})
pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerSystem",
args: [system.systemId, system.address, system.allowAll],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to register system ${resourceLabel(system)}, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
)
);

Expand Down
43 changes: 28 additions & 15 deletions packages/cli/src/deploy/ensureTables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { valueSchemaToFieldLayoutHex, keySchemaToHex, valueSchemaToHex } from "@
import { debug } from "./debug";
import { resourceLabel } from "./resourceLabel";
import { getTables } from "./getTables";
import pRetry from "p-retry";
import { wait } from "@latticexyz/common/utils";

export async function ensureTables({
client,
Expand All @@ -29,21 +31,32 @@ export async function ensureTables({
debug("registering tables", missingTables.map(resourceLabel).join(", "));
return await Promise.all(
missingTables.map((table) =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerTable",
args: [
table.tableId,
valueSchemaToFieldLayoutHex(table.valueSchema),
keySchemaToHex(table.keySchema),
valueSchemaToHex(table.valueSchema),
Object.keys(table.keySchema),
Object.keys(table.valueSchema),
],
})
pRetry(
() =>
writeContract(client, {
chain: client.chain ?? null,
address: worldDeploy.address,
abi: worldAbi,
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
functionName: "registerTable",
args: [
table.tableId,
valueSchemaToFieldLayoutHex(table.valueSchema),
keySchemaToHex(table.keySchema),
valueSchemaToHex(table.valueSchema),
Object.keys(table.keySchema),
Object.keys(table.valueSchema),
],
}),
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to register table ${resourceLabel(table)}, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
)
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/runDeploy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from "node:path";
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { InferredOptionTypes, Options } from "yargs";
import { deploy } from "./deploy/deploy";
import { createWalletClient, http, Hex } from "viem";
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e1dc88e

Please sign in to comment.