diff --git a/CHANGELOG.md b/CHANGELOG.md index 06386f0ae..ae00ccb73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Added +- Added CircuitAnalysisModule for easy analysis of protocol circuits [#379](https://github.com/proto-kit/framework/pull/379) - Separated settlement and bridging functionally, so now settlement can be used without bridging [#376](https://github.com/proto-kit/framework/pull/376) - Added nightly releases via pkg.pr.new [#384](https://github.com/proto-kit/framework/pull/384) - Introduced Changelog [#378](https://github.com/proto-kit/framework/pull/378) diff --git a/packages/common/src/log.ts b/packages/common/src/log.ts index ed3c39ef1..a8659d239 100644 --- a/packages/common/src/log.ts +++ b/packages/common/src/log.ts @@ -28,6 +28,8 @@ function logProvable( // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (process.env?.IN_CI ?? false) { loglevel.setLevel("ERROR"); +} else { + loglevel.setLevel("INFO"); } const timeMap: Record = {}; diff --git a/packages/sequencer/src/helpers/CircuitAnalysisModule.ts b/packages/sequencer/src/helpers/CircuitAnalysisModule.ts new file mode 100644 index 000000000..c9b33572f --- /dev/null +++ b/packages/sequencer/src/helpers/CircuitAnalysisModule.ts @@ -0,0 +1,75 @@ +import { inject, injectable } from "tsyringe"; +import { RuntimeEnvironment } from "@proto-kit/module"; +import { log, mapSequential, PlainZkProgram } from "@proto-kit/common"; +import { + MandatoryProtocolModulesRecord, + Protocol, + ProtocolModulesRecord, + SettlementContractModule, + SettlementModulesRecord, +} from "@proto-kit/protocol"; + +@injectable() +export class CircuitAnalysisModule { + public constructor( + @inject("Protocol") + private readonly protocol: Protocol< + ProtocolModulesRecord & MandatoryProtocolModulesRecord + >, + @inject("Runtime") + private readonly runtime: RuntimeEnvironment + ) {} + + public async printSummary() { + const summary = await this.analyseMethods(); + log.info(summary); + } + + public async analyseMethods() { + const zkProgrammables = [ + this.runtime, + this.protocol.stateTransitionProver, + this.protocol.transactionProver, + this.protocol.blockProver, + ]; + + const zkProgrammablePromises = await mapSequential( + zkProgrammables, + (withZkProgrammable) => + mapSequential( + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + withZkProgrammable.zkProgrammable.zkProgramFactory() as PlainZkProgram< + unknown, + unknown + >[], + async (program) => { + const result = await program.analyzeMethods(); + return [program.name, result] as const; + } + ) + ); + + const settlementModule = this.protocol.dependencyContainer.resolve< + SettlementContractModule + >("SettlementContractModule"); + + const contractPromises = await mapSequential( + Object.entries(settlementModule.getContractClasses()), + async ([key, clas]) => { + const result = await clas.analyzeMethods(); + return [key, result] as const; + } + ); + + const allResults = [...zkProgrammablePromises.flat(), ...contractPromises]; + + const summary = allResults.map(([program, result]) => { + const methods = Object.entries(result).map( + ([methodName, constraints]) => [methodName, constraints.rows] as const + ); + return [program, Object.fromEntries(methods)] as const; + }); + + return Object.fromEntries(summary); + } +} diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index 15b423ea7..a0fee0179 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -87,6 +87,7 @@ export * from "./helpers/query/NetworkStateQuery"; export * from "./helpers/query/NetworkStateTransportModule"; export * from "./helpers/query/BlockExplorerQuery"; export * from "./helpers/query/BlockExplorerTransportModule"; +export * from "./helpers/CircuitAnalysisModule"; export * from "./state/prefilled/PreFilledStateService"; export * from "./state/async/AsyncMerkleTreeStore"; export * from "./state/async/AsyncStateService"; diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 3e1c86f26..0b89e8871 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -56,6 +56,7 @@ import { VanillaTaskWorkerModules, Sequencer, InMemoryMinaSigner, + CircuitAnalysisModule, } from "../../src"; import { BlockProofSerializer } from "../../src/protocol/production/tasks/serializers/BlockProofSerializer"; import { testingSequencerModules } from "../TestingSequencer"; @@ -313,6 +314,12 @@ export const settlementTestFn = ( let user0Nonce = 0; let acc0L2Nonce = 0; + it.skip("Print constraint summary", async () => { + await appChain.protocol.dependencyContainer + .resolve(CircuitAnalysisModule) + .printSummary(); + }); + it("should throw error", async () => { const additionalAddresses = tokenConfig === undefined