From d3ab5c3783265b3e82b76157bccedeae6b0445e1 Mon Sep 17 00:00:00 2001 From: alvarius Date: Fri, 6 Sep 2024 22:02:55 +0100 Subject: [PATCH] feat(cli): speed up dev deploy with temporary automine during deploy (#3130) --- .changeset/real-pianos-yell.md | 5 ++ packages/cli/src/runDeploy.ts | 8 ++++ packages/cli/src/utils/enableAutomine.ts | 59 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 .changeset/real-pianos-yell.md create mode 100644 packages/cli/src/utils/enableAutomine.ts diff --git a/.changeset/real-pianos-yell.md b/.changeset/real-pianos-yell.md new file mode 100644 index 0000000000..130da6a63b --- /dev/null +++ b/.changeset/real-pianos-yell.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/cli": patch +--- + +Speed up deployment in development by temporarily enabling automine mode for the duration of the deployment. diff --git a/packages/cli/src/runDeploy.ts b/packages/cli/src/runDeploy.ts index 1dc7be3cb8..09566279bd 100644 --- a/packages/cli/src/runDeploy.ts +++ b/packages/cli/src/runDeploy.ts @@ -16,6 +16,7 @@ import { WorldDeploy } from "./deploy/common"; import { build } from "./build"; import { kmsKeyToAccount } from "@latticexyz/common/kms"; import { configToModules } from "./deploy/configToModules"; +import { enableAutomine } from "./utils/enableAutomine"; export const deployOptions = { configPath: { type: "string", desc: "Path to the MUD config file" }, @@ -133,6 +134,9 @@ export async function runDeploy(opts: DeployOptions): Promise { console.log("Deploying from", client.account.address); + // Attempt to enable automine for the duration of the deploy. Noop if automine is not available. + const { reset: resetMiningMode } = await enableAutomine(client); + const startTime = Date.now(); const worldDeploy = await deploy({ deployerAddress: opts.deployerAddress as Hex | undefined, @@ -155,6 +159,10 @@ export async function runDeploy(opts: DeployOptions): Promise { opts.kms ? true : false, ); } + + // Reset mining mode after deploy + await resetMiningMode(); + console.log(chalk.green("Deployment completed in", (Date.now() - startTime) / 1000, "seconds")); const deploymentInfo = { diff --git a/packages/cli/src/utils/enableAutomine.ts b/packages/cli/src/utils/enableAutomine.ts new file mode 100644 index 0000000000..15c7a2e498 --- /dev/null +++ b/packages/cli/src/utils/enableAutomine.ts @@ -0,0 +1,59 @@ +import { getAutomine, getBlock, setAutomine, setIntervalMining } from "viem/actions"; +import { debug, error } from "../debug"; +import { Client } from "viem"; +import { getAction } from "viem/utils"; + +type MiningMode = + | { + type: "automine"; + } + | { + type: "interval"; + blockTime: number; + }; + +export type EnableAutomineResult = { reset: () => Promise }; + +export async function enableAutomine(client: Client): Promise { + try { + debug("Enabling automine"); + const prevMiningMode = await getMiningMode(client); + await setMiningMode(client, { type: "automine" }); + return { + reset: () => { + debug("Disabling automine"); + return setMiningMode(client, prevMiningMode); + }, + }; + } catch (e) { + debug("Skipping automine"); + error(e); + return { reset: async () => void 0 }; + } +} + +async function getMiningMode(client: Client): Promise { + const localClient = { mode: "anvil", ...client }; // set default mode to "anvil", potential error is caught by enableAutomine + const isAutomine = await getAction(localClient, getAutomine, "getAutomine")({}); + if (isAutomine) { + return { type: "automine" }; + } + + const blockTime = await getBlockTime(client); + return { type: "interval", blockTime }; +} + +async function setMiningMode(client: Client, miningMode: MiningMode): Promise { + if (miningMode.type === "automine") { + await getAction(client, setAutomine, "setAutomine")(true); + } else { + await getAction(client, setIntervalMining, "setIntervalMining")({ interval: miningMode.blockTime }); + } +} + +async function getBlockTime(client: Client): Promise { + const latestBlock = await getAction(client, getBlock, "getBlock")({ blockTag: "latest" }); + const previousBlock = await getAction(client, getBlock, "getBlock")({ blockNumber: latestBlock.number - 1n }); + const blockTime = latestBlock.timestamp - previousBlock.timestamp; + return Number(blockTime); +}