Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganized VKTree services and implemented startup consumption of sequencer arguments for workers #208

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/deployment/src/queue/BullQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export class BullQueue
public createWorker(
name: string,
executor: (data: TaskPayload) => Promise<TaskPayload>,
options?: { concurrency: number }
options?: { concurrency?: number }
): Closeable {
const worker = new Worker<TaskPayload, string>(
const worker = new Worker<TaskPayload, TaskPayload>(
name,
async (job) => JSON.stringify(await executor(job.data)),
async (job) => await executor(job.data),
{
concurrency: options?.concurrency ?? 1,
connection: this.config.redis,
Expand Down
3 changes: 2 additions & 1 deletion packages/protocol/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export * from "./utils/StateTransitionReductionList";
export * from "./utils/utils";
export * from "./prover/block/BlockProver";
export * from "./prover/block/BlockProvable";
export * from "./prover/block/accummulators/RuntimeVerificationKeyTree";
export * from "./prover/block/accummulators/BlockHashMerkleTree";
export * from "./prover/block/services/RuntimeVerificationKeyRootService";
export * from "./prover/statetransition/StateTransitionProver";
export * from "./prover/statetransition/StateTransitionProvable";
export * from "./prover/statetransition/StateTransitionWitnessProvider";
Expand All @@ -29,7 +31,6 @@ export * from "./protocol/ProtocolModule";
export * from "./protocol/ProtocolEnvironment";
export * from "./protocol/ProvableTransactionHook";
export * from "./protocol/ProvableBlockHook";
export * from "./protocol/VerificationKeyService";
export * from "./state/context/TransitionMethodExecutionContext";
export * from "./state/context/RuntimeMethodExecutionContext";
export * from "./state/protocol/ProtocolState";
Expand Down
4 changes: 3 additions & 1 deletion packages/protocol/src/prover/block/BlockProvable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction";
import { NetworkState } from "../../model/network/NetworkState";

import { BlockHashMerkleTreeWitness } from "./accummulators/BlockHashMerkleTree";
import { RuntimeVerificationKeyAttestation } from "./accummulators/RuntimeVerificationKeyTree";

export class BlockProverPublicInput extends Struct({
transactionsHash: Field,
Expand Down Expand Up @@ -75,7 +76,8 @@ export interface BlockProvable
publicInput: BlockProverPublicInput,
stateProof: StateTransitionProof,
appProof: DynamicRuntimeProof,
executionData: BlockProverExecutionData
executionData: BlockProverExecutionData,
verificationKeyAttestation: RuntimeVerificationKeyAttestation
) => Promise<BlockProverPublicOutput>;

proveBlock: (
Expand Down
68 changes: 30 additions & 38 deletions packages/protocol/src/prover/block/BlockProver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ import {
ZkProgrammable,
} from "@proto-kit/common";

import {
MethodVKConfigData,
VerificationKeyService,
} from "../../protocol/VerificationKeyService";
import { DefaultProvableHashList } from "../../utils/ProvableHashList";
import { MethodPublicOutput } from "../../model/MethodPublicOutput";
import { ProtocolModule } from "../../protocol/ProtocolModule";
Expand Down Expand Up @@ -58,6 +54,12 @@ import {
BlockHashMerkleTreeWitness,
BlockHashTreeEntry,
} from "./accummulators/BlockHashMerkleTree";
import {
MethodVKConfigData,
MinimalVKTreeService,
RuntimeVerificationKeyAttestation,
} from "./accummulators/RuntimeVerificationKeyTree";
import { RuntimeVerificationKeyRootService } from "./services/RuntimeVerificationKeyRootService";

const errors = {
stateProofNotStartingAtZero: () =>
Expand Down Expand Up @@ -148,7 +150,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
public readonly runtime: ZkProgrammable<undefined, MethodPublicOutput>,
private readonly transactionHooks: ProvableTransactionHook<unknown>[],
private readonly blockHooks: ProvableBlockHook<unknown>[],
private readonly verificationKeyService: VerificationKeyService
private readonly verificationKeyService: MinimalVKTreeService
) {
super();
}
Expand All @@ -165,6 +167,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
* @param stateTransitionProof
* @param runtimeProof
* @param executionData
* @param verificationKey
* @returns The new BlockProver-state to be used as public output
*/
public async applyTransaction(
Expand Down Expand Up @@ -407,7 +410,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
publicInput: BlockProverPublicInput,
stateProof: StateTransitionProof,
runtimeProof: DynamicRuntimeProof,
executionData: BlockProverExecutionData
executionData: BlockProverExecutionData,
verificationKeyWitness: RuntimeVerificationKeyAttestation
): Promise<BlockProverPublicOutput> {
const state: BlockProverState = {
...publicInput,
Expand All @@ -418,35 +422,18 @@ export class BlockProverProgrammable extends ZkProgrammable<
"ExecutionData Networkstate doesn't equal public input hash"
);

const zkProgramConfig = Provable.witness(MethodVKConfigData, () =>
this.verificationKeyService.getVKConfig(
executionData.transaction.methodId.toBigInt()
)
);
const witness = Provable.witness(
VerificationKeyService.getWitnessType(),
() =>
this.verificationKeyService.getWitness(
executionData.transaction.methodId.toBigInt()
)
);
const vkRecord = Provable.witness(VerificationKey, () =>
this.verificationKeyService.getVkRecordEntry(
executionData.transaction.methodId.toBigInt()
)
);
// Verify the [methodId, vk] tuple against the baked-in vk tree root
const { verificationKey, witness: verificationKeyTreeWitness } =
verificationKeyWitness;

const root = Field(this.verificationKeyService.getRoot());
const calculatedRoot = witness.calculateRoot(zkProgramConfig.hash());
root.assertEquals(calculatedRoot, errors.invalidZkProgramTreeRoot());

zkProgramConfig.methodId.assertEquals(
executionData.transaction.methodId,
errors.invalidZkProgramConfigMethodId()
const calculatedRoot = verificationKeyTreeWitness.calculateRoot(
new MethodVKConfigData({
methodId: executionData.transaction.methodId,
vkHash: verificationKey.hash,
}).hash()
);
vkRecord.hash.assertEquals(zkProgramConfig.vkHash);

runtimeProof.verify(vkRecord);
root.assertEquals(calculatedRoot, errors.invalidZkProgramTreeRoot());

const bundleInclusionState = this.addTransactionToBundle(
state,
Expand All @@ -459,7 +446,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
stateProof,
runtimeProof,
executionData,
vkRecord
verificationKey
);

return new BlockProverPublicOutput({
Expand Down Expand Up @@ -817,19 +804,22 @@ export class BlockProverProgrammable extends ZkProgrammable<
StateTransitionProofClass,
RuntimeProofClass,
BlockProverExecutionData,
RuntimeVerificationKeyAttestation,
],

async method(
publicInput: BlockProverPublicInput,
stateProof: StateTransitionProof,
appProof: DynamicRuntimeProof,
executionData: BlockProverExecutionData
executionData: BlockProverExecutionData,
verificationKeyAttestation: RuntimeVerificationKeyAttestation
) {
return await proveTransaction(
publicInput,
stateProof,
appProof,
executionData
executionData,
verificationKeyAttestation
);
},
},
Expand Down Expand Up @@ -915,7 +905,7 @@ export class BlockProver extends ProtocolModule implements BlockProvable {
transactionHooks: ProvableTransactionHook<unknown>[],
@injectAll("ProvableBlockHook")
blockHooks: ProvableBlockHook<unknown>[],
verificationKeyService: VerificationKeyService
verificationKeyService: RuntimeVerificationKeyRootService
) {
super();
this.zkProgrammable = new BlockProverProgrammable(
Expand All @@ -932,13 +922,15 @@ export class BlockProver extends ProtocolModule implements BlockProvable {
publicInput: BlockProverPublicInput,
stateProof: StateTransitionProof,
appProof: DynamicRuntimeProof,
executionData: BlockProverExecutionData
executionData: BlockProverExecutionData,
verificationKeyAttestation: RuntimeVerificationKeyAttestation
): Promise<BlockProverPublicOutput> {
return this.zkProgrammable.proveTransaction(
publicInput,
stateProof,
appProof,
executionData
executionData,
verificationKeyAttestation
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { createMerkleTree } from "@proto-kit/common";
import { Field, Poseidon, Struct, VerificationKey } from "o1js";

export const treeFeeHeight = 10;
export class VKTree extends createMerkleTree(treeFeeHeight) {}
export class VKTreeWitness extends VKTree.WITNESS {}

export class RuntimeVerificationKeyAttestation extends Struct({
verificationKey: VerificationKey,
witness: VKTreeWitness,
}) {}

export class MethodVKConfigData extends Struct({
methodId: Field,
vkHash: Field,
}) {
public hash() {
return Poseidon.hash(MethodVKConfigData.toFields(this));
}
}

export interface MinimalVKTreeService {
getRoot: () => bigint;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { injectable, Lifecycle, scoped } from "tsyringe";

import { MinimalVKTreeService } from "../accummulators/RuntimeVerificationKeyTree";

@injectable()
@scoped(Lifecycle.ContainerScoped)
export class RuntimeVerificationKeyRootService implements MinimalVKTreeService {
private injectedRoot?: bigint;

public setRoot(root: bigint) {
this.injectedRoot = root;
}

public getRoot() {
if (this.injectedRoot === undefined) {
throw new Error("VKTree root not set");
}
return this.injectedRoot;
}
}
11 changes: 2 additions & 9 deletions packages/sdk/src/appChain/TestingAppChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
BlockProducerModule,
InMemoryDatabase,
SequencerModulesRecord,
VanillaTaskWorkerModules,
} from "@proto-kit/sequencer";
import { TypedClass } from "@proto-kit/common";
import { PrivateKey } from "o1js";
Expand Down Expand Up @@ -108,15 +109,7 @@ export class TestingAppChain<
BlockTrigger: {},
Mempool: {},
BatchProducerModule: {},
LocalTaskWorkerModule: {
StateTransitionTask: {},
RuntimeProvingTask: {},
StateTransitionReductionTask: {},
BlockReductionTask: {},
BlockProvingTask: {},
BlockBuildingTask: {},
CircuitCompilerTask: {},
},
LocalTaskWorkerModule: VanillaTaskWorkerModules.defaultConfig(),
BaseLayer: {},
BlockProducerModule: {},
TaskQueue: {
Expand Down
36 changes: 26 additions & 10 deletions packages/sequencer/src/protocol/ProtocolStartupModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@ import { inject } from "tsyringe";
import {
MandatoryProtocolModulesRecord,
Protocol,
VerificationKeyService,
VKRecord,
RuntimeVerificationKeyRootService,
} from "@proto-kit/protocol";
import { log } from "@proto-kit/common";
import { log, sleep } from "@proto-kit/common";

import {
SequencerModule,
sequencerModule,
} from "../sequencer/builder/SequencerModule";
import { FlowCreator } from "../worker/flow/Flow";
import { WorkerRegistrationFlow } from "../worker/WorkerRegistrationFlow";

import { CircuitCompilerTask } from "./production/tasks/CircuitCompilerTask";
import {
VerificationKeyService,
VKRecord,
} from "./runtime/RuntimeVerificationKeyService";

@sequencerModule()
export class ProtocolStartupModule extends SequencerModule {
private readonly verificationKeyService: VerificationKeyService;

public constructor(
private readonly flowCreator: FlowCreator,
@inject("Protocol") protocol: Protocol<MandatoryProtocolModulesRecord>,
private readonly compileTask: CircuitCompilerTask
@inject("Protocol")
private readonly protocol: Protocol<MandatoryProtocolModulesRecord>,
private readonly compileTask: CircuitCompilerTask,
private readonly verificationKeyService: VerificationKeyService,
private readonly registrationFlow: WorkerRegistrationFlow
) {
super();
this.verificationKeyService = protocol.dependencyContainer.resolve(
VerificationKeyService
);
}

public async start() {
Expand All @@ -44,5 +46,19 @@ export class ProtocolStartupModule extends SequencerModule {
log.info("Protocol circuits compiled");

await this.verificationKeyService.initializeVKTree(vks);

const root = this.verificationKeyService.getRoot();

this.protocol.dependencyContainer
.resolve(RuntimeVerificationKeyRootService)
.setRoot(root);

await this.registrationFlow.start({
runtimeVerificationKeyRoot: root,
});

await sleep(500);

log.info("Protocol circuits compiled successfully, commencing startup");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { CachedMerkleTreeStore } from "../../state/merkle/CachedMerkleTreeStore"
import { AsyncStateService } from "../../state/async/AsyncStateService";
import { AsyncMerkleTreeStore } from "../../state/async/AsyncMerkleTreeStore";
import { BlockResult, BlockWithResult } from "../../storage/model/Block";
import { VerificationKeyService } from "../runtime/RuntimeVerificationKeyService";

import { BlockProverParameters } from "./tasks/BlockProvingTask";
import { StateTransitionProofParameters } from "./tasks/StateTransitionTaskParameters";
Expand Down Expand Up @@ -82,7 +83,8 @@ export class BatchProducerModule extends SequencerModule {
private readonly blockTreeStore: AsyncMerkleTreeStore,
private readonly traceService: TransactionTraceService,
private readonly blockFlowService: BlockTaskFlowService,
private readonly blockProofSerializer: BlockProofSerializer
private readonly blockProofSerializer: BlockProofSerializer,
private readonly verificationKeyService: VerificationKeyService
) {
super();
}
Expand Down Expand Up @@ -248,6 +250,7 @@ export class BatchProducerModule extends SequencerModule {
const result = await this.traceService.createTransactionTrace(
tx,
stateServices,
this.verificationKeyService,
block.networkState.during,
bundleTracker,
eternalBundleTracker,
Expand Down
Loading