Skip to content

Commit

Permalink
Merge branch 'develop' into feature/improve_tx_validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ejMina226 committed Oct 16, 2024
2 parents 3ef48c4 + b8bb115 commit 2433476
Show file tree
Hide file tree
Showing 46 changed files with 1,056 additions and 256 deletions.
26 changes: 15 additions & 11 deletions packages/common/src/zkProgrammable/ZkProgrammable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,25 @@ export abstract class ZkProgrammable<
> {
public abstract get appChain(): AreProofsEnabled | undefined;

public abstract zkProgramFactory(): PlainZkProgram<PublicInput, PublicOutput>;
public abstract zkProgramFactory(): PlainZkProgram<
PublicInput,
PublicOutput
>[];

@Memoize()
public get zkProgram(): PlainZkProgram<PublicInput, PublicOutput> {
public get zkProgram(): PlainZkProgram<PublicInput, PublicOutput>[] {
const zkProgram = this.zkProgramFactory();

if (!this.appChain) {
throw errors.appChainNotSet(this.constructor.name);
}

return {
...zkProgram,
verify: verifyToMockable(zkProgram.verify, this.appChain),
compile: compileToMockable(zkProgram.compile, this.appChain),
};
return zkProgram.map((bucket) => {
if (!this.appChain) {
throw errors.appChainNotSet(this.constructor.name);
}
return {
...bucket,
verify: verifyToMockable(bucket.verify, this.appChain),
compile: compileToMockable(bucket.compile, this.appChain),
};
});
}
}

Expand Down
15 changes: 12 additions & 3 deletions packages/common/src/zkProgrammable/provableMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ export function toProver(
return async function prover(this: ZkProgrammable<any, any>) {
const areProofsEnabled = this.appChain?.areProofsEnabled;
if (areProofsEnabled ?? false) {
const programProvableMethod = this.zkProgram.methods[methodName];
return await Reflect.apply(programProvableMethod, this, args);
for (const prog of this.zkProgram) {
if (Object.keys(prog.methods).includes(methodName)) {
const programProvableMethod = prog.methods[methodName];
// eslint-disable-next-line no-await-in-loop
return await Reflect.apply(programProvableMethod, this, args);
}
}
}

// create a mock proof by simulating method execution in JS
const publicOutput = await Reflect.apply(simulatedMethod, this, args);
const zkProgram =
this.zkProgram.find((prog) => {
return Object.keys(prog.methods).includes(methodName);
}) ?? this.zkProgram[0];

return new this.zkProgram.Proof({
return new zkProgram.Proof({
proof: MOCK_PROOF,

// TODO: provide undefined if public input is not used
Expand Down
59 changes: 30 additions & 29 deletions packages/common/test/zkProgrammable/ZkProgrammable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
AreProofsEnabled,
CompileArtifact,
MOCK_VERIFICATION_KEY,
PlainZkProgram,
ZkProgrammable,
} from "../../src/zkProgrammable/ZkProgrammable";
import { ProvableMethodExecutionContext } from "../../src/zkProgrammable/ProvableMethodExecutionContext";
Expand Down Expand Up @@ -85,38 +84,38 @@ class TestProgrammable extends ZkProgrammable<
fail: program.fail.bind(program),
};

return {
compile: program.compile.bind(program),
verify: program.verify.bind(program),
analyzeMethods: program.analyzeMethods.bind(program),
Proof: SelfProof,
methods,
};
return [
{
compile: program.compile.bind(program),
verify: program.verify.bind(program),
analyzeMethods: program.analyzeMethods.bind(program),
Proof: SelfProof,
methods,
},
];
}
}

class OtherTestProgrammable extends ZkProgrammable {
class OtherTestProgrammable extends ZkProgrammable<undefined, void> {
public appChain: AreProofsEnabled = appChainMock;

public constructor(public testProgrammable: TestProgrammable) {
super();
}

proofType = this.testProgrammable.zkProgram[0].Proof;

@provableMethod()
public async bar(
testProgrammableProof: InstanceType<
typeof this.testProgrammable.zkProgram.Proof
>
) {
public async bar(testProgrammableProof: InstanceType<typeof this.proofType>) {
testProgrammableProof.verify();
}

public zkProgramFactory(): PlainZkProgram {
public zkProgramFactory() {
const program = ZkProgram({
name: "testprogram2",
methods: {
bar: {
privateInputs: [this.testProgrammable.zkProgram.Proof],
privateInputs: [this.testProgrammable.zkProgram[0].Proof],
method: this.bar.bind(this),
},
},
Expand All @@ -128,13 +127,15 @@ class OtherTestProgrammable extends ZkProgrammable {

const SelfProof = ZkProgram.Proof(program);

return {
compile: program.compile.bind(program),
verify: program.verify.bind(program),
analyzeMethods: program.analyzeMethods.bind(program),
Proof: SelfProof,
methods,
};
return [
{
compile: program.compile.bind(program),
verify: program.verify.bind(program),
analyzeMethods: program.analyzeMethods.bind(program),
Proof: SelfProof,
methods,
},
];
}
}

Expand Down Expand Up @@ -184,7 +185,7 @@ describe("zkProgrammable", () => {
testProgrammable = new TestProgrammable();
testProgrammable.appChain.setProofsEnabled(areProofsEnabled);
zkProgramFactorySpy = jest.spyOn(testProgrammable, "zkProgramFactory");
artifact = await testProgrammable.zkProgram.compile();
artifact = await testProgrammable.zkProgram[0].compile();
}, 500_000);

describe("zkProgramFactory", () => {
Expand All @@ -211,7 +212,7 @@ describe("zkProgrammable", () => {
it("if proofs are disabled, it should successfully verify mock proofs", async () => {
expect.assertions(1);

const proof = new testProgrammable.zkProgram.Proof({
const proof = new testProgrammable.zkProgram[0].Proof({
proof: MOCK_PROOF,

publicInput: new TestPublicInput({
Expand All @@ -225,7 +226,7 @@ describe("zkProgrammable", () => {
maxProofsVerified: 0,
});

const verified = await testProgrammable.zkProgram.verify(proof);
const verified = await testProgrammable.zkProgram[0].verify(proof);

expect(verified).toBe(shouldVerifyMockProofs);

Expand All @@ -249,7 +250,7 @@ describe("zkProgrammable", () => {
describe("zkProgram interoperability", () => {
beforeAll(async () => {
otherTestProgrammable = new OtherTestProgrammable(testProgrammable);
await otherTestProgrammable.zkProgram.compile();
await otherTestProgrammable.zkProgram[0].compile();
}, 500_000);

it("should successfully pass proof of one zkProgram as input to another zkProgram", async () => {
Expand All @@ -263,7 +264,7 @@ describe("zkProgrammable", () => {
.current()
.result.prove<Proof<TestPublicInput, TestPublicOutput>>();
const testProofVerified =
await testProgrammable.zkProgram.verify(testProof);
await testProgrammable.zkProgram[0].verify(testProof);

// execute bar
await otherTestProgrammable.bar(testProof);
Expand All @@ -273,7 +274,7 @@ describe("zkProgrammable", () => {
.current()
.result.prove<Proof<undefined, void>>();
const otherTestProofVerified =
await otherTestProgrammable.zkProgram.verify(otherTestProof);
await otherTestProgrammable.zkProgram[0].verify(otherTestProof);

expect(testProof.publicOutput.bar.toString()).toBe(
testPublicInput.foo.toString()
Expand Down
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
104 changes: 58 additions & 46 deletions packages/library/src/hooks/RuntimeFeeAnalyzerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,55 +80,67 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule<RuntimeFeeAnal
networkState: NetworkState.empty(),
});

const analyzedMethods =
await this.runtime.zkProgrammable.zkProgram.analyzeMethods();

container.resolve(RuntimeMethodExecutionContext).clear();

const [values, indexes] = Object.keys(
this.runtime.zkProgrammable.zkProgram.methods
).reduce<[FeeTreeValues, FeeIndexes]>(
// eslint-disable-next-line @typescript-eslint/no-shadow
([values, indexes], combinedMethodName, index) => {
const { rows } = analyzedMethods[combinedMethodName];
// const rows = 1000;
const [moduleName, methodName] = combinedMethodName.split(".");
const methodId = this.runtime.methodIdResolver.getMethodId(
moduleName,
methodName
);

/**
* Determine the fee config for the given method id, and merge it with
* the default fee config.
*/
return [
{
...values,

[methodId.toString()]: {
methodId,

baseFee:
this.config.methods[combinedMethodName]?.baseFee ??
this.config.baseFee,

perWeightUnitFee:
this.config.methods[combinedMethodName]?.perWeightUnitFee ??
this.config.perWeightUnitFee,

weight:
this.config.methods[combinedMethodName]?.weight ?? BigInt(rows),
const [values, indexes] =
await this.runtime.zkProgrammable.zkProgram.reduce<
Promise<[FeeTreeValues, FeeIndexes]>
>(
async (accum, program) => {
const [valuesProg, indexesProg] = await accum;
const analyzedMethods = await program.analyzeMethods();
const [valuesMeth, indexesMeth] = Object.keys(program.methods).reduce<
[FeeTreeValues, FeeIndexes]
>(
// eslint-disable-next-line @typescript-eslint/no-shadow
([values, indexes], combinedMethodName, index) => {
const { rows } = analyzedMethods[combinedMethodName];
// const rows = 1000;
const [moduleName, methodName] = combinedMethodName.split(".");
const methodId = this.runtime.methodIdResolver.getMethodId(
moduleName,
methodName
);

/**
* Determine the fee config for the given method id, and merge it with
* the default fee config.
*/
return [
{
...values,

[methodId.toString()]: {
methodId,

baseFee:
this.config.methods[combinedMethodName]?.baseFee ??
this.config.baseFee,

perWeightUnitFee:
this.config.methods[combinedMethodName]
?.perWeightUnitFee ?? this.config.perWeightUnitFee,

weight:
this.config.methods[combinedMethodName]?.weight ??
BigInt(rows),
},
},
{
...indexes,
[methodId.toString()]: BigInt(index),
},
];
},
},
{
...indexes,
[methodId.toString()]: BigInt(index),
},
];
},
[{}, {}]
);
[{}, {}]
);
return [
{ ...valuesProg, ...valuesMeth },
{ ...indexesProg, ...indexesMeth },
];
},
Promise.resolve([{}, {}])
);

const tree = new FeeTree(new InMemoryMerkleTreeStorage());

Expand Down
6 changes: 6 additions & 0 deletions packages/library/src/sequencer/SimpleSequencerModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import {
BlockTrigger,
Database,
SequencerModule,
ProtocolStartupModule,
} from "@proto-kit/sequencer";
import { TypedClass, ModulesConfig } from "@proto-kit/common";

type PreconfiguredSimpleSequencerModulesRecord = {
Mempool: typeof PrivateMempool;
BatchProducerModule: typeof BatchProducerModule;
BlockProducerModule: typeof BlockProducerModule;
ProtocolStartupModule: TypedClass<
ProtocolStartupModule & SequencerModule<unknown>
>;
};

export type MinimumAdditionalSequencerModules = {
Expand Down Expand Up @@ -86,6 +90,7 @@ export class SimpleSequencerModules {
BlockTrigger,
TaskQueue,
...reducedModules,
ProtocolStartupModule,
} satisfies SimpleSequencerModulesRecord;
}

Expand All @@ -97,6 +102,7 @@ export class SimpleSequencerModules {

Mempool: {},
BatchProducerModule: {},
ProtocolStartupModule: {},
} satisfies ModulesConfig<PreconfiguredSimpleSequencerModulesRecord>;
}

Expand Down
Loading

0 comments on commit 2433476

Please sign in to comment.