Skip to content

Commit 9165dfa

Browse files
committed
refactor
1 parent 29c3abb commit 9165dfa

File tree

7 files changed

+401
-247
lines changed

7 files changed

+401
-247
lines changed

packages/cli/src/internal/commandParsers.ts

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import { standardRepos } from "../lib/repoDefinitions";
1414
import { shardManager } from "../lib/shardManager";
1515
import invariant from "tiny-invariant";
1616
import {
17-
WasmPrecompileService,
18-
WasmPrecompileServiceLive,
19-
} from "./effect/WasmPrecompileService.js";
17+
StartupCacheService,
18+
StartupCacheServiceLive,
19+
} from "./effect/StartupCacheService.js";
2020

2121
const logger = createLogger({ name: "commandParsers" });
2222

@@ -149,34 +149,52 @@ export class LaunchCommandParser {
149149
}
150150

151151
/**
152-
* Run WASM precompilation if enabled in launchSpec.
153-
* This uses an Effect-based service that caches precompiled artifacts by binary hash.
152+
* Cache startup artifacts if enabled in launchSpec.
153+
* This uses an Effect-based service that caches artifacts by binary hash.
154+
*
155+
* When cacheStartupArtifacts is enabled, this generates:
156+
* 1. Precompiled WASM for the runtime
157+
* 2. Raw chain spec to skip genesis WASM compilation
158+
*
159+
* This reduces startup from ~3s to ~200ms (~10x improvement).
154160
*/
155-
async withWasmPrecompile(): Promise<LaunchCommandParser> {
156-
if (!this.launchSpec.precompileWasm) {
161+
async withStartupCache(): Promise<LaunchCommandParser> {
162+
if (!this.launchSpec.cacheStartupArtifacts) {
157163
return this;
158164
}
159165

160166
// Skip for Docker images
161167
if (this.launchSpec.useDocker) {
162-
logger.warn("WASM precompilation is not supported for Docker images, skipping");
168+
logger.warn("Startup caching is not supported for Docker images, skipping");
163169
return this;
164170
}
165171

166-
// Extract chain argument from existing args
167-
const chainArg = this.args.find((arg) => arg.includes("--chain"));
172+
// Extract chain argument from existing args (e.g., "--chain=moonbase-dev")
173+
const chainArg = this.args.find((arg) => arg.startsWith("--chain"));
174+
// Check if using --dev flag
175+
const hasDevFlag = this.args.includes("--dev");
176+
// Extract chain name from --chain=XXX or --chain XXX
177+
const existingChainName = chainArg?.match(/--chain[=\s]?(\S+)/)?.[1];
168178

169-
const cacheDir = this.launchSpec.wasmCacheDir || path.join(process.cwd(), "tmp", "wasm-cache");
179+
// We can generate raw chain spec for both --dev mode and explicit --chain=XXX
180+
const canGenerateRawSpec = hasDevFlag || !!existingChainName;
170181

171-
const program = WasmPrecompileService.pipe(
182+
const cacheDir =
183+
this.launchSpec.startupCacheDir || path.join(process.cwd(), "tmp", "startup-cache");
184+
185+
const program = StartupCacheService.pipe(
172186
Effect.flatMap((service) =>
173-
service.getPrecompiledPath({
187+
service.getCachedArtifacts({
174188
binPath: this.launchSpec.binPath,
175189
chainArg,
176190
cacheDir,
191+
// Generate raw chain spec for faster startup (works for both --dev and --chain=XXX)
192+
generateRawChainSpec: canGenerateRawSpec,
193+
// Pass dev mode flag for proper chain name detection
194+
isDevMode: hasDevFlag,
177195
})
178196
),
179-
Effect.provide(WasmPrecompileServiceLive)
197+
Effect.provide(StartupCacheServiceLive)
180198
);
181199

182200
try {
@@ -185,6 +203,28 @@ export class LaunchCommandParser {
185203
// Get the directory containing the precompiled wasm
186204
const precompiledDir = path.dirname(result.precompiledPath);
187205
this.overrideArg(`--wasmtime-precompiled=${precompiledDir}`);
206+
207+
// If we have a raw chain spec, use it for ~10x faster startup
208+
if (result.rawChainSpecPath) {
209+
if (hasDevFlag) {
210+
// Remove --dev flag and add equivalent flags
211+
this.args = this.args.filter((arg) => arg !== "--dev");
212+
this.overrideArg(`--chain=${result.rawChainSpecPath}`);
213+
// Add flags that --dev would normally set
214+
this.args.push("--alice");
215+
this.args.push("--force-authoring");
216+
this.overrideArg("--rpc-cors=all");
217+
// Use a deterministic node key for consistency
218+
this.overrideArg(
219+
"--node-key=0000000000000000000000000000000000000000000000000000000000000001"
220+
);
221+
} else if (existingChainName) {
222+
// Replace original --chain=XXX with --chain=<raw-spec-path>
223+
this.overrideArg(`--chain=${result.rawChainSpecPath}`);
224+
}
225+
logger.debug(`Using raw chain spec for ~10x faster startup: ${result.rawChainSpecPath}`);
226+
}
227+
188228
logger.debug(
189229
result.fromCache
190230
? `Using cached precompiled WASM: ${result.precompiledPath}`
@@ -216,7 +256,7 @@ export class LaunchCommandParser {
216256
const parsed = await parser
217257
.withPorts()
218258
.then((p) => p.withDefaultForkConfig().withLaunchOverrides())
219-
.then((p) => p.withWasmPrecompile());
259+
.then((p) => p.withStartupCache());
220260

221261
if (options.verbose) {
222262
parsed.print();

0 commit comments

Comments
 (0)