From f9797cd96f71278e7985cf78b290ce3244a066f8 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 2 Mar 2026 13:17:41 -0300 Subject: [PATCH 1/7] Moved tasks to better folders --- .../tasks/{ => compile}/CircuitCompilerTask.ts | 11 +++++------ .../worker/{worker => }/startup/CloseWorkerError.ts | 0 .../{worker => }/startup/WorkerRegistrationFlow.ts | 4 ++-- .../{worker => }/startup/WorkerRegistrationTask.ts | 12 ++++++------ 4 files changed, 13 insertions(+), 14 deletions(-) rename packages/sequencer/src/protocol/production/tasks/{ => compile}/CircuitCompilerTask.ts (93%) rename packages/sequencer/src/worker/{worker => }/startup/CloseWorkerError.ts (100%) rename packages/sequencer/src/worker/{worker => }/startup/WorkerRegistrationFlow.ts (90%) rename packages/sequencer/src/worker/{worker => }/startup/WorkerRegistrationTask.ts (91%) diff --git a/packages/sequencer/src/protocol/production/tasks/CircuitCompilerTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts similarity index 93% rename from packages/sequencer/src/protocol/production/tasks/CircuitCompilerTask.ts rename to packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts index 2e14928d8..08f41697d 100644 --- a/packages/sequencer/src/protocol/production/tasks/CircuitCompilerTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts @@ -21,15 +21,14 @@ import { ContractArgsRegistry, } from "@proto-kit/protocol"; -import { TaskSerializer } from "../../../worker/flow/Task"; -import { UnpreparingTask } from "../../../worker/flow/UnpreparingTask"; -import { SignedSettlementPermissions } from "../../../settlement/permissions/SignedSettlementPermissions"; -import { ProvenSettlementPermissions } from "../../../settlement/permissions/ProvenSettlementPermissions"; - +import { TaskSerializer } from "../../../../worker/flow/Task"; +import { UnpreparingTask } from "../../../../worker/flow/UnpreparingTask"; +import { SignedSettlementPermissions } from "../../../../settlement/permissions/SignedSettlementPermissions"; +import { ProvenSettlementPermissions } from "../../../../settlement/permissions/ProvenSettlementPermissions"; import { ArtifactRecordSerializer, SerializedArtifactRecord, -} from "./serializers/ArtifactionRecordSerializer"; +} from "../serializers/ArtifactionRecordSerializer"; export type CompilerTaskParams = { existingArtifacts: ArtifactRecord; diff --git a/packages/sequencer/src/worker/worker/startup/CloseWorkerError.ts b/packages/sequencer/src/worker/startup/CloseWorkerError.ts similarity index 100% rename from packages/sequencer/src/worker/worker/startup/CloseWorkerError.ts rename to packages/sequencer/src/worker/startup/CloseWorkerError.ts diff --git a/packages/sequencer/src/worker/worker/startup/WorkerRegistrationFlow.ts b/packages/sequencer/src/worker/startup/WorkerRegistrationFlow.ts similarity index 90% rename from packages/sequencer/src/worker/worker/startup/WorkerRegistrationFlow.ts rename to packages/sequencer/src/worker/startup/WorkerRegistrationFlow.ts index 17340300e..be6133a06 100644 --- a/packages/sequencer/src/worker/worker/startup/WorkerRegistrationFlow.ts +++ b/packages/sequencer/src/worker/startup/WorkerRegistrationFlow.ts @@ -1,8 +1,8 @@ import { injectable } from "tsyringe"; import { log } from "@proto-kit/common"; -import { Closeable } from "../../../sequencer/builder/Closeable"; -import { FlowCreator } from "../../flow/Flow"; +import { Closeable } from "../../sequencer/builder/Closeable"; +import { FlowCreator } from "../flow/Flow"; import { WorkerRegistrationTask, diff --git a/packages/sequencer/src/worker/worker/startup/WorkerRegistrationTask.ts b/packages/sequencer/src/worker/startup/WorkerRegistrationTask.ts similarity index 91% rename from packages/sequencer/src/worker/worker/startup/WorkerRegistrationTask.ts rename to packages/sequencer/src/worker/startup/WorkerRegistrationTask.ts index 3d4474717..370d95b5e 100644 --- a/packages/sequencer/src/worker/worker/startup/WorkerRegistrationTask.ts +++ b/packages/sequencer/src/worker/startup/WorkerRegistrationTask.ts @@ -15,18 +15,18 @@ import { } from "@proto-kit/protocol"; import { VerificationKey } from "o1js"; -import { Task } from "../../flow/Task"; -import { AbstractStartupTask } from "../../flow/AbstractStartupTask"; +import { Task } from "../flow/Task"; +import { AbstractStartupTask } from "../flow/AbstractStartupTask"; import { VerificationKeyJSON, VerificationKeySerializer, -} from "../../../protocol/production/tasks/serializers/VerificationKeySerializer"; +} from "../../protocol/production/tasks/serializers/VerificationKeySerializer"; import { ArtifactRecordSerializer, SerializedArtifactRecord, -} from "../../../protocol/production/tasks/serializers/ArtifactionRecordSerializer"; -import { SignedSettlementPermissions } from "../../../settlement/permissions/SignedSettlementPermissions"; -import { ProvenSettlementPermissions } from "../../../settlement/permissions/ProvenSettlementPermissions"; +} from "../../protocol/production/tasks/serializers/ArtifactionRecordSerializer"; +import { SignedSettlementPermissions } from "../../settlement/permissions/SignedSettlementPermissions"; +import { ProvenSettlementPermissions } from "../../settlement/permissions/ProvenSettlementPermissions"; import { CloseWorkerError } from "./CloseWorkerError"; From efcbfff937ebddd0cb9e52a4390665cbf9752b59 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 2 Mar 2026 18:20:35 -0300 Subject: [PATCH 2/7] Granularized compile tasks --- packages/sequencer/src/index.ts | 4 + ...tCompilerTask.ts => CircuitCompileTask.ts} | 91 ++---------------- .../tasks/compile/ProtocolCompileTask.ts | 28 ++++++ .../tasks/compile/RuntimeCompileTask.ts | 30 ++++++ .../tasks/compile/SettlementCompileTask.ts | 94 +++++++++++++++++++ .../src/sequencer/SequencerStartupModule.ts | 38 ++++---- .../src/sequencer/SettlementStartupModule.ts | 5 +- .../worker/worker/LocalTaskWorkerModule.ts | 14 ++- 8 files changed, 199 insertions(+), 105 deletions(-) rename packages/sequencer/src/protocol/production/tasks/compile/{CircuitCompilerTask.ts => CircuitCompileTask.ts} (53%) create mode 100644 packages/sequencer/src/protocol/production/tasks/compile/ProtocolCompileTask.ts create mode 100644 packages/sequencer/src/protocol/production/tasks/compile/RuntimeCompileTask.ts create mode 100644 packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index 7da10194e..0c477b8ff 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -47,6 +47,10 @@ export * from "./protocol/production/tasks/serializers/RuntimeVerificationKeyAtt export * from "./protocol/production/tasks/serializers/StateTransitionParametersSerializer"; export * from "./protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer"; export * from "./protocol/production/tasks/serializers/VerificationKeySerializer"; +export * from "./protocol/production/tasks/compile/CircuitCompileTask"; +export * from "./protocol/production/tasks/compile/ProtocolCompileTask"; +export * from "./protocol/production/tasks/compile/RuntimeCompileTask"; +export * from "./protocol/production/tasks/compile/SettlementCompileTask"; export * from "./protocol/production/trigger/BlockTrigger"; export * from "./protocol/production/trigger/ManualBlockTrigger"; export * from "./protocol/production/trigger/TimedBlockTrigger"; diff --git a/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompileTask.ts similarity index 53% rename from packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts rename to packages/sequencer/src/protocol/production/tasks/compile/CircuitCompileTask.ts index 08f41697d..b6cdc656c 100644 --- a/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompilerTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/compile/CircuitCompileTask.ts @@ -1,22 +1,15 @@ -import { inject, injectable, Lifecycle, scoped } from "tsyringe"; -import { Runtime } from "@proto-kit/module"; import { log, mapSequential, - StringKeyOf, ArtifactRecord, CompileRegistry, CompilableModule, safeParseJson, - reduceSequential, } from "@proto-kit/common"; import { - MandatorySettlementModulesRecord, Protocol, - SettlementContractModule, RuntimeVerificationKeyRootService, MandatoryProtocolModulesRecord, - type SettlementModulesRecord, BridgingSettlementContractArgs, ContractArgsRegistry, } from "@proto-kit/protocol"; @@ -32,32 +25,24 @@ import { export type CompilerTaskParams = { existingArtifacts: ArtifactRecord; - targets: string[]; runtimeVKRoot?: string; isSignedSettlement?: boolean; }; -@injectable() -@scoped(Lifecycle.ContainerScoped) -export class CircuitCompilerTask extends UnpreparingTask< +export abstract class CircuitCompileTask extends UnpreparingTask< CompilerTaskParams, ArtifactRecord > { - public name = "compiledCircuit"; - - public constructor( - @inject("Runtime") protected readonly runtime: Runtime, - @inject("Protocol") + protected constructor( protected readonly protocol: Protocol, - private readonly compileRegistry: CompileRegistry, - private readonly contractArgsRegistry: ContractArgsRegistry + protected readonly compileRegistry: CompileRegistry, + protected readonly contractArgsRegistry: ContractArgsRegistry ) { super(); } public inputSerializer(): TaskSerializer { type CompilerTaskParamsJSON = { - targets: string[]; runtimeVKRoot?: string; existingArtifacts: SerializedArtifactRecord; isSignedSettlement?: boolean; @@ -67,7 +52,6 @@ export class CircuitCompilerTask extends UnpreparingTask< return { toJSON: (input) => JSON.stringify({ - targets: input.targets, runtimeVKRoot: input.runtimeVKRoot, existingArtifacts: serializer.toJSON(input.existingArtifacts), isSignedSettlement: input.isSignedSettlement, @@ -75,7 +59,6 @@ export class CircuitCompilerTask extends UnpreparingTask< fromJSON: (input) => { const json = safeParseJson(input); return { - targets: json.targets, runtimeVKRoot: json.runtimeVKRoot, existingArtifacts: serializer.fromJSON(json.existingArtifacts), isSignedSettlement: json.isSignedSettlement, @@ -93,51 +76,7 @@ export class CircuitCompilerTask extends UnpreparingTask< }; } - public getSettlementTargets(): Record { - // We only care about the BridgeContract for now - later with caching, - // we might want to expand that to all protocol circuits - const container = this.protocol.dependencyContainer; - if (container.isRegistered("SettlementContractModule")) { - const settlementModule = container.resolve< - SettlementContractModule - >("SettlementContractModule"); - - // Needed so that all contractFactory functions are called, because - // they set static args on the contracts - settlementModule.getContractClasses(); - - const moduleNames = - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - settlementModule.moduleNames as StringKeyOf[]; - - const modules = moduleNames.map<[string, CompilableModule]>((name) => [ - `Settlement.${name}`, - settlementModule.resolve(name), - ]); - - const sumModule = { - compile: async (registry: CompileRegistry) => { - await reduceSequential<[string, CompilableModule], ArtifactRecord>( - modules, - async (record, [moduleName, module]) => { - log.info(`Compiling ${moduleName}`); - const artifacts = await module.compile(registry); - return { - ...record, - ...artifacts, - }; - }, - {} - ); - }, - }; - - const combinedModules = [...modules, ["Settlement", sumModule]]; - - return Object.fromEntries(combinedModules); - } - return {}; - } + public abstract getTargets(): Promise; public async compute(input: CompilerTaskParams): Promise { log.info("Computing VKs"); @@ -166,24 +105,12 @@ export class CircuitCompilerTask extends UnpreparingTask< ); } - // TODO make adaptive - const targets: Record = { - runtime: this.runtime, - protocol: this.protocol.blockProver, - ...this.getSettlementTargets(), - }; + const targets = await this.getTargets(); - const msg = `Compiling targets [${input.targets}]`; + const msg = `Compiling targets ${this.name}`; log.time(msg); - await mapSequential(input.targets, async (target) => { - if (target in targets) { - await targets[target].compile(this.compileRegistry); - } else { - log.info( - // TODO Is that right? Or should we check that the bridge exists on the sequencer side? - `Compile target ${target} not found, skipping` - ); - } + await mapSequential(targets, async (target) => { + await target.compile(this.compileRegistry); }); log.timeEnd.info(msg); diff --git a/packages/sequencer/src/protocol/production/tasks/compile/ProtocolCompileTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/ProtocolCompileTask.ts new file mode 100644 index 000000000..fba628ca9 --- /dev/null +++ b/packages/sequencer/src/protocol/production/tasks/compile/ProtocolCompileTask.ts @@ -0,0 +1,28 @@ +import { inject, injectable, Lifecycle, scoped } from "tsyringe"; +import { CompilableModule, CompileRegistry } from "@proto-kit/common"; +import { + ContractArgsRegistry, + MandatoryProtocolModulesRecord, + Protocol, +} from "@proto-kit/protocol"; + +import { CircuitCompileTask } from "./CircuitCompileTask"; + +@injectable() +@scoped(Lifecycle.ContainerScoped) +export class ProtocolCompileTask extends CircuitCompileTask { + public name = "compile-protocol"; + + public constructor( + @inject("Protocol") + protocol: Protocol, + compileRegistry: CompileRegistry, + contractArgsRegistry: ContractArgsRegistry + ) { + super(protocol, compileRegistry, contractArgsRegistry); + } + + public async getTargets(): Promise { + return [this.protocol.blockProver]; + } +} diff --git a/packages/sequencer/src/protocol/production/tasks/compile/RuntimeCompileTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/RuntimeCompileTask.ts new file mode 100644 index 000000000..3002c9137 --- /dev/null +++ b/packages/sequencer/src/protocol/production/tasks/compile/RuntimeCompileTask.ts @@ -0,0 +1,30 @@ +import { inject, injectable, Lifecycle, scoped } from "tsyringe"; +import { CompilableModule, CompileRegistry } from "@proto-kit/common"; +import { Runtime } from "@proto-kit/module"; +import { + ContractArgsRegistry, + MandatoryProtocolModulesRecord, + Protocol, +} from "@proto-kit/protocol"; + +import { CircuitCompileTask } from "./CircuitCompileTask"; + +@injectable() +@scoped(Lifecycle.ContainerScoped) +export class RuntimeCompileTask extends CircuitCompileTask { + public name = "compile-runtime"; + + public constructor( + @inject("Runtime") protected readonly runtime: Runtime, + @inject("Protocol") + protocol: Protocol, + compileRegistry: CompileRegistry, + contractArgsRegistry: ContractArgsRegistry + ) { + super(protocol, compileRegistry, contractArgsRegistry); + } + + public async getTargets(): Promise { + return [this.runtime]; + } +} diff --git a/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts new file mode 100644 index 000000000..629ff7132 --- /dev/null +++ b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts @@ -0,0 +1,94 @@ +import { inject, injectable, Lifecycle, scoped } from "tsyringe"; +import { + ArtifactRecord, + CompilableModule, + CompileRegistry, + log, + reduceSequential, + StringKeyOf, +} from "@proto-kit/common"; +import { + ContractArgsRegistry, + MandatoryProtocolModulesRecord, + MandatorySettlementModulesRecord, + Protocol, + SettlementContractModule, + SettlementModulesRecord, +} from "@proto-kit/protocol"; + +import { BatchProducerModule } from "../../BatchProducerModule"; + +import { CircuitCompileTask } from "./CircuitCompileTask"; + +@injectable() +@scoped(Lifecycle.ContainerScoped) +export class SettlementCompileTask extends CircuitCompileTask { + public name = "compile-settlement"; + + public constructor( + @inject("Protocol") + protocol: Protocol, + compileRegistry: CompileRegistry, + contractArgsRegistry: ContractArgsRegistry, + @inject("BatchProducerModule", { isOptional: true }) + batchProducerModule: BatchProducerModule | undefined + ) { + super(protocol, compileRegistry, contractArgsRegistry); + + const container = this.protocol.dependencyContainer; + if ( + !container.isRegistered("SettlementContractModule") && + // Disable this check for the sequencer + batchProducerModule === undefined + ) { + throw new Error( + "SettlementContractModule not configured but SettlementCompilerTask is - fix the configuration" + ); + } + } + + public getSettlementTargets(): CompilableModule[] { + // We only care about the BridgeContract for now - later with caching, + // we might want to expand that to all protocol circuits + const container = this.protocol.dependencyContainer; + const settlementModule = container.resolve< + SettlementContractModule + >("SettlementContractModule"); + + // Needed so that all contractFactory functions are called, because + // they set static args on the contracts + settlementModule.getContractClasses(); + + const moduleNames = + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + settlementModule.moduleNames as StringKeyOf[]; + + const modules = moduleNames.map<[string, CompilableModule]>((name) => [ + `Settlement.${name}`, + settlementModule.resolve(name), + ]); + + const sumModule = { + compile: async (registry: CompileRegistry) => { + await reduceSequential<[string, CompilableModule], ArtifactRecord>( + modules, + async (record, [moduleName, module]) => { + log.info(`Compiling ${moduleName}`); + const artifacts = await module.compile(registry); + return { + ...record, + ...artifacts, + }; + }, + {} + ); + }, + }; + + return [sumModule]; + } + + public async getTargets(): Promise { + return this.getSettlementTargets(); + } +} diff --git a/packages/sequencer/src/sequencer/SequencerStartupModule.ts b/packages/sequencer/src/sequencer/SequencerStartupModule.ts index 603835f7a..07043976f 100644 --- a/packages/sequencer/src/sequencer/SequencerStartupModule.ts +++ b/packages/sequencer/src/sequencer/SequencerStartupModule.ts @@ -15,14 +15,15 @@ import { } from "@proto-kit/common"; import { Flow, FlowCreator } from "../worker/flow/Flow"; -import { WorkerRegistrationFlow } from "../worker/worker/startup/WorkerRegistrationFlow"; -import { - CircuitCompilerTask, - CompilerTaskParams, -} from "../protocol/production/tasks/CircuitCompilerTask"; +import { WorkerRegistrationFlow } from "../worker/startup/WorkerRegistrationFlow"; import { VerificationKeyService } from "../protocol/runtime/RuntimeVerificationKeyService"; import type { MinaBaseLayer } from "../protocol/baselayer/MinaBaseLayer"; import { NoopBaseLayer } from "../protocol/baselayer/NoopBaseLayer"; +import { RuntimeCompileTask } from "../protocol/production/tasks/compile/RuntimeCompileTask"; +import { ProtocolCompileTask } from "../protocol/production/tasks/compile/ProtocolCompileTask"; +import { SettlementCompileTask } from "../protocol/production/tasks/compile/SettlementCompileTask"; +import { CompilerTaskParams } from "../protocol/production/tasks/compile/CircuitCompileTask"; +import { Task } from "../worker/flow/Task"; import { SequencerModule, sequencerModule } from "./builder/SequencerModule"; import { Closeable, closeable } from "./builder/Closeable"; @@ -37,7 +38,9 @@ export class SequencerStartupModule private readonly flowCreator: FlowCreator, @inject("Protocol") private readonly protocol: Protocol, - private readonly compileTask: CircuitCompilerTask, + private readonly runtimeCompilerTask: RuntimeCompileTask, + private readonly protocolCompilerTask: ProtocolCompileTask, + private readonly settlementCompilerTask: SettlementCompileTask, private readonly verificationKeyService: VerificationKeyService, private readonly registrationFlow: WorkerRegistrationFlow, private readonly compileRegistry: CompileRegistry, @@ -52,21 +55,25 @@ export class SequencerStartupModule private async pushCompileTask( flow: Flow<{}>, + task: Task, payload: CompilerTaskParams ): Promise { return await flow.withFlow(async (res, rej) => { - await flow.pushTask(this.compileTask, payload, async (result) => { + await flow.pushTask(task, payload, async (result) => { res(result); }); }); } public async compileRuntime(flow: Flow<{}>) { - const artifacts = await this.pushCompileTask(flow, { - existingArtifacts: {}, - targets: ["runtime"], - runtimeVKRoot: undefined, - }); + const artifacts = await this.pushCompileTask( + flow, + this.runtimeCompilerTask, + { + existingArtifacts: {}, + runtimeVKRoot: undefined, + } + ); // Init runtime VK tree await this.verificationKeyService.initializeVKTree(artifacts); @@ -104,10 +111,9 @@ export class SequencerStartupModule }; await flow.pushTask( - this.compileTask, + this.protocolCompilerTask, { existingArtifacts: {}, - targets: ["protocol"], runtimeVKRoot: runtimeVkTreeRoot.toString(), }, async (protocolResult) => { @@ -117,10 +123,9 @@ export class SequencerStartupModule ); await flow.pushTask( - this.compileTask, + this.settlementCompilerTask, { existingArtifacts: {}, - targets: ["Settlement.BridgeContract"], runtimeVKRoot: undefined, isSignedSettlement, }, @@ -167,6 +172,7 @@ export class SequencerStartupModule log.info("Protocol circuits compiled"); + // TODO Why is this not in SettlementStartupModule? // Init BridgeContract vk for settlement contract const bridgeVk = protocolBridgeArtifacts.BridgeContract; if (bridgeVk !== undefined) { diff --git a/packages/sequencer/src/sequencer/SettlementStartupModule.ts b/packages/sequencer/src/sequencer/SettlementStartupModule.ts index 1936fb3c1..bdc3bee6e 100644 --- a/packages/sequencer/src/sequencer/SettlementStartupModule.ts +++ b/packages/sequencer/src/sequencer/SettlementStartupModule.ts @@ -7,7 +7,7 @@ import { } from "@proto-kit/common"; import { FlowCreator } from "../worker/flow/Flow"; -import { CircuitCompilerTask } from "../protocol/production/tasks/CircuitCompilerTask"; +import { SettlementCompileTask } from "../protocol/production/tasks/compile/SettlementCompileTask"; @injectable() export class SettlementStartupModule { @@ -15,7 +15,7 @@ export class SettlementStartupModule { public constructor( private readonly compileRegistry: CompileRegistry, private readonly flowCreator: FlowCreator, - private readonly compileTask: CircuitCompilerTask + private readonly compileTask: SettlementCompileTask ) {} // TODO Compile only individual contracts - this however runs into the @@ -29,7 +29,6 @@ export class SettlementStartupModule { this.compileTask, { existingArtifacts: this.compileRegistry.getAllArtifacts(), - targets: ["Settlement"], runtimeVKRoot: undefined, }, async (result) => res(result) diff --git a/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts b/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts index 85fa05663..715ad045b 100644 --- a/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts +++ b/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts @@ -23,16 +23,18 @@ import { SettlementProvingTask } from "../../settlement/tasks/SettlementProvingT import { Task } from "../flow/Task"; import { TaskQueue } from "../queue/TaskQueue"; import { StateTransitionTask } from "../../protocol/production/tasks/StateTransitionTask"; -import { CircuitCompilerTask } from "../../protocol/production/tasks/CircuitCompilerTask"; import { closeable } from "../../sequencer/builder/Closeable"; import { StateTransitionReductionTask } from "../../protocol/production/tasks/StateTransitionReductionTask"; import { TransactionProvingTask } from "../../protocol/production/tasks/TransactionProvingTask"; import { BlockReductionTask } from "../../protocol/production/tasks/BlockReductionTask"; import { TransactionReductionTask } from "../../protocol/production/tasks/TransactionReductionTask"; +import { WorkerRegistrationTask } from "../startup/WorkerRegistrationTask"; +import { RuntimeCompileTask } from "../../protocol/production/tasks/compile/RuntimeCompileTask"; +import { ProtocolCompileTask } from "../../protocol/production/tasks/compile/ProtocolCompileTask"; +import { SettlementCompileTask } from "../../protocol/production/tasks/compile/SettlementCompileTask"; import { FlowTaskWorker } from "./FlowTaskWorker"; import { TaskWorkerModule } from "./TaskWorkerModule"; -import { WorkerRegistrationTask } from "./startup/WorkerRegistrationTask"; // Temporary workaround against the compiler emitting // import("common/dist") inside the library artifacts @@ -139,8 +141,9 @@ export class VanillaTaskWorkerModules { TransactionReductionTask, BlockReductionTask, NewBlockTask, - CircuitCompilerTask, WorkerRegistrationTask, + RuntimeCompileTask, + ProtocolCompileTask, } satisfies TaskWorkerModulesRecord; } @@ -148,6 +151,7 @@ export class VanillaTaskWorkerModules { return { ...VanillaTaskWorkerModules.withoutSettlement(), SettlementProvingTask, + SettlementCompileTask, } satisfies TaskWorkerModulesRecord; } @@ -161,8 +165,10 @@ export class VanillaTaskWorkerModules { NewBlockTask: {}, StateTransitionReductionTask: {}, SettlementProvingTask: {}, - CircuitCompilerTask: {}, WorkerRegistrationTask: {}, + RuntimeCompileTask: {}, + ProtocolCompileTask: {}, + SettlementCompileTask: {}, } satisfies ModulesConfig< ReturnType >; From 1b7ce8a4e6e770a4685d10c84e9f907cccd0cead Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 2 Mar 2026 19:04:30 -0300 Subject: [PATCH 3/7] Fixed bug when settlement is not configured --- .../src/sequencer/SequencerStartupModule.ts | 35 ++++++++++++------- .../test/integration/MempoolTxRemoved.test.ts | 1 + 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/sequencer/src/sequencer/SequencerStartupModule.ts b/packages/sequencer/src/sequencer/SequencerStartupModule.ts index 07043976f..9ddf893da 100644 --- a/packages/sequencer/src/sequencer/SequencerStartupModule.ts +++ b/packages/sequencer/src/sequencer/SequencerStartupModule.ts @@ -27,6 +27,7 @@ import { Task } from "../worker/flow/Task"; import { SequencerModule, sequencerModule } from "./builder/SequencerModule"; import { Closeable, closeable } from "./builder/Closeable"; +import { SettlementModule } from "../settlement/SettlementModule"; @sequencerModule() @closeable() @@ -48,7 +49,9 @@ export class SequencerStartupModule private readonly baseLayer: MinaBaseLayer | undefined, @inject("AreProofsEnabled") private readonly areProofsEnabled: AreProofsEnabled, - private readonly contractArgsRegistry: ContractArgsRegistry + private readonly contractArgsRegistry: ContractArgsRegistry, + @inject("SettlementModule", { isOptional: true }) + private readonly settlementModule: SettlementModule | undefined ) { super(); } @@ -108,6 +111,10 @@ export class SequencerStartupModule if (bridge !== undefined && protocol !== undefined) { res({ ...protocol, ...bridge }); } + // TODO Try to generalize stuff like this a bit more + if (this.settlementModule === undefined && protocol !== undefined) { + res(protocol); + } }; await flow.pushTask( @@ -122,18 +129,20 @@ export class SequencerStartupModule } ); - await flow.pushTask( - this.settlementCompilerTask, - { - existingArtifacts: {}, - runtimeVKRoot: undefined, - isSignedSettlement, - }, - async (bridgeResult) => { - results.bridge = bridgeResult; - resolveIfPossible(); - } - ); + if (this.settlementModule !== undefined) { + await flow.pushTask( + this.settlementCompilerTask, + { + existingArtifacts: {}, + runtimeVKRoot: undefined, + isSignedSettlement, + }, + async (bridgeResult) => { + results.bridge = bridgeResult; + resolveIfPossible(); + } + ); + } }); this.compileRegistry.addArtifactsRaw(result); return result; diff --git a/packages/sequencer/test/integration/MempoolTxRemoved.test.ts b/packages/sequencer/test/integration/MempoolTxRemoved.test.ts index 02fae71f5..ace902990 100644 --- a/packages/sequencer/test/integration/MempoolTxRemoved.test.ts +++ b/packages/sequencer/test/integration/MempoolTxRemoved.test.ts @@ -27,6 +27,7 @@ describe("mempool removal mechanism", () => { let trigger: ManualBlockTrigger; const createAppChain = async () => { + log.setLevel("TRACE"); const app = AppChain.from({ Sequencer: Sequencer.from(testingSequencerModules({})), Protocol: Protocol.from(Protocol.defaultModules()), From 2fdb5693ff76487c5a6a5a8aed24b9da9d0694ec Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 2 Mar 2026 22:55:27 -0300 Subject: [PATCH 4/7] Added missing export --- packages/sequencer/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index 0c477b8ff..0cf5a36d0 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -23,6 +23,8 @@ export * from "./worker/worker/FlowTaskWorker"; export * from "./worker/worker/LocalTaskWorkerModule"; export * from "./worker/worker/TaskWorkerModule"; export * from "./worker/worker/WorkerReadyModule"; +export * from "./worker/startup/WorkerRegistrationTask"; +export * from "./worker/startup/CloseWorkerError"; export * from "./protocol/baselayer/BaseLayer"; export * from "./protocol/baselayer/MinaBaseLayer"; export * from "./protocol/baselayer/NoopBaseLayer"; From 1ef6bb2fd554b2af801d89cadcbbdae9a451fbee Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 3 Mar 2026 12:21:54 -0300 Subject: [PATCH 5/7] Made startup flow serial because of sideloaded blockprover vk --- .../src/sequencer/SequencerStartupModule.ts | 97 ++++++++----------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/packages/sequencer/src/sequencer/SequencerStartupModule.ts b/packages/sequencer/src/sequencer/SequencerStartupModule.ts index 9ddf893da..6e8fce9f0 100644 --- a/packages/sequencer/src/sequencer/SequencerStartupModule.ts +++ b/packages/sequencer/src/sequencer/SequencerStartupModule.ts @@ -12,6 +12,7 @@ import { ChildVerificationKeyService, CompileRegistry, AreProofsEnabled, + CompileArtifact, } from "@proto-kit/common"; import { Flow, FlowCreator } from "../worker/flow/Flow"; @@ -92,57 +93,36 @@ export class SequencerStartupModule return root; } - private async compileProtocolAndBridge( - flow: Flow<{}>, - runtimeVkTreeRoot: bigint, - isSignedSettlement?: boolean - ) { - // Can happen in parallel - type ParallelResult = { - protocol?: ArtifactRecord; - bridge?: ArtifactRecord; - }; - + private async compileBridge(flow: Flow<{}>, isSignedSettlement?: boolean) { const result = await flow.withFlow(async (res, rej) => { - const results: ParallelResult = {}; - - const resolveIfPossible = () => { - const { bridge, protocol } = results; - if (bridge !== undefined && protocol !== undefined) { - res({ ...protocol, ...bridge }); - } - // TODO Try to generalize stuff like this a bit more - if (this.settlementModule === undefined && protocol !== undefined) { - res(protocol); + await flow.pushTask( + this.settlementCompilerTask, + { + existingArtifacts: this.compileRegistry.getAllArtifacts(), + runtimeVKRoot: undefined, + isSignedSettlement, + }, + async (bridgeResult) => { + res(bridgeResult); } - }; + ); + }); + this.compileRegistry.addArtifactsRaw(result); + return result; + } + private async compileProtocol(flow: Flow<{}>, runtimeVkTreeRoot: bigint) { + const result = await flow.withFlow(async (res, rej) => { await flow.pushTask( this.protocolCompilerTask, { - existingArtifacts: {}, + existingArtifacts: this.compileRegistry.getAllArtifacts(), runtimeVKRoot: runtimeVkTreeRoot.toString(), }, async (protocolResult) => { - results.protocol = protocolResult; - resolveIfPossible(); + res(protocolResult); } ); - - if (this.settlementModule !== undefined) { - await flow.pushTask( - this.settlementCompilerTask, - { - existingArtifacts: {}, - runtimeVKRoot: undefined, - isSignedSettlement, - }, - async (bridgeResult) => { - results.bridge = bridgeResult; - resolveIfPossible(); - } - ); - } }); this.compileRegistry.addArtifactsRaw(result); return result; @@ -173,27 +153,32 @@ export class SequencerStartupModule const root = await this.compileRuntime(flow); - const protocolBridgeArtifacts = await this.compileProtocolAndBridge( - flow, - root, - isSignedSettlement - ); + await this.compileProtocol(flow, root); - log.info("Protocol circuits compiled"); + let bridgeVk: CompileArtifact | undefined = undefined; - // TODO Why is this not in SettlementStartupModule? - // Init BridgeContract vk for settlement contract - const bridgeVk = protocolBridgeArtifacts.BridgeContract; - if (bridgeVk !== undefined) { - // TODO Inject CompileRegistry directly - this.contractArgsRegistry.addArgs( - "SettlementContract", - { - BridgeContractVerificationKey: bridgeVk.verificationKey, - } + if (this.settlementModule !== undefined) { + const bridgeArtifacts = await this.compileBridge( + flow, + isSignedSettlement ); + + // TODO Why is this not in SettlementStartupModule? + // Init BridgeContract vk for settlement contract + bridgeVk = bridgeArtifacts.BridgeContract; + if (bridgeVk !== undefined) { + // TODO Inject CompileRegistry directly + this.contractArgsRegistry.addArgs( + "SettlementContract", + { + BridgeContractVerificationKey: bridgeVk.verificationKey, + } + ); + } } + log.info("Protocol circuits compiled"); + await this.registrationFlow.start({ runtimeVerificationKeyRoot: root, bridgeContractVerificationKey: bridgeVk?.verificationKey, From b5f07865231d6c39b8cb546fa7b23a243500e935 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 3 Mar 2026 17:06:23 -0300 Subject: [PATCH 6/7] Added childvkservice setup for settlement compile task --- .../production/tasks/compile/SettlementCompileTask.ts | 8 ++++++-- packages/sequencer/test/settlement/Settlement-only.ts | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts index 629ff7132..ee7a21707 100644 --- a/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts @@ -1,6 +1,7 @@ import { inject, injectable, Lifecycle, scoped } from "tsyringe"; import { ArtifactRecord, + ChildVerificationKeyService, CompilableModule, CompileRegistry, log, @@ -18,7 +19,7 @@ import { import { BatchProducerModule } from "../../BatchProducerModule"; -import { CircuitCompileTask } from "./CircuitCompileTask"; +import { CircuitCompileTask, CompilerTaskParams } from "./CircuitCompileTask"; @injectable() @scoped(Lifecycle.ContainerScoped) @@ -31,7 +32,8 @@ export class SettlementCompileTask extends CircuitCompileTask { compileRegistry: CompileRegistry, contractArgsRegistry: ContractArgsRegistry, @inject("BatchProducerModule", { isOptional: true }) - batchProducerModule: BatchProducerModule | undefined + batchProducerModule: BatchProducerModule | undefined, + private readonly childVkService: ChildVerificationKeyService ) { super(protocol, compileRegistry, contractArgsRegistry); @@ -89,6 +91,8 @@ export class SettlementCompileTask extends CircuitCompileTask { } public async getTargets(): Promise { + this.childVkService.setCompileRegistry(this.compileRegistry); + return this.getSettlementTargets(); } } diff --git a/packages/sequencer/test/settlement/Settlement-only.ts b/packages/sequencer/test/settlement/Settlement-only.ts index c894bfbcf..ddae5a758 100644 --- a/packages/sequencer/test/settlement/Settlement-only.ts +++ b/packages/sequencer/test/settlement/Settlement-only.ts @@ -39,6 +39,7 @@ import { SettlementModule, SettlementProvingTask, VanillaTaskWorkerModules, + SettlementCompileTask, } from "../../src"; import { Withdrawals } from "./mocks/Withdrawals"; @@ -80,6 +81,7 @@ export const settlementOnlyTestFn = ( }, { SettlementProvingTask, + SettlementCompileTask, } ) ); From 0e18960f72f52141e41f4602b837ba45ad56f3ac Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 3 Mar 2026 17:26:08 -0300 Subject: [PATCH 7/7] linting --- .../protocol/production/tasks/compile/SettlementCompileTask.ts | 2 +- packages/sequencer/src/sequencer/SequencerStartupModule.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts index ee7a21707..9fbfa1168 100644 --- a/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/compile/SettlementCompileTask.ts @@ -19,7 +19,7 @@ import { import { BatchProducerModule } from "../../BatchProducerModule"; -import { CircuitCompileTask, CompilerTaskParams } from "./CircuitCompileTask"; +import { CircuitCompileTask } from "./CircuitCompileTask"; @injectable() @scoped(Lifecycle.ContainerScoped) diff --git a/packages/sequencer/src/sequencer/SequencerStartupModule.ts b/packages/sequencer/src/sequencer/SequencerStartupModule.ts index 6e8fce9f0..2e37e8bf1 100644 --- a/packages/sequencer/src/sequencer/SequencerStartupModule.ts +++ b/packages/sequencer/src/sequencer/SequencerStartupModule.ts @@ -25,10 +25,10 @@ import { ProtocolCompileTask } from "../protocol/production/tasks/compile/Protoc import { SettlementCompileTask } from "../protocol/production/tasks/compile/SettlementCompileTask"; import { CompilerTaskParams } from "../protocol/production/tasks/compile/CircuitCompileTask"; import { Task } from "../worker/flow/Task"; +import { SettlementModule } from "../settlement/SettlementModule"; import { SequencerModule, sequencerModule } from "./builder/SequencerModule"; import { Closeable, closeable } from "./builder/Closeable"; -import { SettlementModule } from "../settlement/SettlementModule"; @sequencerModule() @closeable()