Skip to content

Commit

Permalink
fix(cli): handle module already installed (#1769)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic authored Oct 13, 2023
1 parent ccc21e9 commit 4e2a170
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .changeset/heavy-eyes-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/cli": patch
---

Deploys now continue if they detect a `Module_AlreadyInstalled` revert error.
3 changes: 2 additions & 1 deletion packages/cli/src/deploy/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Abi, Address, Hex, padHex } from "viem";
import storeConfig from "@latticexyz/store/mud.config.js";
import worldConfig from "@latticexyz/world/mud.config.js";
import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json" assert { type: "json" };
import IModuleAbi from "@latticexyz/world-modules/out/IModule.sol/IModule.abi.json" assert { type: "json" };
import { Tables, configToTables } from "./configToTables";
import { StoreConfig, helloStoreEvent } from "@latticexyz/store";
import { WorldConfig, helloWorldEvent } from "@latticexyz/world";
Expand All @@ -14,7 +15,7 @@ export const worldTables = configToTables(worldConfig);

export const worldDeployEvents = [helloStoreEvent, helloWorldEvent] as const;

export const worldAbi = IBaseWorldAbi;
export const worldAbi = [...IBaseWorldAbi, ...IModuleAbi] as const;

export type WorldDeploy = {
readonly address: Address;
Expand Down
88 changes: 43 additions & 45 deletions packages/cli/src/deploy/ensureModules.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Client, Transport, Chain, Account, Hex } from "viem";
import { Client, Transport, Chain, Account, Hex, BaseError } from "viem";
import { writeContract } from "@latticexyz/common";
import { Module, WorldDeploy, worldAbi } from "./common";
import { debug } from "./debug";
import { wait } from "@latticexyz/common/utils";
import { isDefined, wait } from "@latticexyz/common/utils";
import pRetry from "p-retry";

export async function ensureModules({
Expand All @@ -17,49 +17,47 @@ export async function ensureModules({
if (!modules.length) return [];

debug("installing modules:", modules.map((mod) => mod.name).join(", "));
const installTxs = await Promise.all(
modules.map((mod) =>
mod.installAsRoot
? 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);
},
return (
await Promise.all(
modules.map((mod) =>
pRetry(
async () => {
try {
return mod.installAsRoot
? await 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],
})
: await 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],
});
} catch (error) {
if (error instanceof BaseError && error.message.includes("Module_AlreadyInstalled")) {
debug(`module ${mod.name} already installed`);
return;
}
throw error;
}
)
: 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);
},
}
)
},
{
retries: 3,
onFailedAttempt: async (error) => {
const delay = error.attemptNumber * 500;
debug(`failed to install module ${mod.name}, retrying in ${delay}ms...`);
await wait(delay);
},
}
)
)
)
);

return await Promise.all(installTxs);
).filter(isDefined);
}

0 comments on commit 4e2a170

Please sign in to comment.