Skip to content

Commit 684b621

Browse files
committed
Enabled proven settlement
1 parent 4d63b5a commit 684b621

File tree

15 files changed

+280
-86
lines changed

15 files changed

+280
-86
lines changed

packages/common/src/compiling/CompileRegistry.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { inject, injectable, singleton } from "tsyringe";
22

3-
import { AreProofsEnabled } from "../zkProgrammable/ZkProgrammable";
3+
import {
4+
AreProofsEnabled,
5+
CompileArtifact,
6+
} from "../zkProgrammable/ZkProgrammable";
47

58
import {
69
ArtifactRecord,
@@ -38,7 +41,7 @@ export class CompileRegistry {
3841
return this.artifacts[target.name];
3942
}
4043

41-
public getArtifact(name: string) {
44+
public getArtifact(name: string): CompileArtifact | undefined {
4245
if (this.artifacts[name] === undefined) {
4346
throw new Error(
4447
`Artifact for ${name} not available, did you compile it via the CompileRegistry?`

packages/common/src/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ export function isSubtypeOfName(
176176
clas: TypedClass<unknown>,
177177
name: string
178178
): boolean {
179+
if (clas === undefined || clas === null) {
180+
return false;
181+
}
182+
179183
if (clas.name === name) {
180184
return true;
181185
}

packages/sequencer/src/protocol/baselayer/MinaBaseLayer.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { DependencyFactory } from "@proto-kit/common";
1+
import { AreProofsEnabled, DependencyFactory } from "@proto-kit/common";
22
import { Mina } from "o1js";
33
import { match } from "ts-pattern";
4+
import { inject } from "tsyringe";
45

56
import { MinaIncomingMessageAdapter } from "../../settlement/messages/MinaIncomingMessageAdapter";
6-
import { SequencerModule } from "../../sequencer/builder/SequencerModule";
7+
import {
8+
sequencerModule,
9+
SequencerModule,
10+
} from "../../sequencer/builder/SequencerModule";
711
import { MinaTransactionSender } from "../../settlement/transactions/MinaTransactionSender";
812
import { WithdrawalQueue } from "../../settlement/messages/WithdrawalQueue";
913

@@ -27,6 +31,7 @@ export interface MinaBaseLayerConfig {
2731
};
2832
}
2933

34+
@sequencerModule()
3035
export class MinaBaseLayer
3136
extends SequencerModule<MinaBaseLayerConfig>
3237
implements BaseLayer, DependencyFactory
@@ -35,6 +40,13 @@ export class MinaBaseLayer
3540

3641
public originalNetwork?: Parameters<typeof Mina.setActiveInstance>[0];
3742

43+
public constructor(
44+
@inject("AreProofsEnabled")
45+
private readonly areProofsEnabled: AreProofsEnabled
46+
) {
47+
super();
48+
}
49+
3850
public dependencies() {
3951
return {
4052
IncomingMessageAdapter: {
@@ -63,15 +75,18 @@ export class MinaBaseLayer
6375
const Network = await match(network)
6476
.with(
6577
{ type: "local" },
66-
async () => await Mina.LocalBlockchain({ proofsEnabled: false })
78+
async () =>
79+
await Mina.LocalBlockchain({
80+
proofsEnabled: this.areProofsEnabled.areProofsEnabled,
81+
})
6782
)
6883
.with({ type: "lightnet" }, async (lightnet) => {
6984
const net = Mina.Network({
7085
mina: lightnet.graphql,
7186
archive: lightnet.archive,
7287
lightnetAccountManager: lightnet.accountManager,
7388
});
74-
net.proofsEnabled = false;
89+
net.proofsEnabled = this.areProofsEnabled.areProofsEnabled;
7590
return net;
7691
})
7792
.with({ type: "remote" }, async (remote) =>

packages/sequencer/src/protocol/production/BlockTaskFlowService.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
Protocol,
1010
StateTransitionProof,
1111
} from "@proto-kit/protocol";
12-
import { log } from "@proto-kit/common";
12+
import { log, MOCK_PROOF } from "@proto-kit/common";
1313

1414
import { TaskQueue } from "../../worker/queue/TaskQueue";
1515
import { Flow, FlowCreator } from "../../worker/flow/Flow";
@@ -194,7 +194,11 @@ export class BlockTaskFlowService {
194194
this.flowCreator
195195
);
196196
blockMergingFlow.onCompletion(async (result) => {
197-
log.debug(`Block generation finished, with proof ${result.proof}`); // TODO Remove result logging
197+
const printableProof =
198+
result.proof === MOCK_PROOF
199+
? result.proof
200+
: result.toJSON().proof.slice(100);
201+
log.debug(`Block generation finished, with proof ${printableProof}`); // TODO Remove result logging
198202
flow.resolve(result);
199203
});
200204
blockMergingFlow.deferErrorsTo(flow);

packages/sequencer/src/protocol/production/tasks/CircuitCompilerTask.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CompileRegistry,
99
CompilableModule,
1010
safeParseJson,
11+
reduceSequential,
1112
} from "@proto-kit/common";
1213
import {
1314
MandatorySettlementModulesRecord,
@@ -132,11 +133,29 @@ export class CircuitCompilerTask extends UnpreparingTask<
132133
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
133134
settlementModule.moduleNames as StringKeyOf<MandatorySettlementModulesRecord>[];
134135

135-
const modules = moduleNames.map((name) => [
136+
const modules = moduleNames.map<[string, CompilableModule]>((name) => [
136137
`Settlement.${name}`,
137138
settlementModule.resolve(name),
138139
]);
139140

141+
const sumModule = {
142+
compile: async (registry: CompileRegistry) => {
143+
await reduceSequential<CompilableModule, ArtifactRecord>(
144+
modules.map(([, module]) => module),
145+
async (record, module) => {
146+
const artifacts = await module.compile(registry);
147+
return {
148+
...record,
149+
...artifacts,
150+
};
151+
},
152+
{}
153+
);
154+
},
155+
};
156+
157+
modules.push(["Settlement", sumModule]);
158+
140159
return Object.fromEntries(modules);
141160
}
142161
return {};

packages/sequencer/src/sequencer/SequencerStartupModule.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,6 @@ export class SequencerStartupModule extends SequencerModule {
136136
bridgeVk.verificationKey;
137137
}
138138

139-
const record = await this.pushCompileTask(flow, {
140-
existingArtifacts: this.compileRegistry.getAllArtifacts(),
141-
targets: ["Settlement.SettlementContract"],
142-
});
143-
144-
this.compileRegistry.addArtifactsRaw(record);
145-
146-
// TODO Compile all contracts and retrieve artifacts to enable crafting of
147-
// the deployments - edit: can also be done on-demand with the CompileTask
148-
149139
await this.registrationFlow.start({
150140
runtimeVerificationKeyRoot: root,
151141
bridgeContractVerificationKey: bridgeVk?.verificationKey,
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { injectable } from "tsyringe";
2+
import {
3+
ArtifactRecord,
4+
CompileArtifact,
5+
CompileRegistry,
6+
log,
7+
} from "@proto-kit/common";
8+
9+
import { FlowCreator } from "../worker/flow/Flow";
10+
import { CircuitCompilerTask } from "../protocol/production/tasks/CircuitCompilerTask";
11+
12+
@injectable()
13+
export class SettlementStartupModule {
14+
public constructor(
15+
private readonly compileRegistry: CompileRegistry,
16+
private readonly flowCreator: FlowCreator,
17+
private readonly compileTask: CircuitCompilerTask
18+
) {}
19+
20+
// TODO Compile only individual contracts - this however runs into the
21+
// unlinkability issue from module name to artifact name
22+
// although - the settlement proving task currently also only works if
23+
// all contracts that a tx touches are compiled on that worker instance
24+
private async compile() {
25+
const flow = this.flowCreator.createFlow("compile-deploy", {});
26+
const artifacts = await flow.withFlow<ArtifactRecord>(async (res) => {
27+
await flow.pushTask(
28+
this.compileTask,
29+
{
30+
existingArtifacts: this.compileRegistry.getAllArtifacts(),
31+
targets: ["Settlement"],
32+
runtimeVKRoot: undefined,
33+
},
34+
async (result) => res(result)
35+
);
36+
});
37+
this.compileRegistry.addArtifactsRaw(artifacts);
38+
return artifacts;
39+
}
40+
41+
private async getArtifacts(retry: boolean): Promise<{
42+
SettlementSmartContract: CompileArtifact;
43+
DispatchSmartContract: CompileArtifact;
44+
}> {
45+
const settlementVerificationKey = this.compileRegistry.getArtifact(
46+
"SettlementSmartContract"
47+
);
48+
const dispatchVerificationKey = this.compileRegistry.getArtifact(
49+
"DispatchSmartContract"
50+
);
51+
52+
if (
53+
settlementVerificationKey === undefined ||
54+
dispatchVerificationKey === undefined
55+
) {
56+
if (!retry) {
57+
log.info(
58+
"Settlement Contracts not yet compiled, initializing compilation"
59+
);
60+
await this.compile();
61+
return await this.getArtifacts(true);
62+
}
63+
throw new Error(
64+
"Settlement contract verification keys not available for deployment"
65+
);
66+
}
67+
68+
return {
69+
SettlementSmartContract: settlementVerificationKey,
70+
DispatchSmartContract: dispatchVerificationKey,
71+
};
72+
}
73+
74+
public async retrieveVerificationKeys() {
75+
return await this.getArtifacts(false);
76+
}
77+
}

packages/sequencer/src/settlement/SettlementModule.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
log,
2828
AreProofsEnabled,
2929
DependencyFactory,
30-
CompileRegistry,
3130
} from "@proto-kit/common";
3231
import truncate from "lodash/truncate";
3332

@@ -41,6 +40,7 @@ import { Batch, SettleableBatch } from "../storage/model/Batch";
4140
import { BlockProofSerializer } from "../protocol/production/helpers/BlockProofSerializer";
4241
import { Settlement } from "../storage/model/Settlement";
4342
import { FeeStrategy } from "../protocol/baselayer/fees/FeeStrategy";
43+
import { SettlementStartupModule } from "../sequencer/SettlementStartupModule";
4444

4545
import { IncomingMessageAdapter } from "./messages/IncomingMessageAdapter";
4646
import { MinaTransactionSender } from "./transactions/MinaTransactionSender";
@@ -97,7 +97,7 @@ export class SettlementModule
9797
@inject("AreProofsEnabled") areProofsEnabled: AreProofsEnabled,
9898
@inject("FeeStrategy")
9999
private readonly feeStrategy: FeeStrategy,
100-
private readonly compileRegistry: CompileRegistry
100+
private readonly settlementStartupModule: SettlementStartupModule
101101
) {
102102
super();
103103
this.utils = new SettlementUtils(areProofsEnabled, baseLayer);
@@ -253,8 +253,6 @@ export class SettlementModule
253253

254254
const nonce = options?.nonce ?? 0;
255255

256-
// const verificationKey:
257-
258256
const sm = this.protocol.dependencyContainer.resolve<
259257
SettlementContractModule<MandatorySettlementModulesRecord>
260258
>("SettlementContractModule");
@@ -263,6 +261,9 @@ export class SettlementModule
263261
dispatch: dispatchKey.toPublicKey(),
264262
});
265263

264+
const verificationsKeys =
265+
await this.settlementStartupModule.retrieveVerificationKeys();
266+
266267
const permissions = this.utils.isSignedSettlement()
267268
? new SignedSettlementPermissions()
268269
: new ProvenSettlementPermissions();
@@ -277,13 +278,14 @@ export class SettlementModule
277278
async () => {
278279
AccountUpdate.fundNewAccount(feepayer, 2);
279280
await settlement.deploy({
280-
// TODO Create compilation task that generates those artifacts if proofs enabled
281-
verificationKey: undefined,
281+
verificationKey:
282+
verificationsKeys.SettlementSmartContract.verificationKey,
282283
});
283284
settlement.account.permissions.set(permissions.settlementContract());
284285

285286
await dispatch.deploy({
286-
verificationKey: undefined,
287+
verificationKey:
288+
verificationsKeys.DispatchSmartContract.verificationKey,
287289
});
288290
dispatch.account.permissions.set(permissions.dispatchContract());
289291
}

0 commit comments

Comments
 (0)