From d2e216004b0372ba941fab92388ea44d09a0e66a Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 10:34:33 +0300 Subject: [PATCH 01/63] feat: add type alias for FieldString and helper function for it --- packages/sequencer/src/helpers/utils.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/sequencer/src/helpers/utils.ts b/packages/sequencer/src/helpers/utils.ts index 686613d52..0f56401f2 100644 --- a/packages/sequencer/src/helpers/utils.ts +++ b/packages/sequencer/src/helpers/utils.ts @@ -194,3 +194,14 @@ export class PairProofTaskSerializer ); } } + +/** + * Type for serialized {@link Field}. + */ +export type FieldString = string; +/** + * + * @param value Value to be converted to {@link Field}. + * @returns + */ +export const FieldString = (value: number | string | bigint): FieldString => String(value); From 4336578574a3dd87053332d924e6077781cb0518 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 10:36:40 +0300 Subject: [PATCH 02/63] refactor: change Field typed properties to FieldString type --- packages/sequencer/src/storage/model/Block.ts | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index da2e44802..1913fd407 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -9,6 +9,7 @@ import { LinkedMerkleTree } from "@proto-kit/common"; import { PendingTransaction } from "../../mempool/PendingTransaction"; import { UntypedStateTransition } from "../../protocol/production/helpers/UntypedStateTransition"; +import { FieldString } from "../../helpers/utils"; export interface StateTransitionBatch { stateTransitions: UntypedStateTransition[]; @@ -31,23 +32,23 @@ export interface TransactionExecutionResult { // TODO Why is Block using Fields, but BlockResult bigints? Align that towards the best option export interface Block { - hash: Field; - previousBlockHash: Field | undefined; - height: Field; + hash: FieldString; + previousBlockHash: FieldString | undefined; + height: FieldString; networkState: { before: NetworkState; during: NetworkState; }; transactions: TransactionExecutionResult[]; - transactionsHash: Field; + transactionsHash: FieldString; - fromEternalTransactionsHash: Field; - fromBlockHashRoot: Field; - fromMessagesHash: Field; - fromStateRoot: Field; - toEternalTransactionsHash: Field; - toMessagesHash: Field; + fromEternalTransactionsHash: FieldString; + fromBlockHashRoot: FieldString; + fromMessagesHash: FieldString; + fromStateRoot: FieldString; + toEternalTransactionsHash: FieldString; + toMessagesHash: FieldString; beforeBlockStateTransitions: UntypedStateTransition[]; } @@ -59,7 +60,7 @@ export const Block = { }, hash(block: Omit): Field { - return Block.calculateHash(block.height, block.transactionsHash); + return Block.calculateHash(Field(block.height), Field(block.transactionsHash)); }, }; @@ -93,21 +94,21 @@ export const BlockWithResult = { createEmpty: () => ({ block: { - hash: Field(0), + hash: FieldString(0), - height: Field(0), - transactionsHash: Field(0), - fromEternalTransactionsHash: Field(0), - toEternalTransactionsHash: Field(0), + height: FieldString(0), + transactionsHash: FieldString(0), + fromEternalTransactionsHash: FieldString(0), + toEternalTransactionsHash: FieldString(0), transactions: [], networkState: { before: NetworkState.empty(), during: NetworkState.empty(), }, - fromBlockHashRoot: Field(BlockHashMerkleTree.EMPTY_ROOT), - fromMessagesHash: Field(0), - fromStateRoot: LinkedMerkleTree.EMPTY_ROOT, - toMessagesHash: ACTIONS_EMPTY_HASH, + fromBlockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), + fromMessagesHash: FieldString(0), + fromStateRoot: FieldString(LinkedMerkleTree.EMPTY_ROOT), + toMessagesHash: FieldString(ACTIONS_EMPTY_HASH), beforeBlockStateTransitions: [], previousBlockHash: undefined, From be7c06e06eb0699a654ae139b008f195667944b5 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 10:39:16 +0300 Subject: [PATCH 03/63] refactor: update codebase to use string properties of Block --- packages/indexer/src/IndexerNotifier.ts | 2 +- packages/indexer/src/tasks/IndexBlockTask.ts | 4 +- packages/indexer/test/IndexBlockTask.test.ts | 4 +- packages/indexer/test/IndexerNotifier.test.ts | 2 +- .../services/prisma/mappers/BlockMapper.ts | 40 +++++++++---------- .../src/handlers/HandlersExecutor.ts | 2 +- .../src/triggers/TimedProcessorTrigger.ts | 2 +- .../sdk/src/query/InMemoryBlockExplorer.ts | 9 +++-- .../src/mempool/private/PrivateMempool.ts | 6 +-- .../sequencing/BlockProducerModule.ts | 2 +- .../sequencing/BlockProductionService.ts | 21 +++++----- .../sequencing/BlockResultService.ts | 18 ++++----- .../production/tracing/BatchTracingService.ts | 7 ++-- .../production/tracing/BlockTracingService.ts | 8 ++-- .../integration/StorageIntegration.test.ts | 8 ++-- packages/stack/test/graphql/graphql.test.ts | 14 +++---- 16 files changed, 76 insertions(+), 73 deletions(-) diff --git a/packages/indexer/src/IndexerNotifier.ts b/packages/indexer/src/IndexerNotifier.ts index e29b6497a..38371bebb 100644 --- a/packages/indexer/src/IndexerNotifier.ts +++ b/packages/indexer/src/IndexerNotifier.ts @@ -36,7 +36,7 @@ export class IndexerNotifier extends SequencerModule> { this.sequencer.events.on("block-metadata-produced", async (block) => { log.debug( "Notifiying the indexer about block", - block.block.height.toBigInt() + block.block.height ); const payload = await inputSerializer.toJSON(block); const sequencerId = this.sequencerIdProvider.getSequencerId(); diff --git a/packages/indexer/src/tasks/IndexBlockTask.ts b/packages/indexer/src/tasks/IndexBlockTask.ts index edce4fb86..a65cfc681 100644 --- a/packages/indexer/src/tasks/IndexBlockTask.ts +++ b/packages/indexer/src/tasks/IndexBlockTask.ts @@ -35,11 +35,11 @@ export class IndexBlockTask await this.blockStorage.pushBlock(input.block); await this.blockStorage.pushResult(input.result); } catch (error) { - log.error("Failed to index block", input.block.height.toBigInt(), error); + log.error("Failed to index block", input.block.height, error); return; } - log.info(`Block ${input.block.height.toBigInt()} indexed sucessfully`); + log.info(`Block ${input.block.height} indexed sucessfully`); } public inputSerializer(): TaskSerializer { diff --git a/packages/indexer/test/IndexBlockTask.test.ts b/packages/indexer/test/IndexBlockTask.test.ts index b5432e5a3..12f506a39 100644 --- a/packages/indexer/test/IndexBlockTask.test.ts +++ b/packages/indexer/test/IndexBlockTask.test.ts @@ -54,8 +54,8 @@ describe("IndexBlockTask", () => { const storage = indexer.resolve("BlockStorage"); const latestBlock = await storage.getLatestBlock(); - expect(latestBlock?.block.hash.toBigInt()).toBe( - block.block.hash.toBigInt() + expect(latestBlock?.block.hash).toBe( + block.block.hash ); }); }); diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 31ab57210..fce8274b2 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -183,7 +183,7 @@ describe.skip("IndexerNotifier", () => { .resolve(IndexBlockTaskParametersSerializer) .fromJSON(addTaskSpy.mock.lastCall?.[0].payload!); - expect(block.height.toBigInt()).toBe(0n); + expect(block.height).toBe("0"); expect(block.transactions.length).toBe(2); }); }); diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index bd5ee9b06..448cfda26 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -29,18 +29,18 @@ export class BlockMapper implements ObjectMapper { ), }, - hash: Field(input.hash), - height: Field(input.height), - fromEternalTransactionsHash: Field(input.fromEternalTransactionsHash), - toEternalTransactionsHash: Field(input.toEternalTransactionsHash), - fromBlockHashRoot: Field(input.fromBlockHashRoot), - fromMessagesHash: Field(input.fromMessagesHash), - toMessagesHash: Field(input.toMessagesHash), - fromStateRoot: Field(input.fromStateRoot), + hash: input.hash, + height: input.height.toString(), + fromEternalTransactionsHash: input.fromEternalTransactionsHash, + toEternalTransactionsHash: input.toEternalTransactionsHash, + fromBlockHashRoot: input.fromBlockHashRoot, + fromMessagesHash: input.fromMessagesHash, + toMessagesHash: input.toMessagesHash, + fromStateRoot: input.fromStateRoot, - transactionsHash: Field(input.transactionsHash), + transactionsHash: input.transactionsHash, previousBlockHash: - input.parentHash !== null ? Field(input.parentHash) : undefined, + input.parentHash !== null ? input.parentHash : undefined, beforeBlockStateTransitions: this.stArrayMapper.mapIn( input.beforeBlockStateTransitions @@ -50,19 +50,19 @@ export class BlockMapper implements ObjectMapper { public mapOut(input: Block): PrismaBlock { return { - height: Number(input.height.toBigInt()), + height: Number(input.height), beforeNetworkState: NetworkState.toJSON(input.networkState.before), duringNetworkState: NetworkState.toJSON(input.networkState.during), - fromEternalTransactionsHash: input.fromEternalTransactionsHash.toString(), - toEternalTransactionsHash: input.toEternalTransactionsHash.toString(), - fromBlockHashRoot: input.fromBlockHashRoot.toString(), - fromMessagesHash: input.fromMessagesHash.toString(), - toMessagesHash: input.toMessagesHash.toString(), - fromStateRoot: input.fromStateRoot.toString(), + fromEternalTransactionsHash: input.fromEternalTransactionsHash, + toEternalTransactionsHash: input.toEternalTransactionsHash, + fromBlockHashRoot: input.fromBlockHashRoot, + fromMessagesHash: input.fromMessagesHash, + toMessagesHash: input.toMessagesHash, + fromStateRoot: input.fromStateRoot, - hash: input.hash.toString(), - transactionsHash: input.transactionsHash.toString(), - parentHash: input.previousBlockHash?.toString() ?? null, + hash: input.hash, + transactionsHash: input.transactionsHash, + parentHash: input.previousBlockHash ?? null, batchHeight: null, beforeBlockStateTransitions: this.stArrayMapper.mapOut( diff --git a/packages/processor/src/handlers/HandlersExecutor.ts b/packages/processor/src/handlers/HandlersExecutor.ts index a67612a8a..64d171e77 100644 --- a/packages/processor/src/handlers/HandlersExecutor.ts +++ b/packages/processor/src/handlers/HandlersExecutor.ts @@ -75,7 +75,7 @@ export class HandlersExecutor< ) { await client.block.create({ data: { - height: Number(block.block.height.toBigInt()), + height: Number(block.block.height), }, }); } diff --git a/packages/processor/src/triggers/TimedProcessorTrigger.ts b/packages/processor/src/triggers/TimedProcessorTrigger.ts index 7f3f59454..0b6912e7e 100644 --- a/packages/processor/src/triggers/TimedProcessorTrigger.ts +++ b/packages/processor/src/triggers/TimedProcessorTrigger.ts @@ -40,7 +40,7 @@ export class TimedProcessorTrigger extends ProcessorModule { } log.info( - `Produced block #${block.height.toBigInt()} (${block.transactions.length} txs)` + `Produced block #${block.height} (${block.transactions.length} txs)` ); this.prettyPrintBlockContents(block); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 18010fa28..7b909ecf2 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -35,6 +35,7 @@ import { TransactionExecutionResultStatus, TransactionExecutionService, } from "./TransactionExecutionService"; +import { FieldString } from "../../../helpers/utils"; function isIncludedTxs( x: TransactionExecutionResultStatus @@ -120,10 +121,10 @@ export class BlockProductionService { const blockState: BlockTrackers = { blockHashRoot: Field(lastResult.blockHashRoot), eternalTransactionsList: new TransactionHashList( - lastBlock.toEternalTransactionsHash + Field(lastBlock.toEternalTransactionsHash) ), transactionList: new TransactionHashList(), - incomingMessages: new MinaActionsHashList(lastBlock.toMessagesHash), + incomingMessages: new MinaActionsHashList(Field(lastBlock.toMessagesHash)), }; // Get used networkState by executing beforeBlock() hooks @@ -149,7 +150,7 @@ export class BlockProductionService { ); const previousBlockHash = - lastResult.blockHash === 0n ? undefined : Field(lastResult.blockHash); + lastResult.blockHash === 0n ? undefined : FieldString(lastResult.blockHash); if (executionResults.length === 0 && !allowEmptyBlocks) { log.info( @@ -164,16 +165,16 @@ export class BlockProductionService { const block: Omit = { transactions: includedTransactions, - transactionsHash: newBlockState.transactionList.commitment, + transactionsHash: FieldString(newBlockState.transactionList.commitment), fromEternalTransactionsHash: lastBlock.toEternalTransactionsHash, toEternalTransactionsHash: - newBlockState.eternalTransactionsList.commitment, + FieldString(newBlockState.eternalTransactionsList.commitment), height: - lastBlock.hash.toBigInt() !== 0n ? lastBlock.height.add(1) : Field(0), - fromBlockHashRoot: Field(lastResult.blockHashRoot), + FieldString(lastBlock.hash) !== "0" ? FieldString(BigInt(lastBlock.height) + 1n) : FieldString(0), + fromBlockHashRoot: FieldString(lastResult.blockHashRoot), fromMessagesHash: lastBlock.toMessagesHash, - fromStateRoot: Field(lastResult.stateRoot), - toMessagesHash: newBlockState.incomingMessages.commitment, + fromStateRoot: FieldString(lastResult.stateRoot), + toMessagesHash: FieldString(newBlockState.incomingMessages.commitment), previousBlockHash, networkState: { @@ -183,7 +184,7 @@ export class BlockProductionService { beforeBlockStateTransitions, }; - const hash = Block.hash(block); + const hash = Block.hash(block).toString(); const includedTxs = executionResults.map((x) => { const txHash = match(x) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 5419344bb..702293738 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -131,21 +131,21 @@ export class BlockResultService { ); // TODO This can be optimized a lot (we are only interested in the root at this step) - await blockHashInMemoryStore.preloadKey(block.height.toBigInt()); + await blockHashInMemoryStore.preloadKey(BigInt(block.height)); const blockHashTree = new BlockHashMerkleTree(blockHashInMemoryStore); blockHashTree.setLeaf( - block.height.toBigInt(), + BigInt(block.height), new BlockHashTreeEntry({ block: { - index: block.height, - transactionListHash: block.transactionsHash, + index: Field(block.height), + transactionListHash: Field(block.transactionsHash), }, closed: Bool(true), }).hash() ); - const blockHashWitness = blockHashTree.getWitness(block.height.toBigInt()); + const blockHashWitness = blockHashTree.getWitness(BigInt(block.height)); const newBlockHashRoot = blockHashTree.getRoot(); return { @@ -218,9 +218,9 @@ export class BlockResultService { { blockHashRoot, stateRoot: witnessedStateRoot, - incomingMessagesHash: block.toMessagesHash, - transactionsHash: block.transactionsHash, - eternalTransactionsHash: block.toEternalTransactionsHash, + incomingMessagesHash: Field(block.toMessagesHash), + transactionsHash: Field(block.transactionsHash), + eternalTransactionsHash: Field(block.toEternalTransactionsHash), }, block.networkState.during, stateService @@ -250,7 +250,7 @@ export class BlockResultService { afterBlockStateTransitions: stateTransitions.map((st) => UntypedStateTransition.fromStateTransition(st) ), - blockHash: block.hash.toBigInt(), + blockHash: BigInt(block.hash), }, treeStore: inMemoryStore, blockHashTreeStore: cachedBlockHashTreeStore, diff --git a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts index f54d52e6f..12ea078dc 100644 --- a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts @@ -19,6 +19,7 @@ import { BlockTracingState, } from "./BlockTracingService"; import { StateTransitionTracingService } from "./StateTransitionTracingService"; +import { Field } from "o1js"; type BatchTracingState = Omit; @@ -40,11 +41,11 @@ export class BatchTracingService { return { pendingSTBatches: new AppliedBatchHashList(), witnessedRoots: new WitnessedRootHashList(), - stateRoot: block.block.fromStateRoot, + stateRoot: Field(block.block.fromStateRoot), eternalTransactionsList: new TransactionHashList( - block.block.fromEternalTransactionsHash + Field(block.block.fromEternalTransactionsHash) ), - incomingMessages: new MinaActionsHashList(block.block.fromMessagesHash), + incomingMessages: new MinaActionsHashList(Field(block.block.fromMessagesHash)), networkState: block.block.networkState.before, }; } diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 8b6a98bbf..2cdae386e 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -59,10 +59,10 @@ export class BlockTracingService { ): Promise<[BlockTracingState, BlockTrace]> { const publicInput: BlockProverPublicInput = new BlockProverPublicInput({ stateRoot: state.stateRoot, - blockNumber: block.block.height, - blockHashRoot: block.block.fromBlockHashRoot, - eternalTransactionsHash: block.block.fromEternalTransactionsHash, - incomingMessagesHash: block.block.fromMessagesHash, + blockNumber: Field(block.block.height), + blockHashRoot: Field(block.block.fromBlockHashRoot), + eternalTransactionsHash: Field(block.block.fromEternalTransactionsHash), + incomingMessagesHash: Field(block.block.fromMessagesHash), transactionsHash: Field(0), networkStateHash: block.block.networkState.before.hash(), witnessedRootsHash: state.witnessedRoots.commitment, diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index b26a5008b..d2c312ed9 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -148,8 +148,8 @@ describe.each([["InMemory", InMemoryDatabase]])( const { block } = blocks[0]; - expect(block.hash.toBigInt()).toStrictEqual( - generatedBlock.hash.toBigInt() + expect(block.hash).toStrictEqual( + generatedBlock.hash ); const blockStorage = sequencer.resolve("BlockStorage") as BlockStorage; @@ -158,8 +158,8 @@ describe.each([["InMemory", InMemoryDatabase]])( ); expectDefined(block2); - expect(block2.hash.toBigInt()).toStrictEqual( - generatedBlock.hash.toBigInt() + expect(block2.hash).toStrictEqual( + generatedBlock.hash ); const stateDiff = collectStateDiff( diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index 2cbb2526f..e334e5f55 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -222,7 +222,7 @@ describe("graphql client test", () => { const block = await trigger.produceBlock(); const hash = block?.hash.toString()!; - const height = Number(block?.height.toBigInt()); + const height = Number(block?.height); const hashResult = await appChain.query.explorer.getBlock({ hash: hash }); const heightResult = await appChain.query.explorer.getBlock({ @@ -239,19 +239,19 @@ describe("graphql client test", () => { expect(blockTxHash).toBe(queryTxHash); // Block hashes should match - expect(block?.hash.toBigInt()).toBe(heightResult?.hash.toBigInt()); + expect(block?.hash).toBe(heightResult?.hash.toString()); // Block heights should match - expect(block?.height.toBigInt()).toBe(heightResult?.height.toBigInt()); + expect(block?.height).toBe(heightResult?.height.toString()); // Previous block hashes should match - expect(block?.previousBlockHash?.toBigInt()).toBe( - heightResult?.previousBlockHash?.toBigInt() + expect(block?.previousBlockHash).toBe( + heightResult?.previousBlockHash?.toString() ); // Transaction hashes should match - expect(block?.transactionsHash.toBigInt()).toBe( - heightResult?.transactionsHash.toBigInt() + expect(block?.transactionsHash).toBe( + heightResult?.transactionsHash.toString() ); // Both query methods should return the same result From 86f87db8f68c09d23b1d2a8a7dd8e5fff2d1d7ee Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 10:40:47 +0300 Subject: [PATCH 04/63] refactor: allow Field in FieldString input --- packages/sequencer/src/helpers/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sequencer/src/helpers/utils.ts b/packages/sequencer/src/helpers/utils.ts index 0f56401f2..a1dc946f7 100644 --- a/packages/sequencer/src/helpers/utils.ts +++ b/packages/sequencer/src/helpers/utils.ts @@ -204,4 +204,4 @@ export type FieldString = string; * @param value Value to be converted to {@link Field}. * @returns */ -export const FieldString = (value: number | string | bigint): FieldString => String(value); +export const FieldString = (value: number | string | bigint | Field): FieldString => String(value); From c29a51d26122766215072269bb364bff72a907f9 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 12:50:12 +0300 Subject: [PATCH 05/63] refactor: Infer JSON type of NetworkState and use in Block interface --- packages/protocol/src/model/network/NetworkState.ts | 4 +++- packages/sequencer/src/storage/model/Block.ts | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/protocol/src/model/network/NetworkState.ts b/packages/protocol/src/model/network/NetworkState.ts index b0213ac36..87c8be710 100644 --- a/packages/protocol/src/model/network/NetworkState.ts +++ b/packages/protocol/src/model/network/NetworkState.ts @@ -1,4 +1,4 @@ -import { Field, Poseidon, Struct, UInt64 } from "o1js"; +import { Field, InferJson, Poseidon, Struct, UInt64 } from "o1js"; import { RollupMerkleTree } from "@proto-kit/common"; export class CurrentBlock extends Struct({ @@ -31,3 +31,5 @@ export class NetworkState extends Struct({ }); } } + +export type NetworkStateJson = InferJson; diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 1913fd407..8ac0d60a5 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -4,6 +4,7 @@ import { BlockHashMerkleTree, BlockHashMerkleTreeWitness, NetworkState, + NetworkStateJson } from "@proto-kit/protocol"; import { LinkedMerkleTree } from "@proto-kit/common"; @@ -36,8 +37,8 @@ export interface Block { previousBlockHash: FieldString | undefined; height: FieldString; networkState: { - before: NetworkState; - during: NetworkState; + before: NetworkStateJson; + during: NetworkStateJson; }; transactions: TransactionExecutionResult[]; @@ -102,8 +103,8 @@ export const BlockWithResult = { toEternalTransactionsHash: FieldString(0), transactions: [], networkState: { - before: NetworkState.empty(), - during: NetworkState.empty(), + before: NetworkState.toJSON(NetworkState.empty()), + during: NetworkState.toJSON(NetworkState.empty()) , }, fromBlockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), fromMessagesHash: FieldString(0), From adc99a0e9f12b0b67a9880a3e9708c50bd3e5b50 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 14:26:17 +0300 Subject: [PATCH 06/63] refactor: update codebase for use of NetworkStateJson type --- .../services/prisma/mappers/BlockMapper.ts | 18 ++++++------- .../PrismaBlockProduction.test.ts | 26 +++++-------------- .../production/BatchProducerModule.ts | 4 +-- .../sequencing/BlockProductionService.ts | 4 +-- .../production/tracing/BatchTracingService.ts | 3 ++- .../production/tracing/BlockTracingService.ts | 17 ++++++++---- .../sequencer/test/settlement/Settlement.ts | 4 +-- 7 files changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index 448cfda26..9fb586417 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,7 +1,7 @@ import { singleton } from "tsyringe"; import { Block } from "@proto-kit/sequencer"; import { Block as PrismaBlock } from "@prisma/client"; -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; import { Field } from "o1js"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -19,14 +19,14 @@ export class BlockMapper implements ObjectMapper { transactions: [], networkState: { - before: new NetworkState( + before: // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - NetworkState.fromJSON(input.beforeNetworkState as any) - ), - during: new NetworkState( + input.beforeNetworkState as NetworkStateJson + , + during: // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - NetworkState.fromJSON(input.duringNetworkState as any) - ), + input.duringNetworkState as NetworkStateJson + }, hash: input.hash, @@ -51,8 +51,8 @@ export class BlockMapper implements ObjectMapper { public mapOut(input: Block): PrismaBlock { return { height: Number(input.height), - beforeNetworkState: NetworkState.toJSON(input.networkState.before), - duringNetworkState: NetworkState.toJSON(input.networkState.during), + beforeNetworkState: input.networkState.before, + duringNetworkState: input.networkState.during, fromEternalTransactionsHash: input.fromEternalTransactionsHash, toEternalTransactionsHash: input.toEternalTransactionsHash, fromBlockHashRoot: input.fromBlockHashRoot, diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index f6299f6b1..7db92d22a 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -101,8 +101,8 @@ describe("prisma integration", () => { block.transactions[0].tx.hash().toString() ); - expect(retrievedBlock.hash.toString()).toStrictEqual( - block.hash.toString() + expect(retrievedBlock.hash).toStrictEqual( + block.hash ); // Check that events match @@ -111,24 +111,12 @@ describe("prisma integration", () => { block.transactions[0].events ); - expect( - NetworkState.toFields(retrievedBlock.networkState.before).map((x) => - x.toString() - ) - ).toStrictEqual( - NetworkState.toFields(block.networkState.before).map((x) => - x.toString() - ) - ); - expect( - NetworkState.toFields(retrievedBlock.networkState.during).map((x) => - x.toString() - ) - ).toStrictEqual( - NetworkState.toFields(block.networkState.during).map((x) => - x.toString() - ) + expect(retrievedBlock.networkState.before).toStrictEqual( + block.networkState.before ); + expect(retrievedBlock.networkState.during).toStrictEqual( + block.networkState.during) + }); it("should save and retrieve the same batch", async () => { diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 545190624..6a454924e 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -141,7 +141,7 @@ export class BatchProducerModule extends SequencerModule { ): Promise { const batch = await this.computeBatch(blocks, height); - const blockHashes = blocks.map((bundle) => bundle.block.hash.toString()); + const blockHashes = blocks.map((bundle) => bundle.block.hash); const jsonProof = this.blockProofSerializer .getBlockProofSerializer() @@ -196,7 +196,7 @@ export class BatchProducerModule extends SequencerModule { const proof = await this.batchFlow.executeBatch(trace, batchId); - const fromNetworkState = blocks[0].block.networkState.before; + const fromNetworkState = new NetworkState(NetworkState.fromJSON(blocks[0].block.networkState.before)); const toNetworkState = blocks.at(-1)!.result.afterNetworkState; return { diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 7b909ecf2..69ed048b5 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -178,8 +178,8 @@ export class BlockProductionService { previousBlockHash, networkState: { - before: new NetworkState(lastResult.afterNetworkState), - during: networkState, + before: NetworkState.toJSON(lastResult.afterNetworkState), + during: NetworkState.toJSON(networkState), }, beforeBlockStateTransitions, }; diff --git a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts index 12ea078dc..10bfca965 100644 --- a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts @@ -2,6 +2,7 @@ import { log, yieldSequential } from "@proto-kit/common"; import { AppliedBatchHashList, MinaActionsHashList, + NetworkState, TransactionHashList, WitnessedRootHashList, } from "@proto-kit/protocol"; @@ -46,7 +47,7 @@ export class BatchTracingService { Field(block.block.fromEternalTransactionsHash) ), incomingMessages: new MinaActionsHashList(Field(block.block.fromMessagesHash)), - networkState: block.block.networkState.before, + networkState: new NetworkState(NetworkState.fromJSON(block.block.networkState.before)), }; } diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 2cdae386e..249001971 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -1,6 +1,7 @@ import { BlockProverPublicInput, BlockProverState, + NetworkState, WitnessedRootWitness, } from "@proto-kit/protocol"; import { Bool, Field } from "o1js"; @@ -50,7 +51,7 @@ export class BlockTracingService { ) {} @trace("batch.trace.block", ([, block]) => ({ - height: block.block.height.toString(), + height: block.block.height, })) public async traceBlock( state: BlockTracingState, @@ -64,7 +65,9 @@ export class BlockTracingService { eternalTransactionsHash: Field(block.block.fromEternalTransactionsHash), incomingMessagesHash: Field(block.block.fromMessagesHash), transactionsHash: Field(0), - networkStateHash: block.block.networkState.before.hash(), + networkStateHash: new NetworkState( + NetworkState.fromJSON(block.block.networkState.before) + ).hash(), witnessedRootsHash: state.witnessedRoots.commitment, pendingSTBatchesHash: state.pendingSTBatches.commitment, }); @@ -75,7 +78,9 @@ export class BlockTracingService { const blockTrace = { publicInput, - networkState: block.block.networkState.before, + networkState: new NetworkState( + NetworkState.fromJSON(block.block.networkState.before) + ) , deferSTProof: Bool(!includeSTProof), blockWitness: block.result.blockHashWitness, startingStateBeforeHook, @@ -87,7 +92,9 @@ export class BlockTracingService { ), applied: Bool(true), }); - state.networkState = block.block.networkState.during; + state.networkState = new NetworkState( + NetworkState.fromJSON(block.block.networkState.during) + ) ; const [afterState, transactionTraces] = await yieldSequential( chunk(block.block.transactions, 2), @@ -144,7 +151,7 @@ export class BlockTracingService { afterBlockRootWitness, }, transactions: transactionTraces, - height: block.block.height.toString(), + height: block.block.height, }, ]; } diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index cfc97c045..68f581aed 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -249,7 +249,7 @@ export const settlementTestFn = ( const [block, batch] = result; console.log( - `block ${block?.height.toString()} ${block?.fromMessagesHash.toString()} -> ${block?.toMessagesHash.toString()}` + `block ${block?.height} ${block?.fromMessagesHash} -> ${block?.toMessagesHash}` ); const proof = await blockSerializer .getBlockProofSerializer() @@ -686,7 +686,7 @@ export const settlementTestFn = ( expectDefined(batch); console.log("Test networkstate"); - console.log(NetworkState.toJSON(block.networkState.during)); + console.log(block.networkState.during); console.log(NetworkState.toJSON(batch.toNetworkState)); const settlementResult = await trigger.settle(batch, { From 2483e821d1e0ac3af33bd5bd03915d0f20185581 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 7 Jan 2026 14:28:00 +0300 Subject: [PATCH 07/63] refactor: remove unnecessary stringifications and type conversions --- packages/api/src/graphql/modules/BlockResolver.ts | 8 ++++---- packages/api/src/metrics/SequencerInstrumentation.ts | 2 +- .../persistance/src/services/prisma/PrismaBlockStorage.ts | 4 ++-- packages/processor/src/triggers/TimedProcessorTrigger.ts | 4 ++-- packages/processor/test/HandlersExecutor.test.ts | 4 ++-- .../protocol/production/sequencing/BlockProducerModule.ts | 8 ++++---- .../protocol/production/sequencing/BlockResultService.ts | 6 ++++-- .../src/storage/inmemory/InMemoryBlockStorage.ts | 6 +++--- .../src/storage/inmemory/InMemoryTransactionStorage.ts | 4 ++-- .../sequencer/test/integration/StorageIntegration.test.ts | 2 +- .../production/sequencing/atomic-block-production.test.ts | 2 +- packages/stack/test/graphql/graphql.test.ts | 2 +- 12 files changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/api/src/graphql/modules/BlockResolver.ts b/packages/api/src/graphql/modules/BlockResolver.ts index 036184873..a62675dcb 100644 --- a/packages/api/src/graphql/modules/BlockResolver.ts +++ b/packages/api/src/graphql/modules/BlockResolver.ts @@ -10,7 +10,7 @@ import { BatchTransactionModel } from "./model/BatchTransactionModel"; export class BlockModel { public static fromServiceLayerModel(block: Block) { return new BlockModel( - Number(block.networkState.during.block.height.toBigInt()), + Number(block.networkState.during.block.height), block.transactions.map((tx) => BatchTransactionModel.fromServiceLayerModel({ tx: tx.tx, @@ -18,9 +18,9 @@ export class BlockModel { statusMessage: tx.statusMessage, }) ), - block.transactionsHash.toString(), - block.hash.toString(), - block.previousBlockHash?.toString() + block.transactionsHash, + block.hash, + block.previousBlockHash ); } diff --git a/packages/api/src/metrics/SequencerInstrumentation.ts b/packages/api/src/metrics/SequencerInstrumentation.ts index 846daf704..956a2a69b 100644 --- a/packages/api/src/metrics/SequencerInstrumentation.ts +++ b/packages/api/src/metrics/SequencerInstrumentation.ts @@ -15,7 +15,7 @@ export class SequencerInstrumentation extends InstrumentationBase<{}> { super("protokit", "canary", {}); if (trigger !== undefined) { trigger.events.on("block-produced", (block) => { - this.blockProduced(parseInt(block.height.toString(), 10)); + this.blockProduced(parseInt(block.height, 10)); }); } } diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index f3146642e..21cfee7b5 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -88,7 +88,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { const encoded = this.transactionResultMapper.mapOut(tx); return { ...encoded[0], - blockHash: block.hash.toString(), + blockHash: block.hash, }; } ); @@ -191,7 +191,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { if (result !== undefined) { if (result.result === undefined) { throw new Error( - `Block result for block ${result.block.height.toString()} not found` + `Block result for block ${result.block.height} not found` ); } return { diff --git a/packages/processor/src/triggers/TimedProcessorTrigger.ts b/packages/processor/src/triggers/TimedProcessorTrigger.ts index 0b6912e7e..beee4dfe6 100644 --- a/packages/processor/src/triggers/TimedProcessorTrigger.ts +++ b/packages/processor/src/triggers/TimedProcessorTrigger.ts @@ -46,13 +46,13 @@ export class TimedProcessorTrigger extends ProcessorModule { await client.balance.create({ data: { address: from.toBase58(), - height: Number(block.height.toString()), + height: Number(block.height), amount: newFromBalance > 0n ? newFromBalance.toString() : "0", }, }); @@ -109,7 +109,7 @@ describe("HandlersModule", () => { await client.balance.create({ data: { address: to.toBase58(), - height: Number(block.height.toString()), + height: Number(block.height), amount: newToBalance > 0n ? newToBalance.toString() : "0", }, }); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 47a7ea9d3..1507c3afd 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -110,10 +110,10 @@ export class BlockProducerModule extends SequencerModule { } } - @trace("block.result", ([block]) => ({ height: block.height.toString() })) + @trace("block.result", ([block]) => ({ height: block.height })) public async generateMetadata(block: Block): Promise { const traceMetadata = { - height: block.height.toString(), + height: block.height, }; const { result, blockHashTreeStore, treeStore, stateService } = @@ -193,7 +193,7 @@ export class BlockProducerModule extends SequencerModule { metadata = BlockWithResult.createEmpty(); } else if (parentBlock.result === undefined) { throw new Error( - `Metadata for block at height ${parentBlock.block.height.toString()} not available` + `Metadata for block at height ${parentBlock.block.height} not available` ); } else { metadata = { @@ -248,7 +248,7 @@ export class BlockProducerModule extends SequencerModule { await this.blockQueue.pushBlock(block); }), { - height: block.height.toString(), + height: block.height, } ); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 702293738..5a0084a5e 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -184,7 +184,7 @@ export class BlockResultService { } @trace("block.result.generate", ([block]) => ({ - height: block.height.toString(), + height: block.height, })) public async generateMetadataForNextBlock( block: Block, @@ -222,7 +222,9 @@ export class BlockResultService { transactionsHash: Field(block.transactionsHash), eternalTransactionsHash: Field(block.toEternalTransactionsHash), }, - block.networkState.during, + new NetworkState( + NetworkState.fromJSON(block.networkState.during) + ), stateService ); diff --git a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts index 5c5306e7b..102b53fa0 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts @@ -47,7 +47,7 @@ export class InMemoryBlockStorage implements BlockStorage, BlockQueue { if (result !== undefined) { if (result.result === undefined) { throw new Error( - `Block result for block ${result.block.height.toString()} not found` + `Block result for block ${result.block.height} not found` ); } return { @@ -65,7 +65,7 @@ export class InMemoryBlockStorage implements BlockStorage, BlockQueue { if (latestBatch !== undefined) { cursor = this.blocks.reduce( (c, block, index) => - latestBatch.blockHashes.includes(block.hash.toString()) + latestBatch.blockHashes.includes(block.hash) ? index + 1 : c, 0 @@ -100,6 +100,6 @@ export class InMemoryBlockStorage implements BlockStorage, BlockQueue { } public async getBlock(hash: string): Promise { - return this.blocks.find((block) => block.hash.toString() === hash); + return this.blocks.find((block) => block.hash === hash); } } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index df0fe7fd7..146dc9a6e 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -105,10 +105,10 @@ export class InMemoryTransactionStorage implements TransactionStorage { ); if (txResult !== undefined) { // eslint-disable-next-line no-await-in-loop - const batch = await this.findBatch(block.hash.toString()); + const batch = await this.findBatch(block.hash); return { transaction: txResult.tx, - block: block.transactionsHash.toString(), + block: block.transactionsHash, batch, }; } diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index d2c312ed9..fd182ae2f 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -154,7 +154,7 @@ describe.each([["InMemory", InMemoryDatabase]])( const blockStorage = sequencer.resolve("BlockStorage") as BlockStorage; const block2 = await blockStorage.getBlockAt( - Number(blocks[0].block.height.toString()) + Number(blocks[0].block.height) ); expectDefined(block2); diff --git a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts index a9b156023..2f2144ecb 100644 --- a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts +++ b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts @@ -119,6 +119,6 @@ describe("atomic block production", () => { const block = await trigger.produceBlock(); expectDefined(block); - expect(block.height.toString()).toBe("1"); + expect(block.height).toBe("1"); }); }); diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index e334e5f55..a7f84cafd 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -221,7 +221,7 @@ describe("graphql client test", () => { await tx.send(); const block = await trigger.produceBlock(); - const hash = block?.hash.toString()!; + const hash = block?.hash!; const height = Number(block?.height); const hashResult = await appChain.query.explorer.getBlock({ hash: hash }); From ae96af11fdc5387678b7b6dbe5b518e5f0fe2a35 Mon Sep 17 00:00:00 2001 From: saitunc Date: Fri, 9 Jan 2026 16:54:25 +0300 Subject: [PATCH 08/63] refactor: change use of NetworkState to NetworkStateJson in codebase --- .../graphql/GraphqlNetworkStateTransportModule.ts | 12 ++++++------ .../src/query/BlockStorageNetworkStateModule.ts | 12 +++++++----- .../src/helpers/query/NetworkStateQuery.ts | 8 ++++---- .../helpers/query/NetworkStateTransportModule.ts | 8 ++++---- .../src/mempool/private/PrivateMempool.ts | 15 +++++++++++---- packages/stack/test/graphql/graphql.test.ts | 2 +- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts index eb406a5aa..882fd94a1 100644 --- a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts @@ -3,7 +3,7 @@ import { NetworkStateTransportModule, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; import { gql } from "@urql/core"; import { GraphqlClient } from "./GraphqlClient"; @@ -28,7 +28,7 @@ export class GraphqlNetworkStateTransportModule super(); } - private async retrieveNetworkState(path: string): Promise { + private async retrieveNetworkState(path: string): Promise { const query = gql` query NetworkState { network { @@ -58,7 +58,7 @@ export class GraphqlNetworkStateTransportModule try { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - return new NetworkState(NetworkState.fromJSON(json)); + return NetworkState.toJSON((NetworkState.fromJSON(json))); } catch (e) { if (e instanceof Error) { throw errors.receivedResultMalformed(e.message); @@ -69,15 +69,15 @@ export class GraphqlNetworkStateTransportModule throw new Error(queryResult.error.message); } - public async getProvenNetworkState(): Promise { + public async getProvenNetworkState(): Promise { return await this.retrieveNetworkState("proven"); } - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { return await this.retrieveNetworkState("staged"); } - public async getUnprovenNetworkState(): Promise { + public async getUnprovenNetworkState(): Promise { return await this.retrieveNetworkState("unproven"); } } diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index 274037c14..e0d070a0a 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -6,7 +6,7 @@ import { BatchStorage, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; import { ModuleContainerLike } from "@proto-kit/common"; @injectable() @@ -37,7 +37,7 @@ export class BlockStorageNetworkStateModule ); } - public async getUnprovenNetworkState(): Promise { + public async getUnprovenNetworkState(): Promise { const latestBlock = await this.unprovenStorage.getLatestBlock(); return latestBlock?.block.networkState.during; } @@ -46,12 +46,14 @@ export class BlockStorageNetworkStateModule * Staged network state is the networkstate after the latest unproven block * with afterBundle() hooks executed */ - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { const result = await this.unprovenStorage.getLatestBlock(); - return result?.result.afterNetworkState; + return result?.result.afterNetworkState + ? NetworkState.toJSON(result.result.afterNetworkState) + : undefined; } - public async getProvenNetworkState(): Promise { + public async getProvenNetworkState(): Promise { const batch = await this.provenStorage.getLatestBatch(); if (batch !== undefined) { diff --git a/packages/sequencer/src/helpers/query/NetworkStateQuery.ts b/packages/sequencer/src/helpers/query/NetworkStateQuery.ts index c11e2d6f1..878be0916 100644 --- a/packages/sequencer/src/helpers/query/NetworkStateQuery.ts +++ b/packages/sequencer/src/helpers/query/NetworkStateQuery.ts @@ -1,4 +1,4 @@ -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkStateJson } from "@proto-kit/protocol"; import { NetworkStateTransportModule } from "./NetworkStateTransportModule"; @@ -7,15 +7,15 @@ export class NetworkStateQuery { private readonly transportModule: NetworkStateTransportModule ) {} - public get unproven(): Promise { + public get unproven(): Promise { return this.transportModule.getUnprovenNetworkState(); } - public get stagedUnproven(): Promise { + public get stagedUnproven(): Promise { return this.transportModule.getStagedNetworkState(); } - public get proven(): Promise { + public get proven(): Promise { return this.transportModule.getProvenNetworkState(); } } diff --git a/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts b/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts index 1a6cd91d4..9e01c5df9 100644 --- a/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts +++ b/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts @@ -1,7 +1,7 @@ -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkStateJson } from "@proto-kit/protocol"; export interface NetworkStateTransportModule { - getUnprovenNetworkState: () => Promise; - getStagedNetworkState: () => Promise; - getProvenNetworkState: () => Promise; + getUnprovenNetworkState: () => Promise; + getStagedNetworkState: () => Promise; + getProvenNetworkState: () => Promise; } diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index d10edf131..2ea8a2c58 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -10,6 +10,7 @@ import { BlockHashMerkleTree, MandatoryProtocolModulesRecord, NetworkState, + NetworkStateJson, Protocol, ProvableHookBlockState, RuntimeMethodExecutionContext, @@ -105,9 +106,11 @@ export class PrivateMempool ); } - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { const result = await this.unprovenQueue.getLatestBlock(); - return result?.result.afterNetworkState; + return result?.result.afterNetworkState + ? NetworkState.toJSON(result.result.afterNetworkState) + : undefined; } public async removeTxs(included: string[], dropped: string[]) { @@ -122,8 +125,12 @@ export class PrivateMempool const baseCachedStateService = new CachedStateService(this.stateService); - const networkState = - (await this.getStagedNetworkState()) ?? NetworkState.empty(); + // Should provide NetworkState to checkTxValid. + const stagedNetworkState = await this.getStagedNetworkState(); + + const networkState = stagedNetworkState + ? new NetworkState(NetworkState.fromJSON(stagedNetworkState)) + : NetworkState.empty(); const validationEnabled = this.config.validationEnabled ?? false; const sortedTxs = validationEnabled diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index a7f84cafd..7fd3e1356 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -156,7 +156,7 @@ describe("graphql client test", () => { const state = await appChain.query.network.unproven; expect(state).toBeDefined(); - expect(state!.block.height.toBigInt()).toBeGreaterThanOrEqual(0n); + expect(BigInt(state!.block.height)).toBeGreaterThanOrEqual(0n); }); it("should retrieve merkle witness", async () => { From 1093afe1780694dae8c98c52e1ebb4b87af75258 Mon Sep 17 00:00:00 2001 From: saitunc Date: Fri, 9 Jan 2026 17:01:13 +0300 Subject: [PATCH 09/63] refactor: refactor ClientBlock and used parts in codebase --- .../src/graphql/GraphqlBlockExplorerTransportModule.ts | 9 ++++----- packages/sdk/src/query/InMemoryBlockExplorer.ts | 8 ++++---- .../src/helpers/query/BlockExplorerTransportModule.ts | 8 ++++---- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts b/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts index 3908ab6cd..4537db272 100644 --- a/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts @@ -7,7 +7,6 @@ import { ClientTransaction, InclusionStatus, } from "@proto-kit/sequencer"; -import { Field } from "o1js"; import { GraphqlClient } from "./GraphqlClient"; @@ -106,14 +105,14 @@ export class GraphqlBlockExplorerTransportModule const previousBlockHash = blockData.previousBlockHash != null && blockData.previousBlockHash !== "" - ? Field(blockData.previousBlockHash) + ? blockData.previousBlockHash : undefined; return { - hash: Field(blockData.hash), - height: Field(blockData.height), + hash: blockData.hash, + height: blockData.height.toString(), previousBlockHash, - transactionsHash: Field(blockData.transactionsHash), + transactionsHash: blockData.transactionsHash, transactions: blockData.txs, }; } diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index ba4000961..103e52c4a 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -84,11 +84,11 @@ export class InMemoryBlockExplorer ); return { - hash: Field(block.hash), - previousBlockHash: block.previousBlockHash!==undefined ? Field(block.previousBlockHash): undefined, - height: Field(block.height), + hash: block.hash, + previousBlockHash: block.previousBlockHash!==undefined ? block.previousBlockHash: undefined, + height: block.height, transactions: clientTransactions, - transactionsHash: Field(block.transactionsHash), + transactionsHash: block.transactionsHash, }; } } diff --git a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts index 67e002cb9..1c99198ce 100644 --- a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts +++ b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts @@ -19,11 +19,11 @@ export interface ClientTransaction { } export interface ClientBlock { - hash: Field; - previousBlockHash: Field | undefined; - height: Field; + hash: string; + previousBlockHash: string | undefined; + height: string; transactions: ClientTransaction[]; - transactionsHash: Field; + transactionsHash: string; } export interface BlockExplorerTransportModule { From 0199877f671b76306cb3f77ebe3e11b2844496ba Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 12 Jan 2026 03:32:34 +0300 Subject: [PATCH 10/63] refactor: update UntypedStateTransition with UntypedSTJson --- .../GeneratedResolverFactoryGraphqlModule.test.ts | 3 ++- .../production/helpers/UntypedStateTransition.ts | 14 ++++++++++++++ .../sequencing/BlockProductionService.ts | 2 +- .../production/sequencing/BlockResultService.ts | 6 +++--- .../production/tracing/BlockTracingService.ts | 7 ++++--- .../tracing/StateTransitionTracingService.ts | 6 +++--- packages/sequencer/src/storage/model/Block.ts | 6 +++--- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts index 3ef0ffe06..d45cfe1e5 100644 --- a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts +++ b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts @@ -8,7 +8,8 @@ import { log } from "@proto-kit/common"; import { jest } from "@jest/globals"; import { Indexer } from "../src/Indexer"; -import { GeneratedResolverFactoryGraphqlModule } from "../src/api/GeneratedResolverFactoryGraphqlModule"; +import { GeneratedResolverFactoryGraphqlModule } from "../src"; + log.setLevel("info"); diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index 425f01445..f2181bceb 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -3,6 +3,20 @@ import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; +export interface UntypedSTJson{ + path: string, + from:{ + isSome: boolean; + isForcedSome: boolean; + value: string[]; + }, + to: { + isSome: boolean; + isForcedSome: boolean; + value: string[]; + } +}; + /** * Generic state transition that constraints the current method circuit * to external state, by providing a state anchor. diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 69ed048b5..1aa920b60 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -181,7 +181,7 @@ export class BlockProductionService { before: NetworkState.toJSON(lastResult.afterNetworkState), during: NetworkState.toJSON(networkState), }, - beforeBlockStateTransitions, + beforeBlockStateTransitions: beforeBlockStateTransitions.map((st: UntypedStateTransition) => st.toJSON()), }; const hash = Block.hash(block).toString(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 5a0084a5e..daa7ecea4 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -21,7 +21,7 @@ import { } from "../../../storage/model/Block"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; -import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import type { StateRecord } from "../BatchProducerModule"; @@ -199,7 +199,7 @@ export class BlockResultService { }> { const combinedDiff = createCombinedOrderedStateDiff( block.transactions, - block.beforeBlockStateTransitions + block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) ); const inMemoryStore = await CachedLinkedLeafStore.new(merkleTreeStore); @@ -250,7 +250,7 @@ export class BlockResultService { blockHashWitness, afterBlockStateTransitions: stateTransitions.map((st) => - UntypedStateTransition.fromStateTransition(st) + UntypedStateTransition.fromStateTransition(st).toJSON() ), blockHash: BigInt(block.hash), }, diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 249001971..8aa151c17 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -21,6 +21,7 @@ import { TransactionTrace, TransactionTracingService, } from "./TransactionTracingService"; +import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; export type TaskStateRecord = Record; @@ -73,7 +74,7 @@ export class BlockTracingService { }); const startingStateBeforeHook = collectStartingState( - block.block.beforeBlockStateTransitions + block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) ); const blockTrace = { @@ -88,7 +89,7 @@ export class BlockTracingService { state.pendingSTBatches.push({ batchHash: toStateTransitionsHash( - block.block.beforeBlockStateTransitions + block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) ), applied: Bool(true), }); @@ -138,7 +139,7 @@ export class BlockTracingService { } const startingStateAfterHook = collectStartingState( - block.result.afterBlockStateTransitions + block.result.afterBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) ); state.networkState = block.result.afterNetworkState; diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index 03621892b..41448f290 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -18,7 +18,7 @@ import { import { distinctByString } from "../../../helpers/utils"; import { BlockWithResult } from "../../../storage/model/Block"; -import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; @@ -47,7 +47,7 @@ export class StateTransitionTracingService { return blocks.reduce((previous, block) => { const batches = [ { - stateTransitions: block.block.beforeBlockStateTransitions, + stateTransitions: block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)), applied: true, }, ...block.block.transactions.flatMap((tx) => tx.stateTransitions), @@ -62,7 +62,7 @@ export class StateTransitionTracingService { } return batchBeforeWitnessing.concat({ - stateTransitions: block.result.afterBlockStateTransitions, + stateTransitions: block.result.afterBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)), applied: true, witnessRoot: false, }); diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 8ac0d60a5..f7ab5444c 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -9,7 +9,7 @@ import { import { LinkedMerkleTree } from "@proto-kit/common"; import { PendingTransaction } from "../../mempool/PendingTransaction"; -import { UntypedStateTransition } from "../../protocol/production/helpers/UntypedStateTransition"; +import { UntypedStateTransition, UntypedSTJson } from "../../protocol/production/helpers/UntypedStateTransition"; import { FieldString } from "../../helpers/utils"; export interface StateTransitionBatch { @@ -51,7 +51,7 @@ export interface Block { toEternalTransactionsHash: FieldString; toMessagesHash: FieldString; - beforeBlockStateTransitions: UntypedStateTransition[]; + beforeBlockStateTransitions: UntypedSTJson[]; } // eslint-disable-next-line @typescript-eslint/no-redeclare @@ -71,7 +71,7 @@ export interface BlockResult { stateRoot: bigint; blockHashRoot: bigint; afterNetworkState: NetworkState; - afterBlockStateTransitions: UntypedStateTransition[]; + afterBlockStateTransitions: UntypedSTJson[]; blockHashWitness: BlockHashMerkleTreeWitness; } From 76e14176e090005eacddec81cb2e8f95df423d78 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 13 Jan 2026 16:01:00 +0300 Subject: [PATCH 11/63] refactor: add utility function for hashing NetworkStateJson values --- packages/protocol/src/utils/utils.ts | 9 +++++++++ .../test/integration/BlockProduction-test.ts | 7 +++++-- packages/sequencer/test/settlement/Settlement.ts | 15 ++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/protocol/src/utils/utils.ts b/packages/protocol/src/utils/utils.ts index 660d8c456..213500684 100644 --- a/packages/protocol/src/utils/utils.ts +++ b/packages/protocol/src/utils/utils.ts @@ -1,5 +1,6 @@ import { Bool, Field, Poseidon, Provable } from "o1js"; import floor from "lodash/floor"; +import { NetworkStateJson } from "../model/network/NetworkState"; export type ReturnType = FunctionType extends ( ...args: any[] @@ -33,6 +34,14 @@ export function notInCircuit(): MethodDecorator { }; } +export function networkStateToFields(json: NetworkStateJson): Field[] { + return [Field(json.block.height), Field(json.previous.rootHash)]; +} + +export function hashNetworkState(json: NetworkStateJson): string { + return Poseidon.hash(networkStateToFields(json)).toString(); +} + export function stringToField(value: string) { const fieldSize = Field.sizeInBytes - 1; diff --git a/packages/sequencer/test/integration/BlockProduction-test.ts b/packages/sequencer/test/integration/BlockProduction-test.ts index 3189f4798..6bd8adf63 100644 --- a/packages/sequencer/test/integration/BlockProduction-test.ts +++ b/packages/sequencer/test/integration/BlockProduction-test.ts @@ -20,6 +20,7 @@ import { Path, Protocol, PROTOKIT_PREFIXES, + hashNetworkState, } from "@proto-kit/protocol"; import { Bool, Field, PrivateKey, PublicKey, Struct, UInt64 } from "o1js"; import "reflect-metadata"; @@ -235,8 +236,10 @@ export function testBlockProduction< expectDefined(latestBlockWithResult); expectDefined(latestBlockWithResult.result); expect( - latestBlockWithResult.result.afterNetworkState.hash().toString() - ).toStrictEqual(batch!.toNetworkState.hash().toString()); + hashNetworkState( + latestBlockWithResult.result.afterNetworkState + ) + ).toStrictEqual(hashNetworkState(batch!.toNetworkState)); // Check if the batchstorage has received the block const batchStorage = sequencer.resolve("BatchStorage") as BatchStorage; diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 68f581aed..a40b25ac9 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -14,6 +14,7 @@ import { ReturnType, SettlementContractModule, SettlementSmartContractBase, + hashNetworkState, } from "@proto-kit/protocol"; import { ClientAppChain, @@ -506,7 +507,7 @@ export const settlementTestFn = ( expectDefined(lastBlock); expectDefined(lastBlock.result); expect(settlement.networkStateHash.get().toString()).toStrictEqual( - lastBlock!.result.afterNetworkState.hash().toString() + hashNetworkState(lastBlock!.result.afterNetworkState).toString() ); expect(settlement.stateRoot.get().toString()).toStrictEqual( lastBlock!.result.stateRoot.toString() @@ -623,12 +624,12 @@ export const settlementTestFn = ( console.log( `Empty Network State ${NetworkState.empty().hash().toString()}` ); - console.log(batch!.toNetworkState.hash().toString()); - console.log(batch2!.fromNetworkState.hash().toString()); + console.log(hashNetworkState(batch!.toNetworkState)); + console.log(hashNetworkState(batch2!.fromNetworkState)); - expect(batch!.toNetworkState.hash().toString()).toStrictEqual( - batch2!.fromNetworkState.hash().toString() - ); + expect( + hashNetworkState(batch!.toNetworkState) + ).toStrictEqual(hashNetworkState(batch2!.fromNetworkState)); expect(batch2!.blockHashes).toHaveLength(1); @@ -687,7 +688,7 @@ export const settlementTestFn = ( console.log("Test networkstate"); console.log(block.networkState.during); - console.log(NetworkState.toJSON(batch.toNetworkState)); + console.log(batch.toNetworkState); const settlementResult = await trigger.settle(batch, { [bridgedTokenId.toString()]: { From 55d5dec4e17ff661bc103c4abdc7e5d5c62a6beb Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 13 Jan 2026 16:23:52 +0300 Subject: [PATCH 12/63] refactor: apply refactoring where NetworkStateJson is used --- .../GraphqlNetworkStateTransportModule.ts | 4 +-- .../query/BlockStorageNetworkStateModule.ts | 4 +-- .../src/mempool/private/PrivateMempool.ts | 20 +++++++---- .../production/BatchProducerModule.ts | 8 ++--- .../sequencing/BlockProductionService.ts | 12 ++++--- .../production/tracing/BlockTracingService.ts | 9 +++-- .../src/settlement/SettlementModule.ts | 5 +-- packages/sequencer/src/storage/model/Batch.ts | 6 ++-- packages/sequencer/src/storage/model/Block.ts | 35 +++++++++++-------- 9 files changed, 61 insertions(+), 42 deletions(-) diff --git a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts index 882fd94a1..a38645d41 100644 --- a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts @@ -3,7 +3,7 @@ import { NetworkStateTransportModule, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkStateJson } from "@proto-kit/protocol"; import { gql } from "@urql/core"; import { GraphqlClient } from "./GraphqlClient"; @@ -58,7 +58,7 @@ export class GraphqlNetworkStateTransportModule try { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - return NetworkState.toJSON((NetworkState.fromJSON(json))); + return json as NetworkStateJson; } catch (e) { if (e instanceof Error) { throw errors.receivedResultMalformed(e.message); diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index e0d070a0a..f1edb9e24 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -48,9 +48,7 @@ export class BlockStorageNetworkStateModule */ public async getStagedNetworkState(): Promise { const result = await this.unprovenStorage.getLatestBlock(); - return result?.result.afterNetworkState - ? NetworkState.toJSON(result.result.afterNetworkState) - : undefined; + return result?.result.afterNetworkState; } public async getProvenNetworkState(): Promise { diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 2ea8a2c58..d6d3319c8 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -108,9 +108,7 @@ export class PrivateMempool public async getStagedNetworkState(): Promise { const result = await this.unprovenQueue.getLatestBlock(); - return result?.result.afterNetworkState - ? NetworkState.toJSON(result.result.afterNetworkState) - : undefined; + return result?.result.afterNetworkState; } public async removeTxs(included: string[], dropped: string[]) { @@ -128,7 +126,7 @@ export class PrivateMempool // Should provide NetworkState to checkTxValid. const stagedNetworkState = await this.getStagedNetworkState(); - const networkState = stagedNetworkState + const networkState = stagedNetworkState ? new NetworkState(NetworkState.fromJSON(stagedNetworkState)) : NetworkState.empty(); @@ -182,9 +180,17 @@ export class PrivateMempool previousBlock?.result.blockHashRoot ?? BlockHashMerkleTree.EMPTY_ROOT ), eternalTransactionsHash: - previousBlock?.block.toEternalTransactionsHash !== undefined ? Field(previousBlock?.block.toEternalTransactionsHash) : Field(0), - transactionsHash: previousBlock?.block.transactionsHash !== undefined ? Field(previousBlock?.block.transactionsHash) : Field(0), - incomingMessagesHash: previousBlock?.block.toMessagesHash !== undefined ? Field(previousBlock?.block.toMessagesHash) : Field(0), + previousBlock?.block.toEternalTransactionsHash !== undefined + ? Field(previousBlock?.block.toEternalTransactionsHash) + : Field(0), + transactionsHash: + previousBlock?.block.transactionsHash !== undefined + ? Field(previousBlock?.block.transactionsHash) + : Field(0), + incomingMessagesHash: + previousBlock?.block.toMessagesHash !== undefined + ? Field(previousBlock?.block.toMessagesHash) + : Field(0), }; while ( diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 6a454924e..9208bed58 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -2,7 +2,7 @@ import { inject } from "tsyringe"; import { BlockProverPublicInput, BlockProverPublicOutput, - NetworkState, + NetworkStateJson, } from "@proto-kit/protocol"; import { Field, Proof } from "o1js"; import { log, noop } from "@proto-kit/common"; @@ -179,8 +179,8 @@ export class BatchProducerModule extends SequencerModule { ): Promise<{ proof: Proof; changes: CachedLinkedLeafStore; - fromNetworkState: NetworkState; - toNetworkState: NetworkState; + fromNetworkState: NetworkStateJson; + toNetworkState: NetworkStateJson; }> { if (blocks.length === 0 || blocks.flat(1).length === 0) { throw errors.blockWithoutTxs(); @@ -196,7 +196,7 @@ export class BatchProducerModule extends SequencerModule { const proof = await this.batchFlow.executeBatch(trace, batchId); - const fromNetworkState = new NetworkState(NetworkState.fromJSON(blocks[0].block.networkState.before)); + const fromNetworkState = blocks[0].block.networkState.before; const toNetworkState = blocks.at(-1)!.result.afterNetworkState; return { diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 1aa920b60..5027d4fab 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -28,6 +28,7 @@ import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; +import { FieldString } from "../../../helpers/utils"; import { BlockTrackers, @@ -35,7 +36,6 @@ import { TransactionExecutionResultStatus, TransactionExecutionService, } from "./TransactionExecutionService"; -import { FieldString } from "../../../helpers/utils"; function isIncludedTxs( x: TransactionExecutionResultStatus @@ -130,7 +130,7 @@ export class BlockProductionService { // Get used networkState by executing beforeBlock() hooks const beforeHookResult = await this.executeBeforeBlockHook( toProvableHookBlockState(blockState), - lastResult.afterNetworkState, + new NetworkState(NetworkState.fromJSON(lastResult.afterNetworkState)), stateService ); @@ -150,7 +150,7 @@ export class BlockProductionService { ); const previousBlockHash = - lastResult.blockHash === 0n ? undefined : FieldString(lastResult.blockHash); + lastResult.blockHash === "0" ? undefined : FieldString(lastResult.blockHash); if (executionResults.length === 0 && !allowEmptyBlocks) { log.info( @@ -178,10 +178,12 @@ export class BlockProductionService { previousBlockHash, networkState: { - before: NetworkState.toJSON(lastResult.afterNetworkState), + before: lastResult.afterNetworkState, during: NetworkState.toJSON(networkState), }, - beforeBlockStateTransitions: beforeBlockStateTransitions.map((st: UntypedStateTransition) => st.toJSON()), + beforeBlockStateTransitions: beforeBlockStateTransitions.map( + (st: UntypedStateTransition) => st.toJSON() + ), }; const hash = Block.hash(block).toString(); diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 8aa151c17..0d4e7ea83 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -1,4 +1,5 @@ import { + BlockHashMerkleTreeWitness, BlockProverPublicInput, BlockProverState, NetworkState, @@ -83,7 +84,9 @@ export class BlockTracingService { NetworkState.fromJSON(block.block.networkState.before) ) , deferSTProof: Bool(!includeSTProof), - blockWitness: block.result.blockHashWitness, + blockWitness: new BlockHashMerkleTreeWitness( + BlockHashMerkleTreeWitness.fromJSON(block.result.blockHashWitness) + ), startingStateBeforeHook, } satisfies Partial; @@ -141,7 +144,9 @@ export class BlockTracingService { const startingStateAfterHook = collectStartingState( block.result.afterBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) ); - state.networkState = block.result.afterNetworkState; + state.networkState = new NetworkState( + NetworkState.fromJSON(block.result.afterNetworkState) + ); return [ afterState, diff --git a/packages/sequencer/src/settlement/SettlementModule.ts b/packages/sequencer/src/settlement/SettlementModule.ts index 597da53b3..c8a221fb7 100644 --- a/packages/sequencer/src/settlement/SettlementModule.ts +++ b/packages/sequencer/src/settlement/SettlementModule.ts @@ -8,6 +8,7 @@ import { MandatoryProtocolModulesRecord, SettlementSmartContractBase, DynamicBlockProof, + NetworkState, } from "@proto-kit/protocol"; import { AccountUpdate, @@ -175,8 +176,8 @@ export class SettlementModule signature, dispatch.address, feepayer, - batch.fromNetworkState, - batch.toNetworkState, + new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), + new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/storage/model/Batch.ts b/packages/sequencer/src/storage/model/Batch.ts index 731b14718..a14685c42 100644 --- a/packages/sequencer/src/storage/model/Batch.ts +++ b/packages/sequencer/src/storage/model/Batch.ts @@ -1,5 +1,5 @@ import { JsonProof } from "o1js"; -import { NetworkState } from "@proto-kit/protocol"; +import { NetworkStateJson } from "@proto-kit/protocol"; import { PendingTransaction } from "../../mempool/PendingTransaction"; @@ -16,6 +16,6 @@ export interface Batch { } export interface SettleableBatch extends Batch { - fromNetworkState: NetworkState; - toNetworkState: NetworkState; + fromNetworkState: NetworkStateJson; + toNetworkState: NetworkStateJson; } diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index f7ab5444c..4264aeb17 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -3,13 +3,17 @@ import { ACTIONS_EMPTY_HASH, BlockHashMerkleTree, BlockHashMerkleTreeWitness, + BlockHashMerkleTreeWitnessJson, NetworkState, - NetworkStateJson + NetworkStateJson, } from "@proto-kit/protocol"; import { LinkedMerkleTree } from "@proto-kit/common"; import { PendingTransaction } from "../../mempool/PendingTransaction"; -import { UntypedStateTransition, UntypedSTJson } from "../../protocol/production/helpers/UntypedStateTransition"; +import { + UntypedStateTransition, + UntypedSTJson, +} from "../../protocol/production/helpers/UntypedStateTransition"; import { FieldString } from "../../helpers/utils"; export interface StateTransitionBatch { @@ -61,16 +65,19 @@ export const Block = { }, hash(block: Omit): Field { - return Block.calculateHash(Field(block.height), Field(block.transactionsHash)); + return Block.calculateHash( + Field(block.height), + Field(block.transactionsHash) + ); }, }; export interface BlockResult { - blockHash: bigint; - witnessedRoots: [bigint]; - stateRoot: bigint; - blockHashRoot: bigint; - afterNetworkState: NetworkState; + blockHash: string; + witnessedRoots: [string]; + stateRoot: string; + blockHashRoot: string; + afterNetworkState: NetworkStateJson; afterBlockStateTransitions: UntypedSTJson[]; blockHashWitness: BlockHashMerkleTreeWitness; } @@ -104,7 +111,7 @@ export const BlockWithResult = { transactions: [], networkState: { before: NetworkState.toJSON(NetworkState.empty()), - during: NetworkState.toJSON(NetworkState.empty()) , + during: NetworkState.toJSON(NetworkState.empty()), }, fromBlockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), fromMessagesHash: FieldString(0), @@ -115,13 +122,13 @@ export const BlockWithResult = { previousBlockHash: undefined, }, result: { - afterNetworkState: NetworkState.empty(), - stateRoot: LinkedMerkleTree.EMPTY_ROOT.toBigInt(), - blockHashRoot: BlockHashMerkleTree.EMPTY_ROOT, + afterNetworkState: NetworkState.toJSON(NetworkState.empty()), + stateRoot: String(LinkedMerkleTree.EMPTY_ROOT), + blockHashRoot: String(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], blockHashWitness: BlockHashMerkleTree.WITNESS.dummy(), - blockHash: 0n, - witnessedRoots: [LinkedMerkleTree.EMPTY_ROOT.toBigInt()], + blockHash: "0", + witnessedRoots: [String(LinkedMerkleTree.EMPTY_ROOT)], }, }) satisfies BlockWithResult, }; From 78aae194af651d52c8d3b167fbeb6ec21c705b31 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 13 Jan 2026 17:49:15 +0300 Subject: [PATCH 13/63] refactor: add BlockHahMerkleTreewitnessJson and refactor with it --- .../accummulators/BlockHashMerkleTree.ts | 9 +++- .../sequencing/BlockResultService.ts | 42 ++++++++++--------- packages/sequencer/src/storage/model/Block.ts | 4 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts b/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts index e80d4b6b8..b40f18fa8 100644 --- a/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts +++ b/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts @@ -1,5 +1,11 @@ import { createMerkleTree } from "@proto-kit/common"; -import { Bool, Field, Poseidon, Struct } from "o1js"; +import { + Bool, + Field, + InferJson, + Poseidon, + Struct, +} from "o1js"; export class BlockHashMerkleTree extends createMerkleTree(40) {} export class BlockHashMerkleTreeWitness extends BlockHashMerkleTree.WITNESS {} @@ -22,3 +28,4 @@ export class BlockHashTreeEntry extends Struct({ return Poseidon.hash([blockHash, ...this.closed.toFields()]); } } +export type BlockHashMerkleTreeWitnessJson = InferJson; diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index daa7ecea4..ba7a1db92 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -3,6 +3,7 @@ import { LinkedMerkleTree } from "@proto-kit/common"; import { AfterBlockHookArguments, BlockHashMerkleTree, + BlockHashMerkleTreeWitness, BlockHashTreeEntry, MandatoryProtocolModulesRecord, NetworkState, @@ -21,7 +22,10 @@ import { } from "../../../storage/model/Block"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; -import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; +import { + UntypedStateTransition, + UntypedSTJson, +} from "../helpers/UntypedStateTransition"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import type { StateRecord } from "../BatchProducerModule"; @@ -31,20 +35,18 @@ import { AsyncLinkedLeafStore } from "../../../state/async/AsyncLinkedLeafStore" import { CachedLinkedLeafStore } from "../../../state/lmt/CachedLinkedLeafStore"; import { executeWithExecutionContext } from "./TransactionExecutionService"; +import { FieldString } from "../../../helpers/utils"; // This is ordered, because javascript maintains the order based on time of first insertion function collectOrderedStateDiff( stateTransitions: UntypedStateTransition[] ): StateRecord { - return stateTransitions.reduce>( - (state, st) => { - if (st.toValue.isSome.toBoolean()) { - state[st.path.toString()] = st.toValue.value; - } - return state; - }, - {} - ); + return stateTransitions.reduce((state, st) => { + if (st.toValue.isSome.toBoolean()) { + state[st.path.toString()] = st.toValue.value; + } + return state; + }, {}); } function createCombinedOrderedStateDiff( @@ -199,7 +201,9 @@ export class BlockResultService { }> { const combinedDiff = createCombinedOrderedStateDiff( block.transactions, - block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) + block.beforeBlockStateTransitions.map((st: UntypedSTJson) => + UntypedStateTransition.fromJSON(st) + ) ); const inMemoryStore = await CachedLinkedLeafStore.new(merkleTreeStore); @@ -222,9 +226,7 @@ export class BlockResultService { transactionsHash: Field(block.transactionsHash), eternalTransactionsHash: Field(block.toEternalTransactionsHash), }, - new NetworkState( - NetworkState.fromJSON(block.networkState.during) - ), + new NetworkState(NetworkState.fromJSON(block.networkState.during)), stateService ); @@ -242,17 +244,17 @@ export class BlockResultService { return { result: { - afterNetworkState: methodResult, + afterNetworkState: NetworkState.toJSON(methodResult), // This is the state root after the last tx and the afterBlock hook - stateRoot: stateRoot.toBigInt(), - witnessedRoots: [witnessedStateRoot.toBigInt()], - blockHashRoot: blockHashRoot.toBigInt(), - blockHashWitness, + stateRoot: FieldString(stateRoot), + witnessedRoots: [FieldString(witnessedStateRoot)], + blockHashRoot: FieldString(blockHashRoot), + blockHashWitness: BlockHashMerkleTreeWitness.toJSON(blockHashWitness), afterBlockStateTransitions: stateTransitions.map((st) => UntypedStateTransition.fromStateTransition(st).toJSON() ), - blockHash: BigInt(block.hash), + blockHash: FieldString(block.hash), }, treeStore: inMemoryStore, blockHashTreeStore: cachedBlockHashTreeStore, diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 4264aeb17..791a5b1ed 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -79,7 +79,7 @@ export interface BlockResult { blockHashRoot: string; afterNetworkState: NetworkStateJson; afterBlockStateTransitions: UntypedSTJson[]; - blockHashWitness: BlockHashMerkleTreeWitness; + blockHashWitness: BlockHashMerkleTreeWitnessJson; } export interface BlockWithResult { @@ -126,7 +126,7 @@ export const BlockWithResult = { stateRoot: String(LinkedMerkleTree.EMPTY_ROOT), blockHashRoot: String(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], - blockHashWitness: BlockHashMerkleTree.WITNESS.dummy(), + blockHashWitness: BlockHashMerkleTreeWitness.toJSON(BlockHashMerkleTree.WITNESS.dummy()), blockHash: "0", witnessedRoots: [String(LinkedMerkleTree.EMPTY_ROOT)], }, From 31db4aac1115254e5ec1d81663c9e383f7e0900b Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 14 Jan 2026 12:23:45 +0300 Subject: [PATCH 14/63] refactor: refactor BlockMapper and BlockResultMapper with new types --- .../services/prisma/mappers/BlockMapper.ts | 20 ++++----- .../prisma/mappers/BlockResultMapper.ts | 43 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index 9fb586417..cec90a877 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,8 +1,11 @@ import { singleton } from "tsyringe"; -import { Block } from "@proto-kit/sequencer"; -import { Block as PrismaBlock } from "@prisma/client"; -import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; -import { Field } from "o1js"; +import { + Block, + UntypedStateTransition, + UntypedSTJson, +} from "@proto-kit/sequencer"; +import { Prisma, Block as PrismaBlock } from "@prisma/client"; +import { NetworkStateJson } from "@proto-kit/protocol"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -42,9 +45,8 @@ export class BlockMapper implements ObjectMapper { previousBlockHash: input.parentHash !== null ? input.parentHash : undefined, - beforeBlockStateTransitions: this.stArrayMapper.mapIn( - input.beforeBlockStateTransitions - ), + // This is cleaner to keep mapIn + beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as UntypedSTJson[] }; } @@ -65,9 +67,7 @@ export class BlockMapper implements ObjectMapper { parentHash: input.previousBlockHash ?? null, batchHeight: null, - beforeBlockStateTransitions: this.stArrayMapper.mapOut( - input.beforeBlockStateTransitions - ), + beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as Prisma.JsonArray }; } } diff --git a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts index fd65c6d02..2a9ea3852 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts @@ -1,7 +1,10 @@ import { singleton } from "tsyringe"; -import { BlockResult } from "@proto-kit/sequencer"; +import { BlockResult, UntypedStateTransition } from "@proto-kit/sequencer"; import { BlockResult as DBBlockResult } from "@prisma/client"; -import { BlockHashMerkleTreeWitness, NetworkState } from "@proto-kit/protocol"; +import { + BlockHashMerkleTreeWitnessJson, + NetworkStateJson, +} from "@proto-kit/protocol"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -17,23 +20,19 @@ export class BlockResultMapper public mapIn(input: DBBlockResult): BlockResult { return { - afterNetworkState: new NetworkState( - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - NetworkState.fromJSON(input.afterNetworkState as any) - ), + afterNetworkState: input.afterNetworkState as NetworkStateJson, - stateRoot: BigInt(input.stateRoot), - blockHashRoot: BigInt(input.blockHashRoot), - blockHashWitness: new BlockHashMerkleTreeWitness( - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - BlockHashMerkleTreeWitness.fromJSON(input.blockHashWitness as any) - ), - afterBlockStateTransitions: this.stArrayMapper.mapIn( - input.afterBlockStateTransitions - ), - blockHash: BigInt(input.blockHash), + stateRoot: input.stateRoot, + blockHashRoot: input.blockHashRoot, + blockHashWitness: + input.blockHashWitness as BlockHashMerkleTreeWitnessJson, - witnessedRoots: [BigInt(input.witnessedRoots[0])], + afterBlockStateTransitions: this.stArrayMapper + .mapIn(input.afterBlockStateTransitions) + .map((st) => st.toJSON()), + blockHash: input.blockHash, + + witnessedRoots: [input.witnessedRoots[0]], }; } @@ -43,13 +42,13 @@ export class BlockResultMapper blockHash: input.blockHash.toString(), blockHashRoot: input.blockHashRoot.toString(), - blockHashWitness: BlockHashMerkleTreeWitness.toJSON( - input.blockHashWitness - ), + blockHashWitness: input.blockHashWitness, afterBlockStateTransitions: this.stArrayMapper.mapOut( - input.afterBlockStateTransitions + input.afterBlockStateTransitions.map((st) => + UntypedStateTransition.fromJSON(st) + ) ), - afterNetworkState: NetworkState.toJSON(input.afterNetworkState), + afterNetworkState: input.afterNetworkState, witnessedRoots: [input.witnessedRoots[0].toString()], }; From 7706aa35db02511613c0e627fab3362305bfa14d Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 14 Jan 2026 13:51:27 +0300 Subject: [PATCH 15/63] refactor: update methodId type to string --- .../library/src/hooks/RuntimeFeeAnalyzerService.ts | 6 +++--- packages/module/src/runtime/MethodIdResolver.ts | 10 +++++----- packages/module/src/runtime/Runtime.ts | 2 +- packages/processor/test/HandlersExecutor.test.ts | 2 +- packages/protocol/src/model/RuntimeLike.ts | 2 +- .../src/mempool/verification/TransactionValidator.ts | 2 +- .../sequencing/TransactionExecutionService.ts | 4 ++-- .../protocol/production/tasks/RuntimeProvingTask.ts | 4 ++-- .../runtime/RuntimeVerificationKeyService.ts | 12 ++++++------ .../messages/MinaIncomingMessageAdapter.ts | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts index 707d80a4c..22ec51bd1 100644 --- a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts +++ b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts @@ -110,8 +110,8 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule { - dict[this.getMethodId(moduleName, methodName).toString()] = { + dict[this.getMethodId(moduleName, methodName)] = { moduleName, methodName, }; @@ -83,8 +83,8 @@ export class MethodIdResolver { }, {}); } - public getMethodNameFromId(methodId: bigint): [string, string] | undefined { - const methodPath = this.dictionary[methodId.toString()]; + public getMethodNameFromId(methodId: string): [string, string] | undefined { + const methodPath = this.dictionary[methodId]; if (methodPath === undefined) { return undefined; @@ -97,12 +97,12 @@ export class MethodIdResolver { return [moduleName, methodName]; } - public getMethodId(moduleName: string, methodName: string): bigint { + public getMethodId(moduleName: string, methodName: string): string { this.runtime.assertIsValidModuleName(moduleName); return Poseidon.hash([ stringToField(moduleName), stringToField(methodName), - ]).toBigInt(); + ]).toString(); } } diff --git a/packages/module/src/runtime/Runtime.ts b/packages/module/src/runtime/Runtime.ts index 37bd65e7c..468940e8e 100644 --- a/packages/module/src/runtime/Runtime.ts +++ b/packages/module/src/runtime/Runtime.ts @@ -337,7 +337,7 @@ export class Runtime * Encoding: "stringToField(module.name) << 128 + stringToField(method-name)" */ public getMethodById( - methodId: bigint + methodId: string ): ((...args: unknown[]) => Promise) | undefined { const methodDescriptor = this.methodIdResolver.getMethodNameFromId(methodId); diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index da95a1f53..32623fb7f 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -42,7 +42,7 @@ describe("HandlersModule", () => { ) => { // iterate over all transactions for (const tx of block.transactions) { - const methodId = tx.tx.methodId.toBigInt(); + const methodId = tx.tx.methodId.toString(); const methodDescriptor = appChain.runtime.methodIdResolver.getMethodNameFromId(methodId); diff --git a/packages/protocol/src/model/RuntimeLike.ts b/packages/protocol/src/model/RuntimeLike.ts index ec636f5d0..733b1620d 100644 --- a/packages/protocol/src/model/RuntimeLike.ts +++ b/packages/protocol/src/model/RuntimeLike.ts @@ -2,7 +2,7 @@ export type RuntimeMethodInvocationType = "INCOMING_MESSAGE" | "SIGNATURE"; export type RuntimeMethodIdMapping = Record< `${string}.${string}`, - { methodId: bigint; type: RuntimeMethodInvocationType } + { methodId: string; type: RuntimeMethodInvocationType } >; export interface RuntimeLike { diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index c839ecece..c6827a287 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -20,7 +20,7 @@ export class TransactionValidator { // module name validation happens inside getMethodNameFromId // and also in the next step const methodPath = this.runtime.methodIdResolver.getMethodNameFromId( - tx.methodId.toBigInt() + tx.methodId.toString() ); if (methodPath === undefined) { diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 753cfbb8f..0e27026d1 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -88,10 +88,10 @@ async function decodeTransaction( module: RuntimeModule; }> { const methodDescriptors = runtime.methodIdResolver.getMethodNameFromId( - tx.methodId.toBigInt() + tx.methodId.toString() ); - const method = runtime.getMethodById(tx.methodId.toBigInt()); + const method = runtime.getMethodById(tx.methodId.toString()); if (methodDescriptors === undefined || method === undefined) { throw errors.methodIdNotFound(tx.methodId.toString()); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 3fe0756d3..bf3dd50d1 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -57,11 +57,11 @@ export class RuntimeProvingTask } public async compute(input: RuntimeProofParameters): Promise { - const method = this.runtime.getMethodById(input.tx.methodId.toBigInt()); + const method = this.runtime.getMethodById(input.tx.methodId.toString()); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(input.tx.methodId.toBigInt()); + .getMethodNameFromId(input.tx.methodId.toString()); if (methodDescriptors === undefined || method === undefined) { throw new Error(`MethodId not found ${input.tx.methodId.toString()}`); diff --git a/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts b/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts index 5445d6e63..9f6607b68 100644 --- a/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts +++ b/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts @@ -25,7 +25,7 @@ export type VKRecord = { }; export interface WithGetMethodId { - getMethodId: (moduleName: string, methodName: string) => bigint; + getMethodId: (moduleName: string, methodName: string) => string; } export interface WithZkProgrammableAndGetMethodById { @@ -82,7 +82,7 @@ export class VerificationKeyService extends ConfigurableModule<{}> { ); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return [ - methodId.toString(), + methodId, new VerificationKey(artifact.verificationKey), ] as [string, VerificationKey]; }); @@ -131,8 +131,8 @@ export class VerificationKeyService extends ConfigurableModule<{}> { return this.persistedVKRecord; } - public getAttestation(methodId: bigint) { - const verificationKey = this.getVkRecord()[methodId.toString()]; + public getAttestation(methodId: string) { + const verificationKey = this.getVkRecord()[methodId]; if (verificationKey === undefined) { throw new Error( `MethodId not registered in VerificationKeyService (${methodId})` @@ -147,9 +147,9 @@ export class VerificationKeyService extends ConfigurableModule<{}> { }); } - public getWitness(methodId: bigint) { + public getWitness(methodId: string) { const vkTree = this.getVKTree(); - return vkTree.tree.getWitness(vkTree.indexes[methodId.toString()]); + return vkTree.tree.getWitness(vkTree.indexes[methodId]); } public getRoot(): bigint { diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 764cfd1ae..44eb99a6e 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -71,7 +71,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { const { methodId } = tx; const methodPointer = this.runtime.methodIdResolver.getMethodNameFromId( - methodId.toBigInt() + methodId.toString() ); if (methodPointer === undefined) { From b46e81d147df1be57ca86ca6a53416d38def119c Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 14 Jan 2026 21:18:05 +0300 Subject: [PATCH 16/63] refactor: add minor change to use methodId --- .../src/protocol/production/sequencing/BlockProducerModule.ts | 2 +- .../protocol/production/tracing/TransactionTracingService.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 1507c3afd..065b83421 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -74,7 +74,7 @@ export class BlockProducerModule extends SequencerModule { private prettyPrintBlockContents(block: Block) { block.transactions.forEach((tx, i) => { const methodName = this.methodIdResolver.getMethodNameFromId( - tx.tx.methodId.toBigInt() + tx.tx.methodId.toString() ); if (!methodName) return; diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 4b30745b5..6f420aa73 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -74,7 +74,7 @@ export class TransactionTracingService { ): Promise { const verificationKeyAttestation = this.verificationKeyService.getAttestation( - transaction.methodId.toBigInt() + transaction.methodId.toString() ); return { From 5934a1331242bb11d823bede243c9b9c35f3cb33 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 14 Jan 2026 21:31:55 +0300 Subject: [PATCH 17/63] refactor: rename UntypedSTJson to UntypedStateTranisitionJson --- .../src/services/prisma/mappers/BlockMapper.ts | 4 ++-- packages/sequencer/src/mempool/PendingTransaction.ts | 2 +- .../protocol/production/helpers/UntypedStateTransition.ts | 2 +- .../protocol/production/sequencing/BlockResultService.ts | 4 ++-- .../protocol/production/tracing/BlockTracingService.ts | 8 ++++---- .../production/tracing/StateTransitionTracingService.ts | 6 +++--- packages/sequencer/src/storage/model/Block.ts | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index cec90a877..30fbb3e0b 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -2,7 +2,7 @@ import { singleton } from "tsyringe"; import { Block, UntypedStateTransition, - UntypedSTJson, + UntypedStateTransitionJson, } from "@proto-kit/sequencer"; import { Prisma, Block as PrismaBlock } from "@prisma/client"; import { NetworkStateJson } from "@proto-kit/protocol"; @@ -46,7 +46,7 @@ export class BlockMapper implements ObjectMapper { input.parentHash !== null ? input.parentHash : undefined, // This is cleaner to keep mapIn - beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as UntypedSTJson[] + beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as UntypedStateTransitionJson[] }; } diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index fd1fedfec..09ac55639 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -118,7 +118,7 @@ export class UnsignedTransaction implements UnsignedTransactionBody { } } -interface PendingTransactionJSONType { +export interface PendingTransactionJSONType { hash: string; methodId: string; nonce: string; diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index f2181bceb..ecd433cde 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -3,7 +3,7 @@ import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; -export interface UntypedSTJson{ +export interface UntypedStateTransitionJson{ path: string, from:{ isSome: boolean; diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index ba7a1db92..5979af780 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -24,7 +24,7 @@ import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore" import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; import { UntypedStateTransition, - UntypedSTJson, + UntypedStateTransitionJson, } from "../helpers/UntypedStateTransition"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; @@ -201,7 +201,7 @@ export class BlockResultService { }> { const combinedDiff = createCombinedOrderedStateDiff( block.transactions, - block.beforeBlockStateTransitions.map((st: UntypedSTJson) => + block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) ) ); diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 0d4e7ea83..1a8c8304b 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -22,7 +22,7 @@ import { TransactionTrace, TransactionTracingService, } from "./TransactionTracingService"; -import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition, UntypedStateTransitionJson } from "../helpers/UntypedStateTransition"; export type TaskStateRecord = Record; @@ -75,7 +75,7 @@ export class BlockTracingService { }); const startingStateBeforeHook = collectStartingState( - block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) + block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) ); const blockTrace = { @@ -92,7 +92,7 @@ export class BlockTracingService { state.pendingSTBatches.push({ batchHash: toStateTransitionsHash( - block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) + block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) ), applied: Bool(true), }); @@ -142,7 +142,7 @@ export class BlockTracingService { } const startingStateAfterHook = collectStartingState( - block.result.afterBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)) + block.result.afterBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) ); state.networkState = new NetworkState( NetworkState.fromJSON(block.result.afterNetworkState) diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index 41448f290..eca11b2ad 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -18,7 +18,7 @@ import { import { distinctByString } from "../../../helpers/utils"; import { BlockWithResult } from "../../../storage/model/Block"; -import { UntypedStateTransition, UntypedSTJson } from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition, UntypedStateTransitionJson } from "../helpers/UntypedStateTransition"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; @@ -47,7 +47,7 @@ export class StateTransitionTracingService { return blocks.reduce((previous, block) => { const batches = [ { - stateTransitions: block.block.beforeBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)), + stateTransitions: block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)), applied: true, }, ...block.block.transactions.flatMap((tx) => tx.stateTransitions), @@ -62,7 +62,7 @@ export class StateTransitionTracingService { } return batchBeforeWitnessing.concat({ - stateTransitions: block.result.afterBlockStateTransitions.map((st: UntypedSTJson) => UntypedStateTransition.fromJSON(st)), + stateTransitions: block.result.afterBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)), applied: true, witnessRoot: false, }); diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 791a5b1ed..d89fd34d5 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -12,7 +12,7 @@ import { LinkedMerkleTree } from "@proto-kit/common"; import { PendingTransaction } from "../../mempool/PendingTransaction"; import { UntypedStateTransition, - UntypedSTJson, + UntypedStateTransitionJson, } from "../../protocol/production/helpers/UntypedStateTransition"; import { FieldString } from "../../helpers/utils"; @@ -55,7 +55,7 @@ export interface Block { toEternalTransactionsHash: FieldString; toMessagesHash: FieldString; - beforeBlockStateTransitions: UntypedSTJson[]; + beforeBlockStateTransitions: UntypedStateTransitionJson[]; } // eslint-disable-next-line @typescript-eslint/no-redeclare @@ -78,7 +78,7 @@ export interface BlockResult { stateRoot: string; blockHashRoot: string; afterNetworkState: NetworkStateJson; - afterBlockStateTransitions: UntypedSTJson[]; + afterBlockStateTransitions: UntypedStateTransitionJson[]; blockHashWitness: BlockHashMerkleTreeWitnessJson; } From b017bb565b22e9b859da2287d7d8b20cd5d9aa43 Mon Sep 17 00:00:00 2001 From: saitunc Date: Wed, 14 Jan 2026 23:03:04 +0300 Subject: [PATCH 18/63] refactor: implement TransactionExecutionResultJson and use it for Block --- .../api/src/graphql/modules/BlockResolver.ts | 6 +- .../sdk/src/query/InMemoryBlockExplorer.ts | 18 +++--- .../sequencing/BlockProducerModule.ts | 12 ++-- .../sequencing/BlockProductionService.ts | 3 +- .../sequencing/BlockResultService.ts | 8 ++- .../production/tracing/BlockTracingService.ts | 4 +- .../tracing/StateTransitionTracingService.ts | 7 ++- .../outgoing/DefaultOutgoingMessageAdapter.ts | 2 +- .../inmemory/InMemoryTransactionStorage.ts | 8 +-- packages/sequencer/src/storage/model/Block.ts | 58 ++++++++++++++++++- 10 files changed, 91 insertions(+), 35 deletions(-) diff --git a/packages/api/src/graphql/modules/BlockResolver.ts b/packages/api/src/graphql/modules/BlockResolver.ts index a62675dcb..257b3a9d0 100644 --- a/packages/api/src/graphql/modules/BlockResolver.ts +++ b/packages/api/src/graphql/modules/BlockResolver.ts @@ -1,5 +1,5 @@ import { inject } from "tsyringe"; -import { Block, BlockStorage } from "@proto-kit/sequencer"; +import { Block, BlockStorage, PendingTransaction } from "@proto-kit/sequencer"; import { Arg, Field, ObjectType, Query } from "type-graphql"; import { GraphqlModule, graphqlModule } from "../GraphqlModule"; @@ -13,8 +13,8 @@ export class BlockModel { Number(block.networkState.during.block.height), block.transactions.map((tx) => BatchTransactionModel.fromServiceLayerModel({ - tx: tx.tx, - status: tx.status.toBoolean(), + tx: PendingTransaction.fromJSON(tx.tx), + status: tx.status, statusMessage: tx.statusMessage, }) ), diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index 103e52c4a..d1356b250 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -65,20 +65,16 @@ export class InMemoryBlockExplorer const clientTransactions: ClientTransaction[] = block.transactions.map( (txResult) => ({ tx: { - hash: txResult.tx.hash().toString(), - methodId: txResult.tx.methodId.toString(), - nonce: txResult.tx.nonce.toString(), - sender: txResult.tx.sender.toBase58(), - argsFields: txResult.tx.argsFields.map((f) => f.toString()), + hash: txResult.tx.hash, + methodId: txResult.tx.methodId, + nonce: txResult.tx.nonce, + sender: txResult.tx.sender, + argsFields: txResult.tx.argsFields, auxiliaryData: txResult.tx.auxiliaryData, - signature: { - r: txResult.tx.signature.r.toString(), - // eslint-disable-next-line @typescript-eslint/no-base-to-string - s: txResult.tx.signature.s.toString(), - }, + signature: txResult.tx.signature, isMessage: txResult.tx.isMessage, }, - status: txResult.status.toBoolean(), + status: txResult.status, statusMessage: txResult.statusMessage, }) ); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 065b83421..2eb876380 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -6,7 +6,7 @@ import { Runtime, RuntimeModulesRecord, } from "@proto-kit/module"; -import { Provable } from "o1js"; +import { Field, Provable } from "o1js"; import { Mempool } from "../../../mempool/Mempool"; import { @@ -74,7 +74,7 @@ export class BlockProducerModule extends SequencerModule { private prettyPrintBlockContents(block: Block) { block.transactions.forEach((tx, i) => { const methodName = this.methodIdResolver.getMethodNameFromId( - tx.tx.methodId.toString() + tx.tx.methodId ); if (!methodName) return; @@ -88,20 +88,20 @@ export class BlockProducerModule extends SequencerModule { log.info(`Transaction #${i}`); log.info( "Sender:", - tx.tx.sender.toBase58(), + tx.tx.sender, "Nonce:", - tx.tx.nonce.toBigInt() + tx.tx.nonce ); log.info(`Method: ${methodName?.join(".")}`); log.info(); if (log.getLevel() <= log.levels.INFO) { Provable.log( "Arguments:", - paramEncoder.decode(tx.tx.argsFields, tx.tx.auxiliaryData) + paramEncoder.decode(tx.tx.argsFields.map((s) => Field(s)), tx.tx.auxiliaryData) ); } log.info( - `Status: ${tx.status.toBoolean()}`, + `Status: ${tx.status ? "true" : "false"}`, tx.statusMessage !== undefined ? `Reason: ${tx.statusMessage}` : "" ); }); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 5027d4fab..a80da5fb9 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -21,6 +21,7 @@ import { Block, BlockWithResult, TransactionExecutionResult, + txResultToJson, } from "../../../storage/model/Block"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; @@ -164,7 +165,7 @@ export class BlockProductionService { .map((x) => x.result); const block: Omit = { - transactions: includedTransactions, + transactions: includedTransactions.map(txResultToJson), transactionsHash: FieldString(newBlockState.transactionList.commitment), fromEternalTransactionsHash: lastBlock.toEternalTransactionsHash, toEternalTransactionsHash: diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 5979af780..8de3098dd 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -18,7 +18,7 @@ import { inject, injectable, Lifecycle, scoped } from "tsyringe"; import { Block, BlockResult, - TransactionExecutionResult, + TransactionExecutionResultJson, } from "../../../storage/model/Block"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; @@ -50,7 +50,7 @@ function collectOrderedStateDiff( } function createCombinedOrderedStateDiff( - transactions: TransactionExecutionResult[], + transactions: TransactionExecutionResultJson[], blockHookSTs: UntypedStateTransition[] ) { // Flatten diff list into a single diff by applying them over each other @@ -58,7 +58,9 @@ function createCombinedOrderedStateDiff( .map((tx) => { const transitions = tx.stateTransitions .filter(({ applied }) => applied) - .flatMap(({ stateTransitions }) => stateTransitions); + .flatMap(({ stateTransitions }) => + stateTransitions.map(st => UntypedStateTransition.fromJSON(st)) + ); transitions.push(...blockHookSTs); diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 1a8c8304b..1ce1b497f 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -12,7 +12,7 @@ import { yieldSequential } from "@proto-kit/common"; import chunk from "lodash/chunk"; import { inject, injectable } from "tsyringe"; -import { BlockWithResult } from "../../../storage/model/Block"; +import { BlockWithResult, txResultFromJson } from "../../../storage/model/Block"; import type { NewBlockProverParameters } from "../tasks/NewBlockTask"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; @@ -101,7 +101,7 @@ export class BlockTracingService { ) ; const [afterState, transactionTraces] = await yieldSequential( - chunk(block.block.transactions, 2), + chunk(block.block.transactions.map(txResultFromJson), 2), async (input, [transaction1, transaction2]) => { const [output, transactionTrace] = transaction2 !== undefined diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index eca11b2ad..2242cb045 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -50,7 +50,12 @@ export class StateTransitionTracingService { stateTransitions: block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)), applied: true, }, - ...block.block.transactions.flatMap((tx) => tx.stateTransitions), + ...block.block.transactions.flatMap((tx) => + tx.stateTransitions.map(batch => ({ + stateTransitions: batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st)), + applied: batch.applied, + })) + ), ].map((batch) => ({ ...batch, witnessRoot: false })); const batchBeforeWitnessing = previous.concat(batches); diff --git a/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts index 3653d023d..e70fa5035 100644 --- a/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts @@ -61,7 +61,7 @@ export class DefaultOutgoingMessageAdapter ) .map((event) => { const type = this.outgoingWithdrawalEvents[event.eventName]; - return type.eventType.fromFields(event.data); + return type.eventType.fromFields(event.data.map(d => Field(d))); }) ); } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index 146dc9a6e..216ec41e2 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -1,5 +1,4 @@ import { inject, injectable } from "tsyringe"; -import { Field } from "o1js"; import { TransactionStorage } from "../repositories/TransactionStorage"; import { PendingTransaction } from "../../mempool/PendingTransaction"; @@ -37,7 +36,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { // eslint-disable-next-line no-await-in-loop const block = await this.blockStorage.getBlockAt(height); if (block !== undefined) { - const hashes = block.transactions.map((tx) => tx.tx.hash().toString()); + const hashes = block.transactions.map((tx) => tx.tx.hash); this.queue = this.queue.filter( (tx) => !hashes.includes(tx.hash().toString()) ); @@ -92,7 +91,6 @@ export class InMemoryTransactionStorage implements TransactionStorage { } const tipHeight = await this.blockStorage.getCurrentBlockHeight(); - const hashField = Field(hash); for (let height = tipHeight - 1; height >= 0; height--) { // eslint-disable-next-line no-await-in-loop @@ -101,13 +99,13 @@ export class InMemoryTransactionStorage implements TransactionStorage { return undefined; } const txResult = block.transactions.find((tx) => - tx.tx.hash().equals(hashField).toBoolean() + tx.tx.hash === hash ); if (txResult !== undefined) { // eslint-disable-next-line no-await-in-loop const batch = await this.findBatch(block.hash); return { - transaction: txResult.tx, + transaction: PendingTransaction.fromJSON(txResult.tx), block: block.transactionsHash, batch, }; diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index d89fd34d5..224b8923a 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -9,7 +9,7 @@ import { } from "@proto-kit/protocol"; import { LinkedMerkleTree } from "@proto-kit/common"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { UntypedStateTransition, UntypedStateTransitionJson, @@ -34,6 +34,60 @@ export interface TransactionExecutionResult { }[]; } +export interface StateTransitionBatchJson { + stateTransitions: UntypedStateTransitionJson[]; + applied: boolean; +} + +export interface TransactionExecutionResultJson { + tx: PendingTransactionJSONType; + stateTransitions: StateTransitionBatchJson[]; + status: boolean; + hooksStatus: boolean; + statusMessage?: string; + events: { + eventName: string; + data: FieldString[]; + source: "afterTxHook" | "beforeTxHook" | "runtime"; + }[]; +} + +export function txResultToJson(txResult: TransactionExecutionResult): TransactionExecutionResultJson { + return { + tx: txResult.tx.toJSON(), + stateTransitions: txResult.stateTransitions.map(batch => ({ + stateTransitions: batch.stateTransitions.map(st => st.toJSON()), + applied: batch.applied, + })), + status: txResult.status.toBoolean(), + hooksStatus: txResult.hooksStatus.toBoolean(), + statusMessage: txResult.statusMessage, + events: txResult.events.map(e => ({ + eventName: e.eventName, + data: e.data.map(f => f.toString()), + source: e.source, + })), + }; +} + +export function txResultFromJson(json: TransactionExecutionResultJson): TransactionExecutionResult { + return { + tx: PendingTransaction.fromJSON(json.tx), + stateTransitions: json.stateTransitions.map(batch => ({ + stateTransitions: batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st)), + applied: batch.applied, + })), + status: Bool(json.status), + hooksStatus: Bool(json.hooksStatus), + statusMessage: json.statusMessage, + events: json.events.map(e => ({ + eventName: e.eventName, + data: e.data.map(f => Field(f)), + source: e.source, + })), + }; +} + // TODO Why is Block using Fields, but BlockResult bigints? Align that towards the best option export interface Block { @@ -45,7 +99,7 @@ export interface Block { during: NetworkStateJson; }; - transactions: TransactionExecutionResult[]; + transactions: TransactionExecutionResultJson[]; transactionsHash: FieldString; fromEternalTransactionsHash: FieldString; From d3c93366ea437cfb7aef43037d9654009c5f8d0f Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 01:18:56 +0300 Subject: [PATCH 19/63] refactor: refactor PrivateMempool to use PendingTransactionJson type --- .../src/mempool/private/PrivateMempool.ts | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index d6d3319c8..482e5cb8f 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -20,7 +20,7 @@ import { import { Field } from "o1js"; import type { Mempool, MempoolEvents } from "../Mempool"; -import type { PendingTransaction } from "../PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../PendingTransaction"; import { sequencerModule, SequencerModule, @@ -35,8 +35,8 @@ import { Tracer } from "../../logging/Tracer"; import { trace } from "../../logging/trace"; type MempoolTransactionPaths = { - transaction: PendingTransaction; - paths: Field[]; + transaction: PendingTransactionJSONType; + paths: string[]; }; interface PrivateMempoolConfig { @@ -74,16 +74,16 @@ export class PrivateMempool return txs.length; } - public async add(tx: PendingTransaction): Promise { + public async add(tx: PendingTransactionJSONType): Promise { const [txValid, error] = this.transactionValidator.validateTx(tx); if (txValid) { const success = await this.transactionStorage.pushUserTransaction(tx); if (success) { - this.events.emit("mempool-transaction-added", tx); - log.trace(`Transaction added to mempool: ${tx.hash().toString()}`); + this.events.emit("mempool-transaction-added", PendingTransaction.fromJSON(tx)); + log.trace(`Transaction added to mempool: ${tx.hash}`); } else { log.error( - `Transaction ${tx.hash().toString()} rejected: already exists in mempool` + `Transaction ${tx.hash} rejected: already exists in mempool` ); } @@ -91,12 +91,12 @@ export class PrivateMempool } log.error( - `Validation of tx ${tx.hash().toString()} failed:`, + `Validation of tx ${tx.hash} failed:`, `${error ?? "unknown error"}` ); throw new Error( - `Validation of tx ${tx.hash().toString()} failed: ${error ?? "unknown error"}` + `Validation of tx ${tx.hash} failed: ${error ?? "unknown error"}` ); } @@ -117,7 +117,7 @@ export class PrivateMempool } @trace("mempool.get_txs") - public async getTxs(limit?: number): Promise { + public async getTxs(limit?: number): Promise { // TODO Add limit to the storage (or do something smarter entirely) const txs = await this.transactionStorage.getPendingUserTransactions(); @@ -127,8 +127,8 @@ export class PrivateMempool const stagedNetworkState = await this.getStagedNetworkState(); const networkState = stagedNetworkState - ? new NetworkState(NetworkState.fromJSON(stagedNetworkState)) - : NetworkState.empty(); + ? stagedNetworkState + : NetworkState.toJSON(NetworkState.empty()); const validationEnabled = this.config.validationEnabled ?? false; const sortedTxs = validationEnabled @@ -154,10 +154,10 @@ export class PrivateMempool @trace("mempool.validate_txs") // eslint-disable-next-line sonarjs/cognitive-complexity private async checkTxValid( - transactions: PendingTransaction[], + transactions: PendingTransactionJSONType[], baseService: CachedStateService, stateServiceProvider: StateServiceProvider, - networkState: NetworkState, + networkState: NetworkStateJson, limit?: number ) { const executionContext = container.resolve( @@ -166,10 +166,10 @@ export class PrivateMempool executionContext.clear(); // Initialize starting state - const sortedTransactions: PendingTransaction[] = []; + const sortedTransactions: PendingTransactionJSONType[] = []; const skippedTransactions: Record = {}; - let queue: PendingTransaction[] = [...transactions]; + let queue: PendingTransactionJSONType[] = [...transactions]; const previousBlock = await this.unprovenQueue.getLatestBlock(); @@ -193,24 +193,31 @@ export class PrivateMempool : Field(0), }; + const provableNetworkState = new NetworkState( + NetworkState.fromJSON(networkState) + ); + + let pendingTransaction: PendingTransaction; + while ( queue.length > 0 && sortedTransactions.length < (limit ?? Number.MAX_VALUE) ) { const [tx] = queue.splice(0, 1); + pendingTransaction = PendingTransaction.fromJSON(tx); const txStateService = new CachedStateService(baseService); stateServiceProvider.setCurrentStateService(txStateService); const contextInputs: RuntimeMethodExecutionData = { - networkState: networkState, - transaction: tx.toProtocolTransaction().transaction, + networkState: provableNetworkState, + transaction: pendingTransaction.toProtocolTransaction().transaction, }; executionContext.setup(contextInputs); - const signedTransaction = tx.toProtocolTransaction(); + const signedTransaction = pendingTransaction.toProtocolTransaction(); // eslint-disable-next-line no-await-in-loop await this.accountStateHook.beforeTransaction({ - networkState: networkState, + networkState: provableNetworkState, transaction: signedTransaction.transaction, signature: signedTransaction.signature, prover: proverState, @@ -219,18 +226,18 @@ export class PrivateMempool executionContext.current().result; if (status.toBoolean()) { - log.trace(`Accepted tx ${tx.hash().toString()}`); + log.trace(`Accepted tx ${tx.hash}`); sortedTransactions.push(tx); // eslint-disable-next-line no-await-in-loop await txStateService.applyStateTransitions(stateTransitions); // eslint-disable-next-line no-await-in-loop await txStateService.mergeIntoParent(); - delete skippedTransactions[tx.hash().toString()]; + delete skippedTransactions[tx.hash]; if (Object.entries(skippedTransactions).length > 0) { // eslint-disable-next-line @typescript-eslint/no-loop-func stateTransitions.forEach((st) => { Object.values(skippedTransactions).forEach((value) => { - if (value.paths.some((x) => x.equals(st.path))) { + if (value.paths.some((x) => x === st.path.toString())) { queue.push(value.transaction); } }); @@ -240,7 +247,7 @@ export class PrivateMempool } else { // eslint-disable-next-line no-await-in-loop const removeTxWhen = await this.accountStateHook.removeTransactionWhen({ - networkState: networkState, + networkState: provableNetworkState, transaction: signedTransaction.transaction, signature: signedTransaction.signature, prover: proverState, @@ -248,25 +255,26 @@ export class PrivateMempool if (removeTxWhen) { // eslint-disable-next-line no-await-in-loop await this.transactionStorage.removeTx( - [tx.hash().toString()], + [tx.hash], "dropped" ); log.trace( - `Deleting tx ${tx.hash().toString()} from mempool because removeTransactionWhen condition is satisfied` + `Deleting tx ${tx.hash} from mempool because removeTransactionWhen condition is satisfied` ); // eslint-disable-next-line no-continue continue; } log.trace( - `Skipped tx ${tx.hash().toString()} because ${statusMessage}` + `Skipped tx ${tx.hash} because ${statusMessage}` ); - if (!(tx.hash().toString() in skippedTransactions)) { - skippedTransactions[tx.hash().toString()] = { + if (!(tx.hash in skippedTransactions)) { + skippedTransactions[tx.hash] = { transaction: tx, paths: stateTransitions .map((x) => x.path) - .filter((id, idx, arr) => arr.indexOf(id) === idx), + .filter((id, idx, arr) => arr.indexOf(id) === idx) + .map((f) => f.toString()), }; } stateServiceProvider.popCurrentStateService(); From 08f95bb47aceadd23f3b593b42be6e7c6f66fa1d Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 03:38:57 +0300 Subject: [PATCH 20/63] refactor: add serialization utility functions for non-provable types --- packages/sequencer/src/storage/model/Block.ts | 103 ++++++++++++------ 1 file changed, 67 insertions(+), 36 deletions(-) diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 224b8923a..31ab41c27 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -52,42 +52,6 @@ export interface TransactionExecutionResultJson { }[]; } -export function txResultToJson(txResult: TransactionExecutionResult): TransactionExecutionResultJson { - return { - tx: txResult.tx.toJSON(), - stateTransitions: txResult.stateTransitions.map(batch => ({ - stateTransitions: batch.stateTransitions.map(st => st.toJSON()), - applied: batch.applied, - })), - status: txResult.status.toBoolean(), - hooksStatus: txResult.hooksStatus.toBoolean(), - statusMessage: txResult.statusMessage, - events: txResult.events.map(e => ({ - eventName: e.eventName, - data: e.data.map(f => f.toString()), - source: e.source, - })), - }; -} - -export function txResultFromJson(json: TransactionExecutionResultJson): TransactionExecutionResult { - return { - tx: PendingTransaction.fromJSON(json.tx), - stateTransitions: json.stateTransitions.map(batch => ({ - stateTransitions: batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st)), - applied: batch.applied, - })), - status: Bool(json.status), - hooksStatus: Bool(json.hooksStatus), - statusMessage: json.statusMessage, - events: json.events.map(e => ({ - eventName: e.eventName, - data: e.data.map(f => Field(f)), - source: e.source, - })), - }; -} - // TODO Why is Block using Fields, but BlockResult bigints? Align that towards the best option export interface Block { @@ -186,3 +150,70 @@ export const BlockWithResult = { }, }) satisfies BlockWithResult, }; + +export function txResultToJson( + txResult: TransactionExecutionResult +): TransactionExecutionResultJson { + return { + tx: txResult.tx.toJSON(), + stateTransitions: txResult.stateTransitions.map((batch) => ({ + stateTransitions: batch.stateTransitions.map((st) => st.toJSON()), + applied: batch.applied, + })), + status: txResult.status.toBoolean(), + hooksStatus: txResult.hooksStatus.toBoolean(), + statusMessage: txResult.statusMessage, + events: txResult.events.map((e) => ({ + eventName: e.eventName, + data: e.data.map((f) => f.toString()), + source: e.source, + })), + }; +} + +export function txResultFromJson( + json: TransactionExecutionResultJson +): TransactionExecutionResult { + return { + tx: PendingTransaction.fromJSON(json.tx), + stateTransitions: json.stateTransitions.map((batch) => ({ + stateTransitions: batch.stateTransitions.map((st) => + UntypedStateTransition.fromJSON(st) + ), + applied: batch.applied, + })), + status: Bool(json.status), + hooksStatus: Bool(json.hooksStatus), + statusMessage: json.statusMessage, + events: json.events.map((e) => ({ + eventName: e.eventName, + data: e.data.map((f) => Field(f)), + source: e.source, + })), + }; +} + +export function STBatchToJson( + stBatch: StateTransitionBatch +): StateTransitionBatchJson { + return { + stateTransitions: stBatch.stateTransitions.map( + (untypedST: UntypedStateTransition) => untypedST.toJSON() + ), + applied: stBatch.applied, + }; +} + +export function STBatchFromJson( + stBatch: StateTransitionBatchJson +): StateTransitionBatch { + return { + stateTransitions: stBatch.stateTransitions.map( + (untypedST: UntypedStateTransitionJson) => + UntypedStateTransition.fromJSON(untypedST) + ), + applied: stBatch.applied, + }; +} + + From d8558f99eb0d42459c27ffc75f50e36f9e5b74be Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 03:41:53 +0300 Subject: [PATCH 21/63] refactor: use non-provable types in storage and mempool interfaces --- packages/sequencer/src/mempool/Mempool.ts | 6 +++--- .../inmemory/InMemoryMessageStorage.ts | 10 +++++----- .../inmemory/InMemoryTransactionStorage.ts | 20 +++++++++---------- .../storage/repositories/MessageStorage.ts | 8 ++++---- .../repositories/TransactionStorage.ts | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/sequencer/src/mempool/Mempool.ts b/packages/sequencer/src/mempool/Mempool.ts index 97401a973..3f679d59e 100644 --- a/packages/sequencer/src/mempool/Mempool.ts +++ b/packages/sequencer/src/mempool/Mempool.ts @@ -1,6 +1,6 @@ import { EventEmittingComponent } from "@proto-kit/common"; -import type { PendingTransaction } from "./PendingTransaction"; +import type { PendingTransaction, PendingTransactionJSONType } from "./PendingTransaction"; export type MempoolEvents = { "mempool-transaction-added": [PendingTransaction]; @@ -12,12 +12,12 @@ export interface Mempool * Add a transaction to the mempool * @returns The new commitment to the mempool */ - add: (tx: PendingTransaction) => Promise; + add: (tx: PendingTransactionJSONType) => Promise; /** * Retrieve all transactions that are currently in the mempool */ - getTxs: (limit?: number) => Promise; + getTxs: (limit?: number) => Promise; removeTxs: (included: string[], dropped: string[]) => Promise; } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts index 1bf671315..8f33605fa 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts @@ -1,6 +1,6 @@ import { injectable } from "tsyringe"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { MessageStorage } from "../repositories/MessageStorage"; @injectable() @@ -8,7 +8,7 @@ export class InMemoryMessageStorage implements MessageStorage { private messages: { [key: string]: { toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }; } = {}; @@ -16,7 +16,7 @@ export class InMemoryMessageStorage implements MessageStorage { | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; } | undefined > { @@ -37,7 +37,7 @@ export class InMemoryMessageStorage implements MessageStorage { const batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }[] = []; let currentHash = fromMessagesHash; @@ -61,7 +61,7 @@ export class InMemoryMessageStorage implements MessageStorage { public async pushMessages( fromMessagesHash: string, toMessagesHash: string, - messages: PendingTransaction[] + messages: PendingTransactionJSONType[] ): Promise { this.messages[fromMessagesHash] = { messages, diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index 216ec41e2..6efff1089 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -1,14 +1,14 @@ import { inject, injectable } from "tsyringe"; import { TransactionStorage } from "../repositories/TransactionStorage"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { BlockStorage } from "../repositories/BlockStorage"; import { InMemoryBatchStorage } from "./InMemoryBatchStorage"; @injectable() export class InMemoryTransactionStorage implements TransactionStorage { - private queue: PendingTransaction[] = []; + private queue: PendingTransactionJSONType[] = []; private latestScannedBlock = -1; @@ -21,12 +21,12 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async removeTx(hashes: string[]) { const hashSet = new Set(hashes); this.queue = this.queue.filter((tx) => { - const hash = tx.hash().toString(); + const hash = tx.hash; return !hashSet.has(hash); }); } - public async getPendingUserTransactions(): Promise { + public async getPendingUserTransactions(): Promise { const nextHeight = await this.blockStorage.getCurrentBlockHeight(); for ( let height = this.latestScannedBlock + 1; @@ -38,7 +38,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { if (block !== undefined) { const hashes = block.transactions.map((tx) => tx.tx.hash); this.queue = this.queue.filter( - (tx) => !hashes.includes(tx.hash().toString()) + (tx) => !hashes.includes(tx.hash) ); } } @@ -47,10 +47,10 @@ export class InMemoryTransactionStorage implements TransactionStorage { return this.queue.slice(); } - public async pushUserTransaction(tx: PendingTransaction): Promise { + public async pushUserTransaction(tx: PendingTransactionJSONType): Promise { const notInQueue = this.queue.find( - (tx2) => tx2.hash().toString() === tx.hash().toString() + (tx2) => tx2.hash === tx.hash ) === undefined; if (notInQueue) { this.queue.push(tx); @@ -76,14 +76,14 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async findTransaction(hash: string): Promise< | { - transaction: PendingTransaction; + transaction: PendingTransactionJSONType; block?: string; batch?: number; } | undefined > { const pending = await this.getPendingUserTransactions(); - const pendingResult = pending.find((tx) => tx.hash().toString() === hash); + const pendingResult = pending.find((tx) => tx.hash === hash); if (pendingResult !== undefined) { return { transaction: pendingResult, @@ -105,7 +105,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { // eslint-disable-next-line no-await-in-loop const batch = await this.findBatch(block.hash); return { - transaction: PendingTransaction.fromJSON(txResult.tx), + transaction: txResult.tx, block: block.transactionsHash, batch, }; diff --git a/packages/sequencer/src/storage/repositories/MessageStorage.ts b/packages/sequencer/src/storage/repositories/MessageStorage.ts index 343e831c8..f137b6c0c 100644 --- a/packages/sequencer/src/storage/repositories/MessageStorage.ts +++ b/packages/sequencer/src/storage/repositories/MessageStorage.ts @@ -1,4 +1,4 @@ -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; /** * Interface to store Messages previously fetched by a IncomingMessageadapter @@ -7,14 +7,14 @@ export interface MessageStorage { pushMessages: ( fromMessagesHash: string, toMessagesHash: string, - messages: PendingTransaction[] + messages: PendingTransactionJSONType[] ) => Promise; getNextMessagesBatch: (fromMessagesHash: string) => Promise< | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; } | undefined >; @@ -26,7 +26,7 @@ export interface MessageStorage { { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }[] >; } diff --git a/packages/sequencer/src/storage/repositories/TransactionStorage.ts b/packages/sequencer/src/storage/repositories/TransactionStorage.ts index ef353ad08..7cf87f1d8 100644 --- a/packages/sequencer/src/storage/repositories/TransactionStorage.ts +++ b/packages/sequencer/src/storage/repositories/TransactionStorage.ts @@ -1,9 +1,9 @@ -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; export interface TransactionStorage { - pushUserTransaction: (tx: PendingTransaction) => Promise; + pushUserTransaction: (tx: PendingTransactionJSONType) => Promise; - getPendingUserTransactions: () => Promise; + getPendingUserTransactions: () => Promise; removeTx: (txHashes: string[], type: "included" | "dropped") => Promise; @@ -16,7 +16,7 @@ export interface TransactionStorage { */ findTransaction: (hash: string) => Promise< | { - transaction: PendingTransaction; + transaction: PendingTransactionJSONType; block?: string; batch?: number; } From 564ba7adbfb9ac1fed181243633acc2bfa9a595f Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 03:46:36 +0300 Subject: [PATCH 22/63] refactor:use non-provable types in execution and tracing services --- .../sequencing/BlockProducerModule.ts | 6 +-- .../sequencing/BlockProductionService.ts | 15 +++--- .../sequencing/TransactionExecutionService.ts | 48 +++++++++++-------- .../messages/IncomingMessageAdapter.ts | 4 +- .../messages/IncomingMessagesService.ts | 8 ++-- .../messages/MinaIncomingMessageAdapter.ts | 8 ++-- 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 2eb876380..38986f3ca 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -14,7 +14,7 @@ import { SequencerModule, } from "../../../sequencer/builder/SequencerModule"; import { BlockQueue } from "../../../storage/repositories/BlockStorage"; -import { PendingTransaction } from "../../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { @@ -177,7 +177,7 @@ export class BlockProducerModule extends SequencerModule { // Idea: Create a service that aggregates a bunch of different sources @trace("block.collect_inputs") private async collectProductionData(): Promise<{ - txs: PendingTransaction[]; + txs: PendingTransactionJSONType[]; metadata: BlockWithResult; }> { const txs = await this.mempool.getTxs(this.maximumBlockSize()); @@ -203,7 +203,7 @@ export class BlockProducerModule extends SequencerModule { }; } - let messages: PendingTransaction[] = []; + let messages: PendingTransactionJSONType[] = []; if (this.messageService !== undefined) { messages = await this.messageService.getPendingMessages(); } diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index a80da5fb9..68483da0f 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -20,11 +20,10 @@ import { match } from "ts-pattern"; import { Block, BlockWithResult, - TransactionExecutionResult, - txResultToJson, + TransactionExecutionResultJson, } from "../../../storage/model/Block"; import { CachedStateService } from "../../../state/state/CachedStateService"; -import { PendingTransaction } from "../../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { Tracer } from "../../../logging/Tracer"; @@ -40,7 +39,7 @@ import { function isIncludedTxs( x: TransactionExecutionResultStatus -): x is { status: "included"; result: TransactionExecutionResult } { +): x is { status: "included"; result: TransactionExecutionResultJson } { return x.status === "included"; } @@ -100,7 +99,7 @@ export class BlockProductionService { */ public async createBlock( asyncStateService: AsyncStateService, - transactions: PendingTransaction[], + transactions: PendingTransactionJSONType[], lastBlockWithResult: BlockWithResult, allowEmptyBlocks: boolean ): Promise< @@ -165,7 +164,7 @@ export class BlockProductionService { .map((x) => x.result); const block: Omit = { - transactions: includedTransactions.map(txResultToJson), + transactions: includedTransactions, transactionsHash: FieldString(newBlockState.transactionList.commitment), fromEternalTransactionsHash: lastBlock.toEternalTransactionsHash, toEternalTransactionsHash: @@ -193,8 +192,8 @@ export class BlockProductionService { const txHash = match(x) .with({ status: "included" }, ({ result }) => result.tx) .otherwise(({ tx }) => tx) - .hash() - .toString(); + .hash; + return { hash: txHash, type: x.status, diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 0e27026d1..afd82765c 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -36,11 +36,13 @@ import { // eslint-disable-next-line import/no-extraneous-dependencies import zip from "lodash/zip"; -import { PendingTransaction } from "../../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { StateTransitionBatch, TransactionExecutionResult, + TransactionExecutionResultJson, + STBatchToJson, } from "../../../storage/model/Block"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { trace } from "../../../logging/trace"; @@ -80,7 +82,7 @@ function getAreProofsEnabledFromModule( } async function decodeTransaction( - tx: PendingTransaction, + tx: PendingTransactionJSONType, runtime: Runtime ): Promise<{ method: SomeRuntimeMethod; @@ -88,13 +90,13 @@ async function decodeTransaction( module: RuntimeModule; }> { const methodDescriptors = runtime.methodIdResolver.getMethodNameFromId( - tx.methodId.toString() + tx.methodId ); - const method = runtime.getMethodById(tx.methodId.toString()); + const method = runtime.getMethodById(tx.methodId); if (methodDescriptors === undefined || method === undefined) { - throw errors.methodIdNotFound(tx.methodId.toString()); + throw errors.methodIdNotFound(tx.methodId); } const [moduleName, methodName] = methodDescriptors; @@ -104,7 +106,7 @@ async function decodeTransaction( module, methodName ); - const args = await parameterDecoder.decode(tx.argsFields, tx.auxiliaryData); + const args = await parameterDecoder.decode(tx.argsFields.map(Field), tx.auxiliaryData); return { method, @@ -199,11 +201,11 @@ function traceLogSTs(msg: string, stateTransitions: StateTransition[]) { export type TransactionExecutionResultStatus = | { - result: TransactionExecutionResult; + result: TransactionExecutionResultJson; status: "included"; } - | { tx: PendingTransaction; status: "skipped" } - | { tx: PendingTransaction; status: "shouldRemove" }; + | { tx: PendingTransactionJSONType; status: "skipped" } + | { tx: PendingTransactionJSONType; status: "shouldRemove" }; @injectable() @scoped(Lifecycle.ContainerScoped) @@ -316,9 +318,9 @@ export class TransactionExecutionService { public addTransactionToBlockProverState( state: BlockTrackers, - tx: PendingTransaction + tx: PendingTransactionJSONType ): BlockTrackers { - const signedTransaction = tx.toProtocolTransaction(); + const signedTransaction = PendingTransaction.fromJSON(tx).toProtocolTransaction(); // Add tx to commitments return this.blockProver.addTransactionToBundle( state, @@ -330,7 +332,7 @@ export class TransactionExecutionService { // eslint-disable-next-line sonarjs/cognitive-complexity public async createExecutionTraces( asyncStateService: CachedStateService, - transactions: PendingTransaction[], + transactions: PendingTransactionJSONType[], networkState: NetworkState, state: BlockTrackers ): Promise<{ @@ -360,7 +362,7 @@ export class TransactionExecutionService { // If the hooks fail AND the tx is not a message (in which case we // have to still execute it), we skip this tx and don't add it to the block if ( - !executionTrace.hooksStatus.toBoolean() && + !executionTrace.hooksStatus && !executionTrace.tx.isMessage ) { const actionMessage = shouldRemove @@ -411,14 +413,14 @@ export class TransactionExecutionService { })) public async createExecutionTrace( asyncStateService: CachedStateService, - tx: PendingTransaction, + tx: PendingTransactionJSONType, { networkState, hash: networkStateHash, }: { networkState: NetworkState; hash: Field }, state: BlockTrackers, newState: BlockTrackers - ): Promise<{ result: TransactionExecutionResult; shouldRemove: boolean }> { + ): Promise<{ result: TransactionExecutionResultJson; shouldRemove: boolean }> { // TODO Use RecordingStateService -> async asProver needed const recordingStateService = new CachedStateService(asyncStateService); @@ -430,7 +432,7 @@ export class TransactionExecutionService { const previousProofsEnabled = appChain.areProofsEnabled; appChain.setProofsEnabled(false); - const signedTransaction = tx.toProtocolTransaction(); + const signedTransaction = PendingTransaction.fromJSON(tx).toProtocolTransaction(); const runtimeContextInputs = { transaction: signedTransaction.transaction, networkState, @@ -490,7 +492,7 @@ export class TransactionExecutionService { status: runtimeResult.status, networkStateHash: networkStateHash, isMessage: Bool(tx.isMessage), - transactionHash: tx.hash(), + transactionHash: Field(tx.hash), eventsHash, stateTransitionsHash, }) @@ -544,15 +546,19 @@ export class TransactionExecutionService { return { result: { tx, - hooksStatus: Bool(txHooksValid), - status: runtimeResult.status, + hooksStatus: txHooksValid, + status: runtimeResult.status.toBoolean(), statusMessage: beforeTxHookResult.statusMessage ?? afterTxHookResult.statusMessage ?? runtimeResult.statusMessage, - stateTransitions, - events: beforeHookEvents.concat(runtimeResultEvents, afterHookEvents), + stateTransitions: stateTransitions.map(STBatchToJson), + events: beforeHookEvents.concat(runtimeResultEvents, afterHookEvents).map(e => ({ + eventName: e.eventName, + data: e.data.map(f => f.toString()), + source: e.source, + })), }, shouldRemove, }; diff --git a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts index dffae431b..f552fdc53 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts @@ -1,6 +1,6 @@ import { PublicKey } from "o1js"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; /** * An interface provided by the BaseLayer via DependencyFactory, @@ -19,6 +19,6 @@ export interface IncomingMessageAdapter { ) => Promise<{ from: string; to: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }>; } diff --git a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts index 509500df3..af3aa0620 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts @@ -4,7 +4,7 @@ import { ACTIONS_EMPTY_HASH } from "@proto-kit/protocol"; import { SettlementStorage } from "../../storage/repositories/SettlementStorage"; import { MessageStorage } from "../../storage/repositories/MessageStorage"; import { BlockStorage } from "../../storage/repositories/BlockStorage"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import type { SettlementModule } from "../SettlementModule"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; @@ -53,7 +53,7 @@ export class IncomingMessagesService { private isComplete( messages: - | { toMessagesHash: string; messages: PendingTransaction[] } + | { toMessagesHash: string; messages: PendingTransactionJSONType[] } | undefined, targetMessagesHash: string ) { @@ -64,7 +64,7 @@ export class IncomingMessagesService { private async ensureMessageCompleteness( messages: - | { toMessagesHash: string; messages: PendingTransaction[] } + | { toMessagesHash: string; messages: PendingTransactionJSONType[] } | undefined, fromMessagesHash: string, targetMessagesHash: string @@ -90,7 +90,7 @@ export class IncomingMessagesService { batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }[] ) { return { diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 44eb99a6e..43c724830 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -24,7 +24,7 @@ import { SettlementContractModule, } from "@proto-kit/protocol"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; @@ -67,7 +67,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { private async mapActionToTransactions( tx: RuntimeTransaction, fieldArgs: Field[] - ): Promise { + ): Promise { const { methodId } = tx; const methodPointer = this.runtime.methodIdResolver.getMethodNameFromId( @@ -96,7 +96,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { argsFields: fields, auxiliaryData: auxiliary, isMessage: true, - }); + }).toJSON(); } public async fetchPendingMessages( @@ -109,7 +109,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { ): Promise<{ from: string; to: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }> { const { network } = this.baseLayer; if (network === undefined) { From 6905b36a0ad8f94d71cef78964be45a3d224dc84 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 03:48:50 +0300 Subject: [PATCH 23/63] refactor: update Prisma interactions to use non-provable types --- .../persistance/src/services/prisma/PrismaBlockStorage.ts | 8 ++++---- .../src/services/prisma/PrismaMessageStorage.ts | 8 ++++---- .../src/services/prisma/PrismaTransactionStorage.ts | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 21cfee7b5..7fe7b3d4f 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -1,5 +1,5 @@ import { - TransactionExecutionResult, + TransactionExecutionResultJson, Block, BlockResult, BlockQueue, @@ -53,7 +53,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { if (dbResult === null) { return undefined; } - const transactions = dbResult.transactions.map( + const transactions = dbResult.transactions.map( (txresult) => this.transactionResultMapper.mapIn([txresult, txresult.tx]) ); @@ -80,7 +80,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { public async pushBlock(block: Block): Promise { log.trace( "Pushing block to DB. Txs:", - block.transactions.map((x) => x.tx.hash().toString()) + block.transactions.map((x) => x.tx.hash) ); const transactions = block.transactions.map( @@ -221,7 +221,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { }); return blocks.map((block, index) => { - const transactions = block.transactions.map( + const transactions = block.transactions.map( (txresult) => { return this.transactionResultMapper.mapIn([txresult, txresult.tx]); } diff --git a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts index c1b113bb7..65dbb6bc4 100644 --- a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts @@ -1,4 +1,4 @@ -import { MessageStorage, PendingTransaction } from "@proto-kit/sequencer"; +import { MessageStorage, PendingTransactionJSONType } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; import type { PrismaConnection } from "../../PrismaDatabaseConnection"; @@ -21,7 +21,7 @@ export class PrismaMessageStorage implements MessageStorage { const batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }[] = []; let currentHash = fromMessagesHash; @@ -43,7 +43,7 @@ export class PrismaMessageStorage implements MessageStorage { | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; } | undefined > { @@ -84,7 +84,7 @@ export class PrismaMessageStorage implements MessageStorage { public async pushMessages( fromMessageHash: string, toMessageHash: string, - messages: PendingTransaction[] + messages: PendingTransactionJSONType[] ): Promise { const transactions = messages.map((message) => this.transactionMapper.mapOut(message) diff --git a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts index d4544a7c4..05dbcce15 100644 --- a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts @@ -1,6 +1,7 @@ import { inject, injectable } from "tsyringe"; import { PendingTransaction, + PendingTransactionJSONType, trace, Tracer, TransactionStorage, @@ -19,7 +20,7 @@ export class PrismaTransactionStorage implements TransactionStorage { ) {} @trace("db.txs.get") - public async getPendingUserTransactions(): Promise { + public async getPendingUserTransactions(): Promise { const { prismaClient } = this.connection; const txs = await prismaClient.transaction.findMany({ @@ -51,7 +52,7 @@ export class PrismaTransactionStorage implements TransactionStorage { } } - public async pushUserTransaction(tx: PendingTransaction): Promise { + public async pushUserTransaction(tx: PendingTransactionJSONType): Promise { const { prismaClient } = this.connection; const result = await prismaClient.transaction.createMany({ @@ -64,7 +65,7 @@ export class PrismaTransactionStorage implements TransactionStorage { public async findTransaction(hash: string): Promise< | { - transaction: PendingTransaction; + transaction: PendingTransactionJSONType; block?: string; batch?: number; } From fb4c8549f9b6744422d84452b49d4eef27dc81ae Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 03:50:21 +0300 Subject: [PATCH 24/63] refactor: use non-provable types in object mappers --- .../prisma/mappers/BlockResultMapper.ts | 10 +--- .../services/prisma/mappers/EventMapper.ts | 24 ++++---- .../prisma/mappers/StateTransitionMapper.ts | 29 +++++----- .../prisma/mappers/TransactionMapper.ts | 55 ++++++++++--------- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts index 2a9ea3852..1c31c974b 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts @@ -1,6 +1,6 @@ import { singleton } from "tsyringe"; import { BlockResult, UntypedStateTransition } from "@proto-kit/sequencer"; -import { BlockResult as DBBlockResult } from "@prisma/client"; +import { BlockResult as DBBlockResult, Prisma } from "@prisma/client"; import { BlockHashMerkleTreeWitnessJson, NetworkStateJson, @@ -29,7 +29,7 @@ export class BlockResultMapper afterBlockStateTransitions: this.stArrayMapper .mapIn(input.afterBlockStateTransitions) - .map((st) => st.toJSON()), + .map((st) => st), blockHash: input.blockHash, witnessedRoots: [input.witnessedRoots[0]], @@ -43,11 +43,7 @@ export class BlockResultMapper blockHashRoot: input.blockHashRoot.toString(), blockHashWitness: input.blockHashWitness, - afterBlockStateTransitions: this.stArrayMapper.mapOut( - input.afterBlockStateTransitions.map((st) => - UntypedStateTransition.fromJSON(st) - ) - ), + afterBlockStateTransitions: input.afterBlockStateTransitions as unknown as Prisma.JsonArray, afterNetworkState: input.afterNetworkState, witnessedRoots: [input.witnessedRoots[0].toString()], diff --git a/packages/persistance/src/services/prisma/mappers/EventMapper.ts b/packages/persistance/src/services/prisma/mappers/EventMapper.ts index b56416a87..6f329c4b7 100644 --- a/packages/persistance/src/services/prisma/mappers/EventMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/EventMapper.ts @@ -1,31 +1,28 @@ import { singleton } from "tsyringe"; import { Prisma } from "@prisma/client"; -import { Field } from "o1js"; import { ObjectMapper } from "../../../ObjectMapper"; -type EventData = { +type EventDataJson = { eventName: string; - data: Field[]; + data: string[]; source: "afterTxHook" | "beforeTxHook" | "runtime"; }; @singleton() -export class EventMapper implements ObjectMapper { - public mapIn(input: Prisma.JsonObject): EventData { +export class EventMapper implements ObjectMapper { + public mapIn(input: Prisma.JsonObject): EventDataJson { return { eventName: input.eventName as string, - data: (input.data as Prisma.JsonArray).map((field) => - Field.fromJSON(field as string) - ), + data: input.data as string[], source: this.sourceConvert(input.source as string), }; } - public mapOut(input: EventData): Prisma.JsonObject { + public mapOut(input: EventDataJson): Prisma.JsonObject { return { eventName: input.eventName, - data: input.data.map((field) => field.toString()), + data: input.data, source: input.source, } as Prisma.JsonObject; } @@ -46,11 +43,11 @@ export class EventMapper implements ObjectMapper { @singleton() export class EventArrayMapper - implements ObjectMapper + implements ObjectMapper { public constructor(private readonly eventMapper: EventMapper) {} - public mapIn(input: Prisma.JsonValue | undefined): EventData[] { + public mapIn(input: Prisma.JsonValue | undefined): EventDataJson[] { if (input === undefined) return []; if (Array.isArray(input)) { @@ -61,9 +58,10 @@ export class EventArrayMapper return []; } - public mapOut(input: EventData[]): Prisma.JsonValue { + public mapOut(input: EventDataJson[]): Prisma.JsonValue { return input.map((event) => this.eventMapper.mapOut(event) ) as Prisma.JsonArray; } } + diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index ed35da7b3..2dc05947b 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -1,7 +1,7 @@ import { singleton } from "tsyringe"; import { - StateTransitionBatch, - UntypedStateTransition, + StateTransitionBatchJson, + UntypedStateTransitionJson, } from "@proto-kit/sequencer"; import { Prisma } from "@prisma/client"; @@ -9,26 +9,27 @@ import { ObjectMapper } from "../../../ObjectMapper"; @singleton() export class StateTransitionMapper - implements ObjectMapper + implements ObjectMapper { - public mapIn(input: Prisma.JsonObject): UntypedStateTransition { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - return UntypedStateTransition.fromJSON(input as any); + public mapIn(input: Prisma.JsonObject): UntypedStateTransitionJson { + // + return input as unknown as UntypedStateTransitionJson; } - public mapOut(input: UntypedStateTransition): Prisma.JsonObject { - return input.toJSON(); + public mapOut(input: UntypedStateTransitionJson): Prisma.JsonObject { + // Already JSON-compatible, just cast + return input as unknown as Prisma.JsonObject; } } @singleton() export class StateTransitionArrayMapper implements - ObjectMapper + ObjectMapper { public constructor(private readonly stMapper: StateTransitionMapper) {} - public mapIn(input: Prisma.JsonValue | undefined): UntypedStateTransition[] { + public mapIn(input: Prisma.JsonValue | undefined): UntypedStateTransitionJson[] { if (input === undefined) return []; if (Array.isArray(input)) { @@ -39,20 +40,20 @@ export class StateTransitionArrayMapper return []; } - public mapOut(input: UntypedStateTransition[]): Prisma.JsonValue { + public mapOut(input: UntypedStateTransitionJson[]): Prisma.JsonValue { return input.map((st) => this.stMapper.mapOut(st)) as Prisma.JsonArray; } } @singleton() export class StateTransitionBatchArrayMapper - implements ObjectMapper + implements ObjectMapper { public constructor( private readonly stArrayMapper: StateTransitionArrayMapper ) {} - public mapOut(input: StateTransitionBatch[]): Prisma.JsonValue { + public mapOut(input: StateTransitionBatchJson[]): Prisma.JsonValue { return input.map((st) => ({ stateTransitions: this.stArrayMapper.mapOut( st.stateTransitions @@ -61,7 +62,7 @@ export class StateTransitionBatchArrayMapper })); } - public mapIn(input: Prisma.JsonValue): StateTransitionBatch[] { + public mapIn(input: Prisma.JsonValue): StateTransitionBatchJson[] { if (input === undefined) return []; if (Array.isArray(input)) { diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index e999e9bc2..b234cc7a3 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -1,13 +1,13 @@ import { singleton, injectable } from "tsyringe"; import { PendingTransaction, - TransactionExecutionResult, + TransactionExecutionResultJson, + PendingTransactionJSONType, } from "@proto-kit/sequencer"; import { Transaction as DBTransaction, TransactionExecutionResult as DBTransactionExecutionResult, } from "@prisma/client"; -import { Bool } from "o1js"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -17,30 +17,35 @@ import { EventArrayMapper } from "./EventMapper"; @singleton() @injectable() export class TransactionMapper - implements ObjectMapper + implements ObjectMapper { - public mapIn(input: DBTransaction): PendingTransaction { - return PendingTransaction.fromJSON({ - ...input, + public mapIn(input: DBTransaction): PendingTransactionJSONType { + return { + hash: input.hash, + methodId: input.methodId, + nonce: input.nonce, + sender: input.sender, + argsFields: input.argsFields, + auxiliaryData: input.auxiliaryData, + isMessage: input.isMessage, signature: { r: input.signature_r, s: input.signature_s, }, - }); + }; } - public mapOut(input: PendingTransaction): DBTransaction { - const json = input.toJSON(); + public mapOut(input: PendingTransactionJSONType): DBTransaction { return { - methodId: json.methodId, - nonce: json.nonce, - sender: json.sender, - argsFields: json.argsFields, - auxiliaryData: json.auxiliaryData, - isMessage: json.isMessage, - signature_r: json.signature.r, - signature_s: json.signature.s, - hash: input.hash().toString(), + hash: input.hash, + methodId: input.methodId, + nonce: input.nonce, + sender: input.sender, + argsFields: input.argsFields, + auxiliaryData: input.auxiliaryData, + isMessage: input.isMessage, + signature_r: input.signature.r, + signature_s: input.signature.s, }; } } @@ -49,7 +54,7 @@ export class TransactionMapper export class TransactionExecutionResultMapper implements ObjectMapper< - TransactionExecutionResult, + TransactionExecutionResultJson, [Omit, DBTransaction] > { @@ -61,12 +66,12 @@ export class TransactionExecutionResultMapper public mapIn( input: [Omit, DBTransaction] - ): TransactionExecutionResult { + ): TransactionExecutionResultJson { const executionResult = input[0]; return { tx: this.transactionMapper.mapIn(input[1]), - status: Bool(executionResult.status), - hooksStatus: Bool(executionResult.hooksStatus), + status: executionResult.status, + hooksStatus: executionResult.hooksStatus, statusMessage: executionResult.statusMessage ?? undefined, stateTransitions: this.stBatchMapper.mapIn( executionResult.stateTransitions @@ -76,12 +81,12 @@ export class TransactionExecutionResultMapper } mapOut( - input: TransactionExecutionResult + input: TransactionExecutionResultJson ): [Omit, DBTransaction] { const tx = this.transactionMapper.mapOut(input.tx); const executionResult = { - status: input.status.toBoolean(), - hooksStatus: input.hooksStatus.toBoolean(), + status: input.status, + hooksStatus: input.hooksStatus, statusMessage: input.statusMessage ?? null, stateTransitions: this.stBatchMapper.mapOut(input.stateTransitions), events: this.eventArrayMapper.mapOut(input.events), From d5b6d7b417f7183f6e02d41edaa2b38988d26b97 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 04:09:03 +0300 Subject: [PATCH 25/63] refactor: update PendingTransaction related code PendingTransactionJson to --- .../api/src/graphql/modules/MempoolResolver.ts | 6 +++--- .../sdk/src/graphql/GraphqlTransactionSender.ts | 6 +++--- .../sdk/src/transaction/AppChainTransaction.ts | 3 ++- .../src/transaction/InMemoryTransactionSender.ts | 5 +++-- .../mempool/verification/TransactionValidator.ts | 16 +++++++++------- .../src/protocol/baselayer/NoopBaseLayer.ts | 4 ++-- packages/sequencer/test/integration/utils.ts | 5 +++-- packages/sequencer/test/settlement/Settlement.ts | 5 +++-- 8 files changed, 28 insertions(+), 22 deletions(-) diff --git a/packages/api/src/graphql/modules/MempoolResolver.ts b/packages/api/src/graphql/modules/MempoolResolver.ts index 034eee651..17b871af0 100644 --- a/packages/api/src/graphql/modules/MempoolResolver.ts +++ b/packages/api/src/graphql/modules/MempoolResolver.ts @@ -125,10 +125,10 @@ export class MempoolResolver extends GraphqlModule { description: "Adds a transaction to the mempool and validates it", }) public async submitTx(@Arg("tx") tx: TransactionObject): Promise { - const decoded = PendingTransaction.fromJSON(tx); + const decoded = PendingTransaction.fromJSON(tx).toJSON(); await this.mempool.add(decoded); - return decoded.hash().toString(); + return decoded.hash; } // TODO Add retrieval of pending messages somewhere as well @@ -162,6 +162,6 @@ export class MempoolResolver extends GraphqlModule { }) public async transactions() { const txs = await this.transactionStorage.getPendingUserTransactions(); - return txs.map((x) => x.hash().toString()); + return txs.map((x) => x.hash); } } diff --git a/packages/sdk/src/graphql/GraphqlTransactionSender.ts b/packages/sdk/src/graphql/GraphqlTransactionSender.ts index 6bf97b774..6345816d2 100644 --- a/packages/sdk/src/graphql/GraphqlTransactionSender.ts +++ b/packages/sdk/src/graphql/GraphqlTransactionSender.ts @@ -1,5 +1,5 @@ import { inject, injectable } from "tsyringe"; -import { PendingTransaction, AppChainModule } from "@proto-kit/sequencer"; +import { PendingTransaction, AppChainModule, PendingTransactionJSONType } from "@proto-kit/sequencer"; import { gql } from "@urql/core"; import { TransactionSender } from "../transaction/InMemoryTransactionSender"; @@ -17,13 +17,13 @@ export class GraphqlTransactionSender super(); } - public async send(transaction: PendingTransaction): Promise { + public async send(transaction: PendingTransactionJSONType): Promise { const query = gql` mutation SubmitTx($tx: TransactionObjectInput!) { submitTx(tx: $tx) } `; - const tx = transaction.toJSON(); + const tx = transaction; const queryResult = await this.graphqlClient.client .mutation(query, { tx }) diff --git a/packages/sdk/src/transaction/AppChainTransaction.ts b/packages/sdk/src/transaction/AppChainTransaction.ts index 496772e17..1d9f30d08 100644 --- a/packages/sdk/src/transaction/AppChainTransaction.ts +++ b/packages/sdk/src/transaction/AppChainTransaction.ts @@ -47,6 +47,7 @@ export class AppChainTransaction { public async send() { this.hasPendingTransaction(this.transaction); - await this.transactionSender.send(this.transaction); + // Wait for next commit + await this.transactionSender.send(this.transaction.toJSON()); } } diff --git a/packages/sdk/src/transaction/InMemoryTransactionSender.ts b/packages/sdk/src/transaction/InMemoryTransactionSender.ts index b3bb74981..7e77dbf24 100644 --- a/packages/sdk/src/transaction/InMemoryTransactionSender.ts +++ b/packages/sdk/src/transaction/InMemoryTransactionSender.ts @@ -2,12 +2,13 @@ import { PrivateMempool, PendingTransaction, AppChainModule, + PendingTransactionJSONType, } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; import { ModuleContainerLike } from "@proto-kit/common"; export interface TransactionSender extends AppChainModule { - send: (transaction: PendingTransaction) => Promise; + send: (transaction: PendingTransactionJSONType) => Promise; } @injectable() @@ -25,7 +26,7 @@ export class InMemoryTransactionSender this.mempool = this.sequencer.resolveOrFail("Mempool", PrivateMempool); } - public async send(transaction: PendingTransaction) { + public async send(transaction: PendingTransactionJSONType) { await this.mempool.add(transaction); } } diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index c6827a287..29aa2e2de 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -5,7 +5,7 @@ import { RuntimeModulesRecord, } from "@proto-kit/module"; -import { PendingTransaction } from "../PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../PendingTransaction"; @injectable() export class TransactionValidator { @@ -13,14 +13,14 @@ export class TransactionValidator { @inject("Runtime") private readonly runtime: Runtime ) {} - private validateMethod(tx: PendingTransaction): string | undefined { + private validateMethod(tx: PendingTransactionJSONType): string | undefined { // Check if method exists // We don't actually need to use runtime.getMethodById here, bcs the // module name validation happens inside getMethodNameFromId // and also in the next step const methodPath = this.runtime.methodIdResolver.getMethodNameFromId( - tx.methodId.toString() + tx.methodId ); if (methodPath === undefined) { @@ -38,16 +38,18 @@ export class TransactionValidator { return undefined; } - public validateTx(tx: PendingTransaction): [boolean, string | undefined] { + public validateTx(tx: PendingTransactionJSONType): [boolean, string | undefined] { const methodError = this.validateMethod(tx); if (methodError !== undefined) { return [false, methodError]; } - const validSignature = tx.signature.verify( - tx.sender, - tx.getSignatureData() + const transaction = PendingTransaction.fromJSON(tx); + + const validSignature = transaction.signature.verify( + transaction.sender, + transaction.getSignatureData() ); if (!validSignature.toBoolean()) { diff --git a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts index 9e64f6996..509641a2f 100644 --- a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts +++ b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts @@ -7,7 +7,7 @@ import { sequencerModule, } from "../../sequencer/builder/SequencerModule"; import { IncomingMessageAdapter } from "../../settlement/messages/IncomingMessageAdapter"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { OutgoingMessageAdapter } from "../../settlement/messages/outgoing/OutgoingMessageCollector"; import { Block } from "../../storage/model/Block"; @@ -23,7 +23,7 @@ class NoopIncomingMessageAdapter implements IncomingMessageAdapter { ): Promise<{ from: string; to: string; - messages: PendingTransaction[]; + messages: PendingTransactionJSONType[]; }> { return { from: "0", diff --git a/packages/sequencer/test/integration/utils.ts b/packages/sequencer/test/integration/utils.ts index f863cf605..ff29d11f0 100644 --- a/packages/sequencer/test/integration/utils.ts +++ b/packages/sequencer/test/integration/utils.ts @@ -7,6 +7,7 @@ import { } from "@proto-kit/module"; import { + PendingTransactionJSONType, StateRecord, UnsignedTransaction, UntypedStateTransition, @@ -18,7 +19,7 @@ export function createTransaction(spec: { method: [string, string]; args: ArgumentTypes; nonce: number; -}) { +}): PendingTransactionJSONType { const methodId = spec.runtime.dependencyContainer .resolve("MethodIdResolver") .getMethodId(spec.method[0], spec.method[1]); @@ -37,7 +38,7 @@ export function createTransaction(spec: { sender: spec.privateKey.toPublicKey(), nonce: UInt64.from(spec.nonce), isMessage: false, - }).sign(spec.privateKey); + }).sign(spec.privateKey).toJSON(); } export function collectStateDiff( diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index a40b25ac9..6ad58436e 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -56,6 +56,7 @@ import { VanillaTaskWorkerModules, Sequencer, InMemoryMinaSigner, + PendingTransactionJSONType, } from "../../src"; import { BlockProofSerializer } from "../../src/protocol/production/tasks/serializers/BlockProofSerializer"; import { testingSequencerModules } from "../TestingSequencer"; @@ -227,7 +228,7 @@ export const settlementTestFn = ( async function createBatch( withTransactions: boolean, customNonce: number = 0, - txs: PendingTransaction[] = [] + txs: PendingTransactionJSONType[] = [] ) { const mempool = appChain.sequencer.resolve("Mempool") as PrivateMempool; if (withTransactions) { @@ -683,7 +684,7 @@ export const settlementTestFn = ( acc0L2Nonce += 2; expectDefined(block); - expect(block.transactions[0].status.toBoolean()).toBe(true); + expect(block.transactions[0].status).toBe(true); expectDefined(batch); console.log("Test networkstate"); From 57ad69dd881d4ed07a8a0d1a07906fb70bdfdff6 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 04:56:27 +0300 Subject: [PATCH 26/63] refactor(test): update with changes in codebase --- .../PrismaBlockProduction.test.ts | 8 +- .../processor/test/HandlersExecutor.test.ts | 4 +- packages/sdk/test/TestingAppChain.test.ts | 2 +- .../sdk/test/blockProof/blockProof.test.ts | 2 +- .../sdk/test/fee-hook-sts-regression.test.ts | 2 +- .../test/networkstate/NetworkState.test.ts | 8 +- packages/sdk/test/parameters.test.ts | 2 +- .../test/integration/BlockProduction-test.ts | 26 ++--- .../test/integration/Mempool.test.ts | 98 +++++++++---------- .../sequencer/test/integration/Proven.test.ts | 2 +- .../integration/StorageIntegration.test.ts | 13 ++- .../sequencer/test/settlement/Settlement.ts | 1 - packages/stack/test/graphql/graphql.test.ts | 2 +- 13 files changed, 84 insertions(+), 86 deletions(-) diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index 7db92d22a..a3beb6c0f 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -97,8 +97,8 @@ describe("prisma integration", () => { // Check that transactions match expect(retrievedBlock.transactions).toHaveLength(1); - expect(retrievedBlock.transactions[0].tx.hash().toString()).toStrictEqual( - block.transactions[0].tx.hash().toString() + expect(retrievedBlock.transactions[0].tx.hash).toStrictEqual( + block.transactions[0].tx.hash ); expect(retrievedBlock.hash).toStrictEqual( @@ -228,7 +228,7 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); expect(txs).toHaveLength(1); - expect(txs[0].hash().toString()).toStrictEqual( + expect(txs[0].hash).toStrictEqual( transaction.transaction.hash().toString() ); }); @@ -244,7 +244,7 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); expect(txs).toHaveLength(1); - expect(txs[0].hash().toString()).toStrictEqual( + expect(txs[0].hash).toStrictEqual( transaction.transaction.hash().toString() ); }); diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index 32623fb7f..88438fad2 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -6,7 +6,7 @@ import { import { TestingAppChain } from "@proto-kit/sdk"; import { Balance, Balances, TokenId } from "@proto-kit/library"; import { MethodParameterEncoder } from "@proto-kit/module"; -import { PrivateKey, PublicKey } from "o1js"; +import { Field, PrivateKey, PublicKey } from "o1js"; import { mockDeep } from "jest-mock-extended"; import { container } from "tsyringe"; @@ -66,7 +66,7 @@ describe("HandlersModule", () => { // @ts-expect-error const [, from, to, amount]: [TokenId, PublicKey, PublicKey, Balance] = await parameterDecoder.decode( - tx.tx.argsFields, + tx.tx.argsFields.map(Field), tx.tx.auxiliaryData ); diff --git a/packages/sdk/test/TestingAppChain.test.ts b/packages/sdk/test/TestingAppChain.test.ts index f07a6c21c..2f67764a5 100644 --- a/packages/sdk/test/TestingAppChain.test.ts +++ b/packages/sdk/test/TestingAppChain.test.ts @@ -147,7 +147,7 @@ describe("testing app chain", () => { Provable.log("block", block); - expect(block?.transactions[0].status.toBoolean()).toBe(true); + expect(block?.transactions[0].status).toBe(true); /** * Observe new state after the block has been produced diff --git a/packages/sdk/test/blockProof/blockProof.test.ts b/packages/sdk/test/blockProof/blockProof.test.ts index f2c81ad29..0819ef3cb 100644 --- a/packages/sdk/test/blockProof/blockProof.test.ts +++ b/packages/sdk/test/blockProof/blockProof.test.ts @@ -138,7 +138,7 @@ describe.skip("blockProof", () => { }) ); - expect(block?.transactions[0].status.toBoolean()).toBe(true); + expect(block?.transactions[0].status).toBe(true); expect(aliceBalance?.toBigInt()).toBe(1000n); }, 120_000); }); diff --git a/packages/sdk/test/fee-hook-sts-regression.test.ts b/packages/sdk/test/fee-hook-sts-regression.test.ts index 69a47d39d..9c0a837ea 100644 --- a/packages/sdk/test/fee-hook-sts-regression.test.ts +++ b/packages/sdk/test/fee-hook-sts-regression.test.ts @@ -167,7 +167,7 @@ describe("testing app chain", () => { console.log("block2", block2); - expect(block2?.transactions[0].status.toBoolean()).toBe(true); + expect(block2?.transactions[0].status).toBe(true); /** * Observe new state after the block has been produced diff --git a/packages/sdk/test/networkstate/NetworkState.test.ts b/packages/sdk/test/networkstate/NetworkState.test.ts index f2b812a6e..428dba6ab 100644 --- a/packages/sdk/test/networkstate/NetworkState.test.ts +++ b/packages/sdk/test/networkstate/NetworkState.test.ts @@ -121,7 +121,7 @@ describe.skip("block production", () => { expectDefined(block2); expect(block2.transactions).toHaveLength(1); - expect(block2!.transactions[0].status.toBoolean()).toBe(true); + expect(block2!.transactions[0].status).toBe(true); }, 60000); it("should produce a valid block", async () => { @@ -138,7 +138,7 @@ describe.skip("block production", () => { await tx.send(); const [block, batch] = await blockTrigger.produceBlockAndBatch(); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expectDefined(batch); const publicOutput = BlockProverPublicOutput.fromFields( @@ -155,7 +155,7 @@ describe.skip("block production", () => { await tx2.send(); const [block2, batch2] = await blockTrigger.produceBlockAndBatch(); - expect(block2!.transactions[0].status.toBoolean()).toBe(true); + expect(block2!.transactions[0].status).toBe(true); expectDefined(batch2); const publicOutput2 = BlockProverPublicOutput.fromFields( @@ -172,6 +172,6 @@ describe.skip("block production", () => { await tx3.send(); const [block3] = await blockTrigger.produceBlockAndBatch(); - expect(block3!.transactions[0].status.toBoolean()).toBe(false); + expect(block3!.transactions[0].status).toBe(false); }, 60_000); }); diff --git a/packages/sdk/test/parameters.test.ts b/packages/sdk/test/parameters.test.ts index 9212d8420..938999caf 100644 --- a/packages/sdk/test/parameters.test.ts +++ b/packages/sdk/test/parameters.test.ts @@ -146,6 +146,6 @@ describe("parameters", () => { const block = await appChain.produceBlock(); expectDefined(block); - expect(block.transactions[0].status.toBoolean()).toBe(true); + expect(block.transactions[0].status).toBe(true); }, 60_000); }); diff --git a/packages/sequencer/test/integration/BlockProduction-test.ts b/packages/sequencer/test/integration/BlockProduction-test.ts index 6bd8adf63..4ac501375 100644 --- a/packages/sequencer/test/integration/BlockProduction-test.ts +++ b/packages/sequencer/test/integration/BlockProduction-test.ts @@ -211,7 +211,7 @@ export function testBlockProduction< expect(block).toBeDefined(); expect(block!.transactions).toHaveLength(1); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expect(block!.transactions[0].statusMessage).toBeUndefined(); expect(block!.transactions[0].stateTransitions).toHaveLength(3); @@ -289,7 +289,7 @@ export function testBlockProduction< expect(block).toBeDefined(); expect(block!.transactions).toHaveLength(1); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expect(block!.transactions[0].statusMessage).toBeUndefined(); expect(batch!.blockHashes).toHaveLength(1); @@ -319,7 +319,7 @@ export function testBlockProduction< const [block] = await test.produceBlockAndBatch(); expect(block?.transactions).toHaveLength(1); - expect(block?.transactions[0].status.toBoolean()).toBe(false); + expect(block?.transactions[0].status).toBe(false); expect(block?.transactions[0].statusMessage).toBe("Condition not met"); const balanceModule = runtime.resolve("Balance"); @@ -359,7 +359,7 @@ export function testBlockProduction< expect(block).toBeDefined(); expect(block!.transactions).toHaveLength(1); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expect(block!.transactions[0].statusMessage).toBeUndefined(); expect( @@ -415,7 +415,7 @@ export function testBlockProduction< expect(block2).toBeDefined(); expect(block2!.transactions).toHaveLength(1); - expect(block2!.transactions[0].status.toBoolean()).toBe(true); + expect(block2!.transactions[0].status).toBe(true); expect(block2!.transactions[0].statusMessage).toBeUndefined(); await expect( @@ -449,17 +449,17 @@ export function testBlockProduction< expect(block!.transactions).toHaveLength(numberTxs); range(0, numberTxs).forEach((index) => { - expect(block!.transactions[index].status.toBoolean()).toBe(true); + expect(block!.transactions[index].status).toBe(true); expect(block!.transactions[index].statusMessage).toBe(undefined); const transitions = block!.transactions[index].stateTransitions[1].stateTransitions; const fromBalance = increment * index; - expect(transitions[0].fromValue.value[0].toBigInt()).toStrictEqual( + expect(BigInt(transitions[0].from.value[0])).toStrictEqual( BigInt(fromBalance) ); - expect(transitions[0].toValue.value[0].toBigInt()).toStrictEqual( + expect(BigInt(transitions[0].to.value[0])).toStrictEqual( BigInt(fromBalance + increment) ); }); @@ -591,7 +591,7 @@ export function testBlockProduction< for (let k = 0; k < txsPerBlock; k++) { expect(block!.transactions).toHaveLength(txsPerBlock); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); } } @@ -624,7 +624,7 @@ export function testBlockProduction< expect(block!.transactions).toHaveLength(1); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expect(block!.transactions[0].statusMessage).toBe(undefined); expect(batch!.blockHashes).toHaveLength(1); @@ -671,7 +671,7 @@ export function testBlockProduction< expect(block).toBeDefined(); expect(block!.transactions).toHaveLength(1); - expect(block!.transactions[0].status.toBoolean()).toBe(true); + expect(block!.transactions[0].status).toBe(true); expect(block!.transactions[0].statusMessage).toBeUndefined(); expect( @@ -717,13 +717,13 @@ export function testBlockProduction< }; const firstEventReduced = { eventName: firstExpectedEvent.eventName, - data: firstExpectedEvent.eventType.toFields(firstExpectedEvent.event), + data: firstExpectedEvent.eventType.toFields(firstExpectedEvent.event).map(f => f.toString()), source: "runtime", }; const secondEventReduced = { eventName: secondExpectedEvent.eventName, - data: secondExpectedEvent.eventType.toFields(secondExpectedEvent.event), + data: secondExpectedEvent.eventType.toFields(secondExpectedEvent.event).map(f => f.toString()), source: "runtime", }; diff --git a/packages/sequencer/test/integration/Mempool.test.ts b/packages/sequencer/test/integration/Mempool.test.ts index 2609ef78f..89faa7f2a 100644 --- a/packages/sequencer/test/integration/Mempool.test.ts +++ b/packages/sequencer/test/integration/Mempool.test.ts @@ -143,18 +143,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[0].sender).toStrictEqual(user1PublicKey); - expect(txs[1].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[1].sender).toStrictEqual(user2PublicKey); - expect(txs[2].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[2].sender).toStrictEqual(user3PublicKey); - expect(txs[3].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[3].sender).toStrictEqual(user1PublicKey); - expect(txs[4].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[4].sender).toStrictEqual(user2PublicKey); - expect(txs[5].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[5].sender).toStrictEqual(user3PublicKey); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - medium", async () => { @@ -172,18 +172,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[0].sender).toStrictEqual(user1PublicKey); - expect(txs[1].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[1].sender).toStrictEqual(user2PublicKey); - expect(txs[2].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[2].sender).toStrictEqual(user1PublicKey); - expect(txs[3].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[3].sender).toStrictEqual(user2PublicKey); - expect(txs[4].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[4].sender).toStrictEqual(user3PublicKey); - expect(txs[5].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[5].sender).toStrictEqual(user3PublicKey); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("1"); + expect(txs[2].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("0"); + expect(txs[4].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - harder", async () => { @@ -199,18 +199,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[0].sender).toStrictEqual(user1PublicKey); - expect(txs[1].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[1].sender).toStrictEqual(user2PublicKey); - expect(txs[2].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[2].sender).toStrictEqual(user3PublicKey); - expect(txs[3].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[3].sender).toStrictEqual(user1PublicKey); - expect(txs[4].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[4].sender).toStrictEqual(user2PublicKey); - expect(txs[5].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[5].sender).toStrictEqual(user3PublicKey); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - hardest", async () => { @@ -228,18 +228,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[0].sender).toStrictEqual(user1PublicKey); - expect(txs[1].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[1].sender).toStrictEqual(user2PublicKey); - expect(txs[2].nonce.toBigInt()).toStrictEqual(0n); - expect(txs[2].sender).toStrictEqual(user3PublicKey); - expect(txs[3].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[3].sender).toStrictEqual(user1PublicKey); - expect(txs[4].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[4].sender).toStrictEqual(user2PublicKey); - expect(txs[5].nonce.toBigInt()).toStrictEqual(1n); - expect(txs[5].sender).toStrictEqual(user3PublicKey); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); } -); +); \ No newline at end of file diff --git a/packages/sequencer/test/integration/Proven.test.ts b/packages/sequencer/test/integration/Proven.test.ts index 6de1a5517..01b7249f0 100644 --- a/packages/sequencer/test/integration/Proven.test.ts +++ b/packages/sequencer/test/integration/Proven.test.ts @@ -210,7 +210,7 @@ describe.skip("Proven", () => { expectDefined(block); expect(block.transactions).toHaveLength(1); - expect(block.transactions[0].status.toBoolean()).toBe(true); + expect(block.transactions[0].status).toBe(true); expectDefined(batch); diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index fd182ae2f..6f1563856 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -18,6 +18,7 @@ import { BlockStorage, VanillaTaskWorkerModules, AppChain, + UntypedStateTransition, } from "../../src"; import { DefaultTestingSequencerModules, @@ -36,7 +37,7 @@ function checkStateDiffEquality(stateDiff: StateRecord, state: StateEntry[]) { return value === undefined; } if (value !== undefined) { - return entry.value.find((v, i) => v !== value[i]) === undefined; + return entry.value.find((v, i) => !v.equals(value[i]).toBoolean()) === undefined; } } return false; @@ -161,12 +162,10 @@ describe.each([["InMemory", InMemoryDatabase]])( expect(block2.hash).toStrictEqual( generatedBlock.hash ); - - const stateDiff = collectStateDiff( - block.transactions.flatMap((tx) => - tx.stateTransitions.flatMap((batch) => batch.stateTransitions) + const input = block.transactions.flatMap((tx) => + tx.stateTransitions.flatMap((batch) => batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st))) ) - ); + const stateDiff = collectStateDiff(input); const state = await unprovenState.getMany( Object.keys(stateDiff).map(Field) @@ -215,7 +214,7 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await txStorage.getPendingUserTransactions(); expect(txs).toHaveLength(1); - expect(txs[0].hash().toString()).toStrictEqual(tx.hash().toString()); + expect(txs[0].hash).toStrictEqual(tx.hash); await sequencer.resolve("BlockTrigger").produceBlock(); diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 6ad58436e..a8937690d 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -43,7 +43,6 @@ import { FungibleToken, FungibleTokenAdmin } from "mina-fungible-token"; import { ManualBlockTrigger, - PendingTransaction, PrivateMempool, BlockQueue, SettlementModule, diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index 7fd3e1356..8ac17d619 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -231,7 +231,7 @@ describe("graphql client test", () => { const heightParsedTx = heightResult?.transactions!; - const blockTxHash = block?.transactions[0].tx.toJSON().hash; + const blockTxHash = block?.transactions[0].tx.hash; const queryTxHash = heightParsedTx[0]?.tx?.hash; From a4ac3928370ecad0e3264504a4e049773a42a805 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 08:27:24 +0300 Subject: [PATCH 27/63] refactor: use non-provable types in tracing and task layers --- .../protocol/production/tasks/NewBlockTask.ts | 14 +++--- .../production/tasks/RuntimeProvingTask.ts | 38 ++++++++++------ .../tasks/TransactionProvingTask.ts | 9 ++-- .../NewBlockProvingParametersSerializer.ts | 29 ++++-------- .../RuntimeProofParametersSerializer.ts | 44 +++++-------------- ...ansactionProvingTaskParameterSerializer.ts | 16 +++---- .../types/TransactionProvingTypes.ts | 5 ++- .../production/tracing/BlockTracingService.ts | 15 +++++++ .../tracing/TransactionTracingService.ts | 19 ++++---- 9 files changed, 92 insertions(+), 97 deletions(-) diff --git a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts index 460d0c337..5a7bf61df 100644 --- a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts @@ -21,7 +21,7 @@ import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PairingDerivedInput } from "../flow/ReductionTaskFlow"; -import type { TaskStateRecord } from "../tracing/BlockTracingService"; +import { TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; import { NewBlockProvingParametersSerializer } from "./serializers/NewBlockProvingParametersSerializer"; import { executeWithPrefilledStateService } from "./TransactionProvingTask"; @@ -34,8 +34,8 @@ export interface NewBlockProverParameters { blockWitness: BlockHashMerkleTreeWitness; deferSTProof: Bool; afterBlockRootWitness: WitnessedRootWitness; - startingStateBeforeHook: TaskStateRecord; - startingStateAfterHook: TaskStateRecord; + startingStateBeforeHook: TaskStateRecordJson; + startingStateAfterHook: TaskStateRecordJson; } export type NewBlockProvingParameters = PairingDerivedInput< @@ -110,15 +110,19 @@ export class NewBlockTask input2 ); + // Convert from JSON to provable types at the proving boundary + const startingStateBeforeHookProvable = taskStateRecordFromJson(startingStateBeforeHook); + const startingStateAfterHookProvable = taskStateRecordFromJson(startingStateAfterHook); + await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHook, startingStateAfterHook], + [startingStateBeforeHookProvable, startingStateAfterHookProvable], async () => {} ); return await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHook, startingStateAfterHook], + [startingStateBeforeHookProvable, startingStateAfterHookProvable], async () => await this.executionContext.current().result.prove() ); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index bf3dd50d1..9bf070de5 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -7,6 +7,7 @@ import { import { MethodPublicOutput, NetworkState, + NetworkStateJson, RuntimeMethodExecutionContext, } from "@proto-kit/protocol"; import { Proof } from "o1js"; @@ -16,8 +17,8 @@ import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; -import { PendingTransaction } from "../../../mempool/PendingTransaction"; -import { TaskStateRecord } from "../tracing/BlockTracingService"; +import { PendingTransaction, PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; +import { TaskStateRecord, TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; @@ -29,11 +30,17 @@ export interface RuntimeProofParameters { state: TaskStateRecord; } +export interface RuntimeProofParametersJson { + tx: PendingTransactionJSONType; + networkState: NetworkStateJson; + state: TaskStateRecordJson; +} + @injectable() @scoped(Lifecycle.ContainerScoped) export class RuntimeProvingTask extends TaskWorkerModule - implements Task + implements Task { protected readonly runtimeZkProgrammable = this.runtime.zkProgrammable.zkProgram; @@ -48,7 +55,7 @@ export class RuntimeProvingTask super(); } - public inputSerializer(): TaskSerializer { + public inputSerializer(): TaskSerializer { return new RuntimeProofParametersSerializer(); } @@ -56,15 +63,20 @@ export class RuntimeProvingTask return new ProofTaskSerializer(this.runtimeZkProgrammable[0].Proof); } - public async compute(input: RuntimeProofParameters): Promise { - const method = this.runtime.getMethodById(input.tx.methodId.toString()); + public async compute(input: RuntimeProofParametersJson): Promise { + // Convert from JSON to provable types at the proving boundary + const tx = PendingTransaction.fromJSON(input.tx); + const networkState = new NetworkState(NetworkState.fromJSON(input.networkState)); + const state = taskStateRecordFromJson(input.state); + + const method = this.runtime.getMethodById(tx.methodId.toString()); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(input.tx.methodId.toString()); + .getMethodNameFromId(tx.methodId.toString()); if (methodDescriptors === undefined || method === undefined) { - throw new Error(`MethodId not found ${input.tx.methodId.toString()}`); + throw new Error(`MethodId not found ${tx.methodId.toString()}`); } const [moduleName, methodName] = methodDescriptors; @@ -74,19 +86,19 @@ export class RuntimeProvingTask methodName ); const decodedArguments = await parameterEncoder.decode( - input.tx.argsFields, - input.tx.auxiliaryData + tx.argsFields, + tx.auxiliaryData ); - const prefilledStateService = new PreFilledStateService(input.state); + const prefilledStateService = new PreFilledStateService(state); this.runtime.stateServiceProvider.setCurrentStateService( prefilledStateService ); // Set network state and transaction for the runtimemodule to access - const { transaction, signature } = input.tx.toProtocolTransaction(); + const { transaction, signature } = tx.toProtocolTransaction(); const contextInputs = { - networkState: input.networkState, + networkState, transaction, signature, }; diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index 38473a22c..0882cc9e1 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -18,7 +18,7 @@ import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskSerializer, Task } from "../../../worker/flow/Task"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; -import type { TaskStateRecord } from "../tracing/BlockTracingService"; +import { TaskStateRecord, TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; import { TransactionProvingTaskParameterSerializer } from "./serializers/TransactionProvingTaskParameterSerializer"; import { @@ -93,9 +93,12 @@ export class TransactionProvingTask public async compute( input: TransactionProvingTaskParameters ): Promise { + + const startingStateProvable = input.parameters.startingState.map(taskStateRecordFromJson); + await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - input.parameters.startingState, + startingStateProvable, async () => { const { type, parameters } = input; @@ -120,7 +123,7 @@ export class TransactionProvingTask return await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - input.parameters.startingState, + startingStateProvable, async () => await this.executionContext.current().result.prove() ); diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts index c8a1f2640..6b13b4687 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts @@ -16,11 +16,7 @@ import type { NewBlockProverParameters } from "../NewBlockTask"; import { TaskSerializer } from "../../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../../helpers/utils"; import { PairingDerivedInput } from "../../flow/ReductionTaskFlow"; - -import { - DecodedStateSerializer, - JSONEncodableState, -} from "./DecodedStateSerializer"; +import { TaskStateRecordJson } from "../../tracing/BlockTracingService"; interface JsonType { input1: string; @@ -29,13 +25,14 @@ interface JsonType { publicInput: ReturnType; networkState: ReturnType; blockWitness: ReturnType; - startingStateBeforeHook: JSONEncodableState; - startingStateAfterHook: JSONEncodableState; + startingStateBeforeHook: TaskStateRecordJson; + startingStateAfterHook: TaskStateRecordJson; deferSTProof: boolean; afterBlockRootWitness: ReturnType; }; } + type NewBlockPayload = PairingDerivedInput< StateTransitionProof, BlockProof, @@ -70,15 +67,9 @@ export class NewBlockProvingParametersSerializer input.params.blockWitness ), - startingStateBeforeHook: DecodedStateSerializer.toJSON( - input.params.startingStateBeforeHook - ), - - startingStateAfterHook: DecodedStateSerializer.toJSON( - input.params.startingStateAfterHook - ), + startingStateBeforeHook: input.params.startingStateBeforeHook, - deferSTProof: input.params.deferSTProof.toBoolean(), + startingStateAfterHook: input.params.startingStateAfterHook, deferSTProof: input.params.deferSTProof.toBoolean(), afterBlockRootWitness: WitnessedRootWitness.toJSON( input.params.afterBlockRootWitness @@ -107,13 +98,9 @@ export class NewBlockProvingParametersSerializer BlockHashMerkleTreeWitness.fromJSON(jsonObject.params.blockWitness) ), - startingStateBeforeHook: DecodedStateSerializer.fromJSON( - jsonObject.params.startingStateBeforeHook - ), + startingStateBeforeHook: jsonObject.params.startingStateBeforeHook, - startingStateAfterHook: DecodedStateSerializer.fromJSON( - jsonObject.params.startingStateBeforeHook - ), + startingStateAfterHook: jsonObject.params.startingStateAfterHook, deferSTProof: Bool(jsonObject.params.deferSTProof), diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts index 102d89c09..1607841ef 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts @@ -1,41 +1,19 @@ -import { NetworkState, ReturnType } from "@proto-kit/protocol"; - import { TaskSerializer } from "../../../../worker/flow/Task"; -import { PendingTransaction } from "../../../../mempool/PendingTransaction"; -import type { RuntimeProofParameters } from "../RuntimeProvingTask"; - -import { - DecodedStateSerializer, - JSONEncodableState, -} from "./DecodedStateSerializer"; +import type { RuntimeProofParametersJson } from "../RuntimeProvingTask"; +/** + * Serializer for RuntimeProofParametersJson. + * Since RuntimeProofParametersJson is already JSON-compatible, this is trivial. + */ export class RuntimeProofParametersSerializer - implements TaskSerializer + implements TaskSerializer { - public toJSON(parameters: RuntimeProofParameters): string { - const jsonReadyObject = { - tx: parameters.tx.toJSON(), - networkState: NetworkState.toJSON(parameters.networkState), - state: DecodedStateSerializer.toJSON(parameters.state), - }; - return JSON.stringify(jsonReadyObject); + public toJSON(parameters: RuntimeProofParametersJson): string { + return JSON.stringify(parameters); } - public fromJSON(json: string): RuntimeProofParameters { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const jsonReadyObject: { - tx: ReturnType; - networkState: ReturnType<(typeof NetworkState)["toJSON"]>; - state: JSONEncodableState; - } = JSON.parse(json); - return { - tx: PendingTransaction.fromJSON(jsonReadyObject.tx), - - networkState: new NetworkState( - NetworkState.fromJSON(jsonReadyObject.networkState) - ), - - state: DecodedStateSerializer.fromJSON(jsonReadyObject.state), - }; + public fromJSON(json: string): RuntimeProofParametersJson { + return JSON.parse(json) as RuntimeProofParametersJson; } } + diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts index da655d863..792f6fb2d 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts @@ -10,17 +10,15 @@ import { JsonProof, Signature } from "o1js"; import { TaskSerializer } from "../../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../../helpers/utils"; +import { TaskStateRecordJson } from "../../tracing/BlockTracingService"; import { TransactionProvingTaskParameters, TransactionProvingType, } from "./types/TransactionProvingTypes"; -import { - DecodedStateSerializer, - JSONEncodableState, -} from "./DecodedStateSerializer"; import { RuntimeVerificationKeyAttestationSerializer } from "./RuntimeVerificationKeyAttestationSerializer"; + export type BlockProverTransactionArgumentsJSON = { transaction: ReturnType; signature: ReturnType; @@ -43,7 +41,7 @@ export type MultiExecutionDataJSON = { export type TransactionProverTaskParametersJSON< ExecutionData extends SingleExecutionDataJSON | MultiExecutionDataJSON, > = { - startingState: JSONEncodableState[]; + startingState: TaskStateRecordJson[]; publicInput: ReturnType; executionData: ExecutionData; }; @@ -108,9 +106,7 @@ export class TransactionProvingTaskParameterSerializer const partialParameters = { publicInput: BlockProverPublicInput.toJSON(parameters.publicInput), - startingState: parameters.startingState.map((stateRecord) => - DecodedStateSerializer.toJSON(stateRecord) - ), + startingState: parameters.startingState, }; // The reason we can't just use the structs toJSON is that the VerificationKey @@ -169,9 +165,7 @@ export class TransactionProvingTaskParameterSerializer const partialParameters = { publicInput: BlockProverPublicInput.fromJSON(parameters.publicInput), - startingState: parameters.startingState.map((stateRecord) => - DecodedStateSerializer.fromJSON(stateRecord) - ), + startingState: parameters.startingState, }; if (type === TransactionProvingType.SINGLE) { diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts index b091abdc2..3da24d473 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts @@ -6,7 +6,7 @@ import { } from "@proto-kit/protocol"; import { Proof } from "o1js"; -import type { TaskStateRecord } from "../../../tracing/BlockTracingService"; +import type { TaskStateRecordJson } from "../../../tracing/BlockTracingService"; export type RuntimeProof = Proof; @@ -22,9 +22,10 @@ export interface TransactionProverTaskParameters< > { publicInput: BlockProverPublicInput; executionData: ExecutionData; - startingState: TaskStateRecord[]; + startingState: TaskStateRecordJson[]; } + export type TransactionProvingTaskParameters = | { type: TransactionProvingType.SINGLE; diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 1ce1b497f..ebfa20e10 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -26,7 +26,22 @@ import { UntypedStateTransition, UntypedStateTransitionJson } from "../helpers/U export type TaskStateRecord = Record; +export type TaskStateRecordJson = Record; + +export function taskStateRecordToJson(record: TaskStateRecord): TaskStateRecordJson { + return Object.fromEntries( + Object.entries(record).map(([key, fields]) => [key, fields.map(f => f.toString())]) + ); +} + +export function taskStateRecordFromJson(json: TaskStateRecordJson): TaskStateRecord { + return Object.fromEntries( + Object.entries(json).map(([key, strings]) => [key, strings.map(s => Field(s))]) + ); +} + export type BlockTracingState = Pick< + BlockProverState, | "witnessedRoots" | "stateRoot" diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 6f420aa73..b6d0221b4 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -16,7 +16,7 @@ import { inject, injectable } from "tsyringe"; import { TransactionExecutionResult } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; -import type { RuntimeProofParameters } from "../tasks/RuntimeProvingTask"; +import type { RuntimeProofParametersJson } from "../tasks/RuntimeProvingTask"; import { TransactionProverTaskParameters, TransactionProvingType, @@ -24,23 +24,23 @@ import { import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { VerificationKeyService } from "../../runtime/RuntimeVerificationKeyService"; -import type { BlockTracingState, TaskStateRecord } from "./BlockTracingService"; +import type { BlockTracingState, TaskStateRecordJson } from "./BlockTracingService"; export type TransactionTrace = | { type: TransactionProvingType.SINGLE; transaction: TransactionProverTaskParameters; - runtime: [RuntimeProofParameters]; + runtime: [RuntimeProofParametersJson]; } | { type: TransactionProvingType.MULTI; transaction: TransactionProverTaskParameters; - runtime: [RuntimeProofParameters, RuntimeProofParameters]; + runtime: [RuntimeProofParametersJson, RuntimeProofParametersJson]; }; export function collectStartingState( stateTransitions: UntypedStateTransition[] -): TaskStateRecord { +): TaskStateRecordJson { const stateEntries = stateTransitions // Filter distinct .filter( @@ -52,11 +52,12 @@ export function collectStartingState( // "state hasn't been set before" and has to correlate to a precondition on Field(0) // and for that the state has to be undefined .filter((st) => st.fromValue.isSome.toBoolean()) - .map((st) => [st.path.toString(), st.fromValue.value]); + .map((st) => [st.path.toString(), st.fromValue.value.map((f: Field) => f.toString())]); return Object.fromEntries(stateEntries); } + @injectable() export class TransactionTracingService { private readonly blockProver: BlockProverProgrammable; @@ -124,14 +125,14 @@ export class TransactionTracingService { private createRuntimeProofParams( tx: TransactionExecutionResult, networkState: NetworkState - ): RuntimeProofParameters { + ): RuntimeProofParametersJson { const startingState = collectStartingState( tx.stateTransitions[1].stateTransitions ); return { - tx: tx.tx, - networkState, + tx: tx.tx.toJSON(), + networkState: NetworkState.toJSON(networkState), state: startingState, }; } From bc53d888459045e58811e19ae4f2bc6fe3065f0b Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 08:56:43 +0300 Subject: [PATCH 28/63] refactor: use non-provable types in tracing services --- .../production/tracing/BlockTracingService.ts | 2 +- .../tracing/TransactionTracingService.ts | 46 +++++++++++-------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index ebfa20e10..26afc53aa 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -116,7 +116,7 @@ export class BlockTracingService { ) ; const [afterState, transactionTraces] = await yieldSequential( - chunk(block.block.transactions.map(txResultFromJson), 2), + chunk(block.block.transactions, 2), async (input, [transaction1, transaction2]) => { const [output, transactionTrace] = transaction2 !== undefined diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index b6d0221b4..d4e7f9924 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -14,7 +14,7 @@ import { MAX_FIELD } from "@proto-kit/common"; import { toStateTransitionsHash } from "@proto-kit/module"; import { inject, injectable } from "tsyringe"; -import { TransactionExecutionResult } from "../../../storage/model/Block"; +import { TransactionExecutionResultJson, STBatchFromJson } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; import type { RuntimeProofParametersJson } from "../tasks/RuntimeProvingTask"; import { @@ -103,16 +103,20 @@ export class TransactionTracingService { private appendTransactionToState( previousState: BlockTracingState, - transaction: TransactionExecutionResult + transaction: TransactionExecutionResultJson ) { - // TODO Remove this call and instead reuse results from sequencing + + const tx = PendingTransaction.fromJSON(transaction.tx); + + // TODO Remove this call and instead reuse results from sequencing ? const newState = this.blockProver.addTransactionToBundle( previousState, - Bool(transaction.tx.isMessage), - transaction.tx.toRuntimeTransaction() + Bool(tx.isMessage), + tx.toRuntimeTransaction() ); - transaction.stateTransitions.forEach((batch) => { + const stBatches = transaction.stateTransitions.map(STBatchFromJson); + stBatches.forEach((batch) => { newState.pendingSTBatches.push({ applied: Bool(batch.applied), batchHash: toStateTransitionsHash(batch.stateTransitions), @@ -123,15 +127,15 @@ export class TransactionTracingService { } private createRuntimeProofParams( - tx: TransactionExecutionResult, + tx: TransactionExecutionResultJson, networkState: NetworkState ): RuntimeProofParametersJson { - const startingState = collectStartingState( - tx.stateTransitions[1].stateTransitions - ); + + const stBatch = STBatchFromJson(tx.stateTransitions[1]); + const startingState = collectStartingState(stBatch.stateTransitions); return { - tx: tx.tx.toJSON(), + tx: tx.tx, networkState: NetworkState.toJSON(networkState), state: startingState, }; @@ -139,10 +143,12 @@ export class TransactionTracingService { private async traceTransaction( previousState: BlockTracingState, - transaction: TransactionExecutionResult + transaction: TransactionExecutionResultJson ) { + const stBatches = transaction.stateTransitions.map(STBatchFromJson); + const beforeHookStartingState = collectStartingState( - transaction.stateTransitions[0].stateTransitions.flat() + stBatches[0].stateTransitions.flat() ); const runtimeTrace1 = this.createRuntimeProofParams( @@ -151,7 +157,7 @@ export class TransactionTracingService { ); const afterHookStartingState = collectStartingState( - transaction.stateTransitions[2].stateTransitions.flat() + stBatches[2].stateTransitions.flat() ); const newState = this.appendTransactionToState(previousState, transaction); @@ -165,7 +171,7 @@ export class TransactionTracingService { public async createSingleTransactionTrace( previousState: BlockTracingState, - transaction: TransactionExecutionResult + transaction: TransactionExecutionResultJson ): Promise<[BlockTracingState, TransactionTrace]> { const publicInput = this.getTransactionProofPublicInput(previousState); @@ -178,7 +184,7 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction: await this.getTransactionData(transaction.tx), + transaction: await this.getTransactionData(PendingTransaction.fromJSON(transaction.tx)), networkState: previousState.networkState, }, startingState, @@ -197,8 +203,8 @@ export class TransactionTracingService { public async createMultiTransactionTrace( previousState: BlockTracingState, - transaction1: TransactionExecutionResult, - transaction2: TransactionExecutionResult + transaction1: TransactionExecutionResultJson, + transaction2: TransactionExecutionResultJson ): Promise<[BlockTracingState, TransactionTrace]> { const publicInput = this.getTransactionProofPublicInput(previousState); @@ -217,8 +223,8 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction1: await this.getTransactionData(transaction1.tx), - transaction2: await this.getTransactionData(transaction2.tx), + transaction1: await this.getTransactionData(PendingTransaction.fromJSON(transaction1.tx)), + transaction2: await this.getTransactionData(PendingTransaction.fromJSON(transaction2.tx)), networkState: previousState.networkState, }, startingState: [...startingState1, ...startingState2], From 57c352064f5191dd0f0d218845ff410b7ccf0186 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 09:13:36 +0300 Subject: [PATCH 29/63] style: run lint fix --- Refactor Block Types Persistence.md | 1111 +++++++++++++++++ packages/indexer/src/IndexerNotifier.ts | 5 +- ...eratedResolverFactoryGraphqlModule.test.ts | 1 - packages/indexer/test/IndexBlockTask.test.ts | 4 +- packages/indexer/test/IndexerNotifier.test.ts | 2 +- .../src/services/prisma/PrismaBlockStorage.ts | 14 +- .../services/prisma/PrismaMessageStorage.ts | 5 +- .../prisma/PrismaTransactionStorage.ts | 9 +- .../services/prisma/mappers/BlockMapper.ts | 22 +- .../prisma/mappers/BlockResultMapper.ts | 5 +- .../services/prisma/mappers/EventMapper.ts | 5 +- .../prisma/mappers/StateTransitionMapper.ts | 6 +- .../prisma/mappers/TransactionMapper.ts | 1 - .../PrismaBlockProduction.test.ts | 9 +- .../accummulators/BlockHashMerkleTree.ts | 12 +- packages/protocol/src/utils/utils.ts | 1 + .../GraphqlNetworkStateTransportModule.ts | 2 +- .../src/graphql/GraphqlTransactionSender.ts | 5 +- .../query/BlockStorageNetworkStateModule.ts | 6 +- .../sdk/src/query/InMemoryBlockExplorer.ts | 6 +- .../transaction/InMemoryTransactionSender.ts | 1 - .../query/BlockExplorerTransportModule.ts | 2 - packages/sequencer/src/helpers/utils.ts | 9 +- packages/sequencer/src/mempool/Mempool.ts | 5 +- .../src/mempool/private/PrivateMempool.ts | 30 +- .../verification/TransactionValidator.ts | 9 +- .../src/protocol/baselayer/NoopBaseLayer.ts | 2 +- .../helpers/UntypedStateTransition.ts | 12 +- .../sequencing/BlockProducerModule.ts | 12 +- .../sequencing/BlockProductionService.ts | 22 +- .../sequencing/BlockResultService.ts | 6 +- .../sequencing/TransactionExecutionService.ts | 39 +- .../protocol/production/tasks/NewBlockTask.ts | 13 +- .../production/tasks/RuntimeProvingTask.ts | 19 +- .../tasks/TransactionProvingTask.ts | 10 +- .../NewBlockProvingParametersSerializer.ts | 4 +- .../RuntimeProofParametersSerializer.ts | 2 +- ...ansactionProvingTaskParameterSerializer.ts | 1 - .../types/TransactionProvingTypes.ts | 1 - .../production/tracing/BatchTracingService.ts | 10 +- .../production/tracing/BlockTracingService.ts | 49 +- .../tracing/StateTransitionTracingService.ts | 23 +- .../tracing/TransactionTracingService.ts | 36 +- .../runtime/RuntimeVerificationKeyService.ts | 8 +- .../messages/MinaIncomingMessageAdapter.ts | 5 +- .../outgoing/DefaultOutgoingMessageAdapter.ts | 2 +- .../storage/inmemory/InMemoryBlockStorage.ts | 4 +- .../inmemory/InMemoryMessageStorage.ts | 2 +- .../inmemory/InMemoryTransactionStorage.ts | 24 +- packages/sequencer/src/storage/model/Block.ts | 13 +- .../test/integration/BlockProduction-test.ts | 12 +- .../test/integration/Mempool.test.ts | 2 +- .../integration/StorageIntegration.test.ts | 19 +- packages/sequencer/test/integration/utils.ts | 4 +- .../sequencer/test/settlement/Settlement.ts | 6 +- 55 files changed, 1425 insertions(+), 224 deletions(-) create mode 100644 Refactor Block Types Persistence.md diff --git a/Refactor Block Types Persistence.md b/Refactor Block Types Persistence.md new file mode 100644 index 000000000..ff4ff32ff --- /dev/null +++ b/Refactor Block Types Persistence.md @@ -0,0 +1,1111 @@ +# Chat Conversation + +## Block Production Flow: Provable vs Non-Provable + +### Overview Diagram + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ SEQUENCING (Non-Provable) │ +│ BlockProducerModule → BlockProductionService → TransactionExecutionService │ +│ │ +│ - Execute transactions │ +│ - Collect state transitions │ +│ - Create Block (with TransactionExecutionResult) │ +│ - Store to DB │ +└─────────────────────────────────────────────────────────────────────────────┘ + ↓ (Block stored) +┌─────────────────────────────────────────────────────────────────────────────┐ +│ TRACING (Non-Provable) │ +│ BatchProducerModule → BatchTracingService → BlockTracingService │ +│ → StateTransitionTracingService │ +│ → TransactionTracingService │ +│ │ +│ - Collect witnesses (merkle proofs, state values) │ +│ - Prepare inputs for provers │ +│ - Still uses o1js types (Field, Bool) but NOT in-circuit │ +└─────────────────────────────────────────────────────────────────────────────┘ + ↓ (Trace created) +┌─────────────────────────────────────────────────────────────────────────────┐ +│ PROVING (Provable/In-Circuit) │ +│ BatchFlow → StateTransitionFlow → StateTransitionTask.compute() │ +│ → BlockFlow → TransactionProvingTask.compute() │ +│ → NewBlockTask.compute() │ +│ │ +│ ⚡ THIS IS WHERE ZK PROOFS ARE GENERATED ⚡ │ +│ - StateTransitionProver.prove*() methods │ +│ - BlockProver.proveTransaction/proveBlock() methods │ +│ - executionContext.current().result.prove() │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +### Detailed Breakdown + +| Stage | File(s) | Provable? | Description | +|-------|---------|-----------|-------------| +| **1. Sequencing** | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | ❌ No | Executes transactions, creates [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) with `TransactionExecutionResult[]` | +| **2. Block Metadata** | [BlockResultService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts:0:0-0:0) | ❌ No | Generates [BlockResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:128:0-136:1) (state root, merkle witnesses) | +| **3. Tracing** | `BatchTracingService.ts`, [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0), `TransactionTracingService.ts`, [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) | ❌ No | Collects witnesses and prepares prover inputs. Uses `o1js` types but just for data construction, NOT in-circuit | +| **4. Flow Orchestration** | [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0), `BlockFlow.ts`, `StateTransitionFlow.ts` | ❌ No | Orchestrates the proving tasks, manages parallelism | +| **5. PROVING TASKS** | `NewBlockTask.compute()`, `TransactionProvingTask.compute()`, `StateTransitionTask.compute()`, `RuntimeProvingTask.compute()` | ✅ **YES** | **This is where ZK proofs are actually generated!** Calls methods like `blockProver.proveBlock()`, `stateTransitionProver.prove*()` | + +--- + +### Where Provable Code Actually Runs + +The **provable (in-circuit)** code is in the `@proto-kit/protocol` package: + +1. **[BlockProver](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:30:0-38:1)** - Proves block validity + - `proveBlock()` + - `proveTransaction()` + - `proveTransactions()` + +2. **`StateTransitionProver`** - Proves state transition validity + - Various prove methods for merkle tree updates + +3. **`Runtime`** (from `@proto-kit/module`) - Proves runtime method execution + - The actual user-defined runtime methods + +These provers are **ZkPrograms** that run inside the provable context. The [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) method in tasks like [NewBlockTask](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:46:0-130:1) calls these prover methods: + +```typescript +// NewBlockTask.compute() - Line 101-108 +await this.blockProver.proveBlock( + publicInput, + networkState, + blockWitness, + input1, + deferSTProof, + afterBlockRootWitness, + input2 +); + +// Then generate the actual proof +return await this.executionContext.current().result.prove(); +``` + +--- + +### Key Insight for Your Refactoring + +The **sequencing** and **block storage** layers ([Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1), [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1)) don't need provable types because: + +1. They run **before** proving happens +2. The tracing services **convert** from storage types (Json) back to provable types when needed +3. The actual proving happens in **worker tasks** that receive serialized (Json) inputs and deserialize them to provable types + +Your refactoring is correct - using Json types in `Block.transactions` and converting to provable types only in the tracing layer is the right approach! + +### User Input + +Okay. Now, as you've stated, there are provable code in non-provable part, namely in Sequencer and Tracer. I want to refactor them to be non-provable and convert to provable when they are only needed in Proving. + +Create a plan to do changes in steps. + +### Planner Response + +# Refactoring Plan: Non-Provable Types in Sequencer & Tracing Layers + +## Objective + +Refactor the Sequencer and Tracing layers to use **non-provable (JSON-serializable) types** for data storage and intermediate processing, converting to **provable types only at the proving boundary** (when data enters the `*Task.compute()` methods). + +--- + +## Current State Analysis + +### Provable Types Used in Non-Provable Code + +| Type | From | Used In | Impact | +|------|------|---------|--------| +| `Field` | `o1js` | State paths, hashes, commitments | High | +| `Bool` | `o1js` | Transaction status, flags | Medium | +| `UInt64` | `o1js` | Block heights, nonces | Medium | +| `Signature` | `o1js` | Transaction signatures | Medium | +| `PublicKey` | `o1js` | Sender addresses | Medium | +| `NetworkState` (Struct) | `@proto-kit/protocol` | Block network state | High | +| `PendingTransaction` (Class) | Sequencer | Mempool, execution | High - **Already done ✅** | +| [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1) | Sequencer | Block transactions | High - **Already done ✅** | +| `UntypedStateTransition` | Sequencer | State tracking | High - **Partially done** | + +--- + +## Phased Refactoring Plan + +### Phase 1: Complete Current Work (Block & Transaction Types) ✅ +**Status: DONE** + +- [x] [TransactionExecutionResultJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:41:0-52:1) interface +- [x] [StateTransitionBatchJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:36:0-39:1) interface +- [x] [txResultToJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:54:0-70:1) converter +- [x] [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) converter +- [x] Update `Block.transactions` to use `TransactionExecutionResultJson[]` +- [x] Update [BlockProductionService](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:46:0-212:1) to convert on block creation +- [x] Update tracing services to convert back when needed + +--- + +### Phase 2: Trackers & Block State Types +**Goal**: Remove `Field` usage from block production tracking structures + +#### 2.1 `BlockTrackers` in `TransactionExecutionService.ts` + +**Current:** +```typescript +export interface BlockTrackers { + blockHashRoot: Field; + eternalTransactionsList: TransactionHashList; + transactionList: TransactionHashList; + incomingMessages: MinaActionsHashList; +} +``` + +**Target:** +```typescript +export interface BlockTrackersJson { + blockHashRoot: string; + eternalTransactionsHash: string; + transactionsHash: string; + incomingMessagesHash: string; +} +``` + +**Files to change:** +- `TransactionExecutionService.ts` +- [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) + +--- + +### Phase 3: Tracing Service Outputs +**Goal**: Make tracing service outputs JSON-serializable + +#### 3.1 [TaskStateRecord](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:26:0-26:54) Type + +**Current (in [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0)):** +```typescript +export type TaskStateRecord = Record; +``` + +**Target:** +```typescript +export type TaskStateRecordJson = Record; +``` + +**Files to change:** +- [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) +- `TransactionTracingService.ts` +- [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) (convert at boundary) + +#### 3.2 [BlockTracingState](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:28:0-37:2) Type + +**Current:** +```typescript +export type BlockTracingState = Pick< + BlockProverState, + | "witnessedRoots" + | "stateRoot" + | "pendingSTBatches" + | "networkState" + | "transactionList" + | "eternalTransactionsList" + | "incomingMessages" +>; +``` + +This uses provable hash lists. These are needed for the proving pipeline but could potentially be replaced with simpler commitment tracking. + +**Recommendation:** Keep as-is for now, as it's tightly coupled to proving logic. + +--- + +### Phase 4: Batch Trace Types +**Goal**: Make `BatchTrace` JSON-serializable for worker serialization + +#### 4.1 `BatchTrace` in `BatchTracingService.ts` + +**Current:** +```typescript +export interface BatchTrace { + blocks: BlockTrace[]; + stateTransitionTrace: StateTransitionProofParameters[]; +} +``` + +Where [BlockTrace](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:39:0-44:2) contains: +```typescript +export type BlockTrace = { + blockParams: NewBlockProverParameters; + transactions: TransactionTrace[]; + height: string; +}; +``` + +And [NewBlockProverParameters](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:30:0-38:1) contains provable types like `NetworkState`, `Bool`, etc. + +**Target:** Create `*Json` variants for serialization. + +**Files to change:** +- `BatchTracingService.ts` +- [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) +- Task serializers (already exist but could be simplified) + +--- + +### Phase 5: Merkle Witness Types +**Goal**: Use JSON representations for merkle witnesses + +#### 5.1 `LinkedMerkleTreeWitness` + +**Current:** Uses `Field[]` internally + +**Target:** Already has [toJSON()](cci:1://file:///Users/saitunc/Desktop/framework/packages/indexer/src/tasks/IndexBlockTaskParameters.ts:18:2-26:3)/[fromJSON()](cci:1://file:///Users/saitunc/Desktop/framework/packages/indexer/src/tasks/IndexBlockTaskParameters.ts:28:2-47:3) - ensure these are used consistently + +**Files to check:** +- [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) +- [StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) + +--- + +### Phase 6: RuntimeProofParameters +**Goal**: Make runtime proving parameters JSON-serializable + +#### 6.1 `RuntimeProofParameters` in `TransactionTracingService.ts` + +**Current:** +```typescript +export interface RuntimeProofParameters { + tx: PendingTransaction; + networkState: NetworkState; + state: TaskStateRecord; +} +``` + +**Target:** +```typescript +export interface RuntimeProofParametersJson { + tx: PendingTransactionJSONType; + networkState: NetworkStateJson; + state: TaskStateRecordJson; +} +``` + +**Files to change:** +- `TransactionTracingService.ts` +- [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) (convert at boundary) + +--- + +## Implementation Order + +``` +Phase 2: BlockTrackers + ↓ +Phase 3: TaskStateRecord + ↓ +Phase 4: BatchTrace (depends on 2 & 3) + ↓ +Phase 5: Merkle Witnesses + ↓ +Phase 6: RuntimeProofParameters +``` + +--- + +## Detailed Steps for Each Phase + +### Phase 2: BlockTrackers (Recommended Next Step) + +| Step | File | Change | +|------|------|--------| +| 2.1.1 | `TransactionExecutionService.ts` | Create `BlockTrackersJson` interface | +| 2.1.2 | `TransactionExecutionService.ts` | Add `blockTrackersToJson()` helper | +| 2.1.3 | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | Use string hashes instead of `Field` for block state | +| 2.1.4 | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | Convert to `Field` only when calling protocol methods | + +### Phase 3: TaskStateRecord + +| Step | File | Change | +|------|------|--------| +| 3.1.1 | [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) | Create `TaskStateRecordJson` type | +| 3.1.2 | `TransactionTracingService.ts` | Update `collectStartingState()` to return Json | +| 3.1.3 | [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) | Convert `TaskStateRecordJson` → [TaskStateRecord](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:26:0-26:54) in [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) | +| 3.1.4 | [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) | Same conversion at boundary | + +### Phase 4: BatchTrace + +| Step | File | Change | +|------|------|--------| +| 4.1.1 | [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) | Create `BlockTraceJson`, `NewBlockProverParametersJson` | +| 4.1.2 | `BatchTracingService.ts` | Create `BatchTraceJson` | +| 4.1.3 | [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0) | Convert Json → Provable when pushing to tasks | +| 4.1.4 | Update task parameter serializers | Simplify (just JSON.stringify) | + +--- + +## Files Summary + +### High Priority (Phase 2-3) +1. `TransactionExecutionService.ts` - BlockTrackers +2. [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) - Uses BlockTrackers +3. [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) - TaskStateRecord, BlockTrace +4. `TransactionTracingService.ts` - collectStartingState, RuntimeProofParameters + +### Medium Priority (Phase 4-5) +5. `BatchTracingService.ts` - BatchTrace +6. [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) - Merkle witnesses +7. [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0) - Orchestration + +### Proving Boundary (Update Converters) +8. [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) - Convert at compute() +9. [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) - Convert at compute() +10. [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) - Convert at compute() +11. [StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) - Convert at compute() + +--- + +## Questions to Consider + +1. **Do you want to proceed phase by phase, or tackle a specific area first?** + +2. **Should we prioritize the tracing layer (which is more complex) or the simpler BlockTrackers first?** + +3. **Are there any specific files you've noticed issues with that you'd like to prioritize?** + +--- + +Would you like me to start implementing **Phase 2 (BlockTrackers)** or **Phase 3 (TaskStateRecord)** first? + +### User Input + +I have a concern, which you might solve. I will change types at so many steps, but mappers or task serializers are using the original types. When we do the change, do i expect to directly not use any mappers or task serializers ? + +### Planner Response + +Excellent question! Let me clarify the relationship between types, mappers, and task serializers: + +## The Two Serialization Boundaries + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ SEQUENCER PROCESS │ +│ │ +│ Domain Layer (your types) │ +│ ↓ │ +│ ┌─────────────────────┐ ┌─────────────────────┐ │ +│ │ PERSISTENCE LAYER │ │ WORKER DISPATCH │ │ +│ │ (Prisma/DB) │ │ (IPC/Network) │ │ +│ │ │ │ │ │ +│ │ Uses: Mappers │ │ Uses: Serializers │ │ +│ └──────────┬──────────┘ └──────────┬──────────┘ │ +└─────────────┼───────────────────────────────┼───────────────────────┘ + ↓ ↓ + ┌─────────┐ ┌─────────────┐ + │ DB │ │ WORKER │ + │ (JSON) │ │ PROCESS │ + └─────────┘ └─────────────┘ +``` + +--- + +## Current State vs Target State + +### 1. Persistence Mappers + +| Current | Target | +|---------|--------| +| Domain uses provable types (`Field`, `Bool`) | Domain uses Json types (`string`, `boolean`) | +| Mappers convert: `Field` → `string` | **No conversion needed** - just cast | +| Complex mapping logic | Simple `as unknown as Prisma.JsonArray` | + +**Result: Mappers become trivial or can be removed** + +You've already seen this with `Block.transactions`: +```typescript +// Before: Complex mapper converting Bool/Field to primitives +// After: Just a cast +transactions: input.transactions as unknown as Prisma.JsonArray +``` + +--- + +### 2. Task Serializers + +This is more nuanced. Let me show you: + +**Current Flow:** +``` +Provable Types (Field, Bool, NetworkState) + ↓ Custom Serializer (e.g., field.toString(), networkState.toJSON()) +JSON String + ↓ Send to worker + ↓ Custom Deserializer (e.g., Field(str), NetworkState.fromJSON()) +Provable Types → Used in proving +``` + +**Target Flow (with Json types):** +``` +Json Types (string, boolean, NetworkStateJson) + ↓ Simple JSON.stringify() +JSON String + ↓ Send to worker + ↓ Simple JSON.parse() +Json Types + ↓ Convert to Provable at boundary (new step!) +Provable Types → Used in proving +``` + +--- + +## The Key Insight + +**Task Serializers don't disappear - they become SIMPLER, and the conversion moves to the compute() method.** + +### Example: `NewBlockProvingParametersSerializer` + +**Current (complex):** +```typescript +class NewBlockProvingParametersSerializer { + toJSON(params: NewBlockProvingParameters): string { + return JSON.stringify({ + publicInput: this.publicInputSerializer.toJSON(params.publicInput), + networkState: NetworkState.toJSON(params.networkState), + blockWitness: BlockHashMerkleTreeWitness.toJSON(params.blockWitness), + deferSTProof: params.deferSTProof.toBoolean(), + // ... lots of custom conversion + }); + } + + fromJSON(json: string): NewBlockProvingParameters { + const parsed = JSON.parse(json); + return { + publicInput: this.publicInputSerializer.fromJSON(parsed.publicInput), + networkState: new NetworkState(NetworkState.fromJSON(parsed.networkState)), + // ... lots of custom reconstruction + }; + } +} +``` + +**Target (simple):** +```typescript +class NewBlockProvingParametersSerializer { + // Types are already Json-compatible! + toJSON(params: NewBlockProvingParametersJson): string { + return JSON.stringify(params); + } + + fromJSON(json: string): NewBlockProvingParametersJson { + return JSON.parse(json); + } +} +``` + +**But now the conversion happens in `NewBlockTask.compute()`:** +```typescript +class NewBlockTask { + async compute(input: NewBlockProvingParametersJson): Promise { + // Convert at the proving boundary + const provableParams = newBlockParamsFromJson(input); + + await this.blockProver.proveBlock( + provableParams.publicInput, + provableParams.networkState, + // ... + ); + } +} +``` + +--- + +## Summary: What Happens to Each + +| Component | Current Role | After Refactoring | +|-----------|--------------|-------------------| +| **Persistence Mappers** | Convert provable ↔ DB types | **Trivial casts or removed** | +| **Task Serializers** | Custom JSON conversion with provable handling | **Simple JSON.stringify/parse** | +| **New Converters** | Don't exist | **`*FromJson()` functions at proving boundary** | + +--- + +## The Trade-off + +**Before:** +- Conversion complexity is in serializers +- Serializers handle provable → JSON → provable + +**After:** +- Serializers are trivial (just JSON) +- Conversion is explicit at the proving boundary (`*FromJson()` functions) +- Clearer separation: _"data is JSON until it enters the prover"_ + +--- + +## Practical Impact + +1. **You CAN remove/simplify mappers** for types that become fully JSON-compatible +2. **Serializers simplify** but don't completely disappear (you still need JSON.stringify/parse) +3. **New converter functions** are needed at the proving boundary (like [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) you already have) + +--- + +## Recommendation + +For the refactoring plan, I suggest we: + +1. **Keep serializers** but make them trivial (just `JSON.stringify`/`parse`) +2. **Add `*FromJson()` converters** for each type that needs to become provable +3. **Call converters in `*.compute()` methods** of tasks + +This gives you: +- ✅ Simple serialization (JSON everywhere) +- ✅ Clean proving boundary (converters in one place) +- ✅ Easy persistence (no mappers needed) + +Would you like me to proceed with Phase 2 using this approach? + +### User Input + +Cool. Add detailed implementation steps for this conversion as well. + +### Planner Response + +# Complete Refactoring Plan: Non-Provable Types with Serializer Simplification + +--- + +## Phase 0: Serializer & Mapper Analysis (Pre-work) + +### Current Serializers Inventory + +| Serializer | Location | Serializes | +|------------|----------|------------| +| `NewBlockProvingParametersSerializer` | `tasks/serializers/` | [NewBlockProvingParameters](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:40:0-44:2) | +| `TransactionProvingTaskParameterSerializer` | `tasks/serializers/` | `TransactionProvingTaskParameters` | +| `StateTransitionProofParametersSerializer` | `tasks/serializers/` | `StateTransitionProofParameters` | +| `RuntimeProofParametersSerializer` | `tasks/serializers/` | `RuntimeProofParameters` | +| `BlockProofSerializer` | `tasks/serializers/` | [BlockProof](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:28:0-28:73) (proofs) | +| `ProofTaskSerializer` | `helpers/utils.ts` | Generic proof serializer | + +### Current Mappers Inventory + +| Mapper | Location | Maps | +|--------|----------|------| +| `BlockMapper` | `persistance/mappers/` | [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) ↔ [PrismaBlock](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/PrismaBlockStorage.ts:27:0-245:1) | +| `BlockResultMapper` | `persistance/mappers/` | [BlockResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:128:0-136:1) ↔ `PrismaBlockResult` | +| [TransactionExecutionResultMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:47:0-91:1) | `persistance/mappers/` | [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1) ↔ DB | +| [TransactionMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:16:0-45:1) | `persistance/mappers/` | `PendingTransaction` ↔ DB | +| `StateTransitionBatchArrayMapper` | `persistance/mappers/` | `StateTransitionBatch[]` ↔ DB | +| `EventArrayMapper` | `persistance/mappers/` | Events ↔ DB | + +--- + +## Phase 1: Type Definitions (Already Done ✅) + +- [x] [TransactionExecutionResultJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:41:0-52:1) +- [x] [StateTransitionBatchJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:36:0-39:1) +- [x] [txResultToJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:54:0-70:1) / [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) + +--- + +## Phase 2: BlockTrackers & Block Production + +### Step 2.1: Create `BlockTrackersJson` Type + +**File:** [packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts:0:0-0:0) + +```typescript +// NEW: JSON-compatible trackers +export interface BlockTrackersJson { + blockHashRoot: string; + eternalTransactionsHash: string; + transactionsHash: string; + incomingMessagesHash: string; +} + +// Keep provable version for internal computation +export interface BlockTrackers { + blockHashRoot: Field; + eternalTransactionsList: TransactionHashList; + transactionList: TransactionHashList; + incomingMessages: MinaActionsHashList; +} + +// Converter +export function blockTrackersToJson(trackers: BlockTrackers): BlockTrackersJson { + return { + blockHashRoot: trackers.blockHashRoot.toString(), + eternalTransactionsHash: trackers.eternalTransactionsList.commitment.toString(), + transactionsHash: trackers.transactionList.commitment.toString(), + incomingMessagesHash: trackers.incomingMessages.commitment.toString(), + }; +} +``` + +### Step 2.2: Update [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) + +Keep using provable `BlockTrackers` internally (needed for hash list operations), but extract JSON values for the [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) object. + +**No change needed** - already uses `FieldString()` for Block fields. + +--- + +## Phase 3: TaskStateRecord + +### Step 3.1: Create `TaskStateRecordJson` Type + +**File:** [packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) + +```typescript +// Current (provable) +export type TaskStateRecord = Record; + +// NEW (JSON-compatible) +export type TaskStateRecordJson = Record; + +// Converters +export function taskStateRecordToJson(record: TaskStateRecord): TaskStateRecordJson { + return Object.fromEntries( + Object.entries(record).map(([key, fields]) => [ + key, + fields.map(f => f.toString()) + ]) + ); +} + +export function taskStateRecordFromJson(json: TaskStateRecordJson): TaskStateRecord { + return Object.fromEntries( + Object.entries(json).map(([key, strings]) => [ + key, + strings.map(s => Field(s)) + ]) + ); +} +``` + +### Step 3.2: Update `collectStartingState()` in `TransactionTracingService.ts` + +**Current:** +```typescript +export function collectStartingState( + stateTransitions: UntypedStateTransition[] +): TaskStateRecord { + // Returns Record +} +``` + +**Target:** +```typescript +export function collectStartingState( + stateTransitions: UntypedStateTransition[] +): TaskStateRecordJson { + const stateEntries = stateTransitions + .filter(...) + .filter(...) + .map((st) => [st.path.toString(), st.fromValue.value.map(f => f.toString())]); + return Object.fromEntries(stateEntries); +} +``` + +### Step 3.3: Update Task Compute Methods + +**Files:** +- [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) +- [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) + +**In [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) method:** +```typescript +// Convert at boundary +const startingStateBeforeHook = taskStateRecordFromJson(parameters.startingStateBeforeHook); +const startingStateAfterHook = taskStateRecordFromJson(parameters.startingStateAfterHook); + +await executeWithPrefilledStateService( + this.protocol.stateServiceProvider, + [startingStateBeforeHook, startingStateAfterHook], + async () => { /* ... */ } +); +``` + +--- + +## Phase 4: NewBlockProverParameters + +### Step 4.1: Create JSON Interface + +**File:** [packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) + +```typescript +// Current (provable) +export interface NewBlockProverParameters { + publicInput: BlockProverPublicInput; + networkState: NetworkState; + blockWitness: BlockHashMerkleTreeWitness; + deferSTProof: Bool; + afterBlockRootWitness: WitnessedRootWitness; + startingStateBeforeHook: TaskStateRecord; + startingStateAfterHook: TaskStateRecord; +} + +// NEW (JSON-compatible) +export interface NewBlockProverParametersJson { + publicInput: BlockProverPublicInputJson; + networkState: NetworkStateJson; + blockWitness: BlockHashMerkleTreeWitnessJson; + deferSTProof: boolean; + afterBlockRootWitness: WitnessedRootWitnessJson; + startingStateBeforeHook: TaskStateRecordJson; + startingStateAfterHook: TaskStateRecordJson; +} + +// Converters +export function newBlockParamsToJson(params: NewBlockProverParameters): NewBlockProverParametersJson { + return { + publicInput: BlockProverPublicInput.toJSON(params.publicInput), + networkState: NetworkState.toJSON(params.networkState), + blockWitness: BlockHashMerkleTreeWitness.toJSON(params.blockWitness), + deferSTProof: params.deferSTProof.toBoolean(), + afterBlockRootWitness: witnessedRootWitnessToJson(params.afterBlockRootWitness), + startingStateBeforeHook: taskStateRecordToJson(params.startingStateBeforeHook), + startingStateAfterHook: taskStateRecordToJson(params.startingStateAfterHook), + }; +} + +export function newBlockParamsFromJson(json: NewBlockProverParametersJson): NewBlockProverParameters { + return { + publicInput: BlockProverPublicInput.fromJSON(json.publicInput), + networkState: new NetworkState(NetworkState.fromJSON(json.networkState)), + blockWitness: new BlockHashMerkleTreeWitness( + BlockHashMerkleTreeWitness.fromJSON(json.blockWitness) + ), + deferSTProof: Bool(json.deferSTProof), + afterBlockRootWitness: witnessedRootWitnessFromJson(json.afterBlockRootWitness), + startingStateBeforeHook: taskStateRecordFromJson(json.startingStateBeforeHook), + startingStateAfterHook: taskStateRecordFromJson(json.startingStateAfterHook), + }; +} +``` + +### Step 4.2: Update [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) + +Change [traceBlock()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:57:2-162:3) to return JSON types: + +**Current:** +```typescript +public async traceBlock(...): Promise<[BlockTracingState, BlockTrace]> { + // Returns BlockTrace with provable NewBlockProverParameters +} +``` + +**Target:** +```typescript +public async traceBlock(...): Promise<[BlockTracingState, BlockTraceJson]> { + // Returns BlockTraceJson with NewBlockProverParametersJson +} + +export interface BlockTraceJson { + blockParams: NewBlockProverParametersJson; + transactions: TransactionTraceJson[]; + height: string; +} +``` + +--- + +## Phase 5: Simplify Serializers + +### Step 5.1: Simplify `NewBlockProvingParametersSerializer` + +**File:** [packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts:0:0-0:0) + +**Current (complex):** +```typescript +export class NewBlockProvingParametersSerializer { + constructor( + private readonly stProofSerializer: ProofTaskSerializer<...>, + private readonly blockProofSerializer: ProofTaskSerializer<...> + ) {} + + toJSON(input: NewBlockProvingParameters): string { + // Complex conversion of each field + } + + fromJSON(json: string): NewBlockProvingParameters { + // Complex reconstruction of each field + } +} +``` + +**Target (simple):** +```typescript +export class NewBlockProvingParametersSerializer + implements TaskSerializer { + + // Proofs still need special handling (they contain actual proof data) + constructor( + private readonly stProofSerializer: ProofTaskSerializer<...>, + private readonly blockProofSerializer: ProofTaskSerializer<...> + ) {} + + toJSON(input: NewBlockProvingParametersJson): string { + return JSON.stringify({ + params: input.params, // Already JSON-compatible! + input1: this.stProofSerializer.toJSON(input.input1), + input2: this.blockProofSerializer.toJSON(input.input2), + }); + } + + fromJSON(json: string): NewBlockProvingParametersJson { + const parsed = JSON.parse(json); + return { + params: parsed.params, // Already correct type + input1: this.stProofSerializer.fromJSON(parsed.input1), + input2: this.blockProofSerializer.fromJSON(parsed.input2), + }; + } +} +``` + +> **Note:** Proof objects (`input1`, `input2`) still need special serialization because they contain cryptographic proof data. The simplification is for the parameters, not the proofs. + +### Step 5.2: Repeat for Other Serializers + +Apply the same pattern to: + +| Serializer | Params become JSON | Proofs stay special | +|------------|-------------------|---------------------| +| `TransactionProvingTaskParameterSerializer` | `TransactionProverParameters` → JSON | `DynamicRuntimeProof` stays | +| `RuntimeProofParametersSerializer` | `RuntimeProofParameters` → JSON | N/A (no proofs) | +| `StateTransitionProofParametersSerializer` | `StateTransitionProofParameters` → JSON | Merkle witnesses already JSON | + +--- + +## Phase 6: Simplify Persistence Mappers + +### Step 6.1: [TransactionExecutionResultMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:47:0-91:1) + +**File:** [packages/persistance/src/services/prisma/mappers/TransactionMapper.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:0:0-0:0) + +**Current (maps provable types):** +```typescript +export class TransactionExecutionResultMapper { + mapIn(input: [DBTransactionExecutionResult, DBTransaction]): TransactionExecutionResult { + return { + tx: this.transactionMapper.mapIn(input[1]), + status: Bool(executionResult.status), + hooksStatus: Bool(executionResult.hooksStatus), + // ... + }; + } + + mapOut(input: TransactionExecutionResult): [...] { + return { + status: input.status.toBoolean(), + hooksStatus: input.hooksStatus.toBoolean(), + // ... + }; + } +} +``` + +**Target (trivial - types already match):** +```typescript +export class TransactionExecutionResultMapper { + // Now Block.transactions is TransactionExecutionResultJson[] + // DB stores JSON - types are already compatible! + + mapIn(input: [DBTransactionExecutionResult, DBTransaction]): TransactionExecutionResultJson { + // Just restructure, no type conversion + return { + tx: { + hash: input[1].hash, + methodId: input[1].methodId, + // ... all already strings + }, + status: input[0].status, // Already boolean in DB + hooksStatus: input[0].hooksStatus, + // ... + }; + } + + mapOut(input: TransactionExecutionResultJson): [...] { + // No conversion needed - types match + return [ + { + status: input.status, + hooksStatus: input.hooksStatus, + stateTransitions: input.stateTransitions as Prisma.JsonArray, + events: input.events as Prisma.JsonArray, + // ... + }, + { + hash: input.tx.hash, + methodId: input.tx.methodId, + // ... + } + ]; + } +} +``` + +### Step 6.2: `BlockMapper` + +**Already largely simplified** - just needs `transactions` to be cast: + +```typescript +mapIn(input: PrismaBlock): Block { + return { + // ... + transactions: input.transactions as unknown as TransactionExecutionResultJson[], + // ... + }; +} + +mapOut(input: Block): PrismaBlock { + return { + // ... + transactions: input.transactions as unknown as Prisma.JsonArray, + // ... + }; +} +``` + +--- + +## Phase 7: RuntimeProofParameters + +### Step 7.1: Create JSON Interface + +**File:** [packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts:0:0-0:0) + +```typescript +// Current +export interface RuntimeProofParameters { + tx: PendingTransaction; + networkState: NetworkState; + state: TaskStateRecord; +} + +// NEW +export interface RuntimeProofParametersJson { + tx: PendingTransactionJSONType; + networkState: NetworkStateJson; + state: TaskStateRecordJson; +} + +// Converters +export function runtimeParamsToJson(params: RuntimeProofParameters): RuntimeProofParametersJson { + return { + tx: params.tx.toJSON(), + networkState: NetworkState.toJSON(params.networkState), + state: taskStateRecordToJson(params.state), + }; +} + +export function runtimeParamsFromJson(json: RuntimeProofParametersJson): RuntimeProofParameters { + return { + tx: PendingTransaction.fromJSON(json.tx), + networkState: new NetworkState(NetworkState.fromJSON(json.networkState)), + state: taskStateRecordFromJson(json.state), + }; +} +``` + +### Step 7.2: Update [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) + +```typescript +class RuntimeProvingTask { + // Input type changes to JSON + async compute(input: RuntimeProofParametersJson): Promise { + // Convert at boundary + const params = runtimeParamsFromJson(input); + + // Use provable types for proving + await this.runtime.prove(params.tx, params.networkState, params.state); + + return await this.executionContext.current().result.prove(); + } +} +``` + +--- + +## Phase 8: StateTransitionProofParameters + +### Step 8.1: Create JSON Interface + +**File:** [packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) + +```typescript +// Current +export interface StateTransitionProofParameters { + batch: StateTransitionProvableBatch; + merkleWitnesses: LinkedMerkleTreeWitness[]; + publicInput: StateTransitionProverPublicInput; + batchState: AppliedStateTransitionBatchState; + witnessRoots: { values: Bool[] }; +} + +// NEW +export interface StateTransitionProofParametersJson { + batch: StateTransitionProvableBatchJson; // Need to define this + merkleWitnesses: LinkedMerkleTreeWitnessJson[]; + publicInput: StateTransitionProverPublicInputJson; + batchState: AppliedStateTransitionBatchStateJson; + witnessRoots: { values: boolean[] }; +} +``` + +> This is more complex because `StateTransitionProvableBatch` is a deeply nested provable structure. May need to defer this or create comprehensive converters. + +--- + +## Implementation Order Summary + +``` +Week 1: Foundation +├── Phase 2: BlockTrackers (if needed) +├── Phase 3: TaskStateRecord +│ └── Step 3.1: Types +│ └── Step 3.2: collectStartingState() +│ └── Step 3.3: Update Task compute() +│ +Week 2: Parameters +├── Phase 4: NewBlockProverParameters +│ └── Step 4.1: JSON types + converters +│ └── Step 4.2: Update BlockTracingService +│ +├── Phase 7: RuntimeProofParameters +│ └── Step 7.1: JSON types + converters +│ └── Step 7.2: Update RuntimeProvingTask +│ +Week 3: Serializers & Mappers +├── Phase 5: Simplify Serializers +│ └── Step 5.1: NewBlockProvingParametersSerializer +│ └── Step 5.2: Other serializers +│ +├── Phase 6: Simplify Mappers +│ └── Step 6.1: TransactionExecutionResultMapper +│ └── Step 6.2: BlockMapper +│ +Week 4: Complex Types (Optional) +└── Phase 8: StateTransitionProofParameters + └── Complex nested structures +``` + +--- + +## Verification Checklist + +After each phase, verify: + +- [ ] `npm run build` passes in sequencer package +- [ ] `npm run build` passes in persistance package +- [ ] `npm run build` passes at repo root +- [ ] Existing tests still pass +- [ ] No runtime type errors (if possible to test) + +--- + +Would you like me to start implementing Phase 3 (TaskStateRecord) as the next concrete step? \ No newline at end of file diff --git a/packages/indexer/src/IndexerNotifier.ts b/packages/indexer/src/IndexerNotifier.ts index 38371bebb..dfb3544fc 100644 --- a/packages/indexer/src/IndexerNotifier.ts +++ b/packages/indexer/src/IndexerNotifier.ts @@ -34,10 +34,7 @@ export class IndexerNotifier extends SequencerModule> { const inputSerializer = this.indexBlockTask.inputSerializer(); this.sequencer.events.on("block-metadata-produced", async (block) => { - log.debug( - "Notifiying the indexer about block", - block.block.height - ); + log.debug("Notifiying the indexer about block", block.block.height); const payload = await inputSerializer.toJSON(block); const sequencerId = this.sequencerIdProvider.getSequencerId(); diff --git a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts index d45cfe1e5..9f24d049d 100644 --- a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts +++ b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts @@ -10,7 +10,6 @@ import { jest } from "@jest/globals"; import { Indexer } from "../src/Indexer"; import { GeneratedResolverFactoryGraphqlModule } from "../src"; - log.setLevel("info"); const port = 8081; diff --git a/packages/indexer/test/IndexBlockTask.test.ts b/packages/indexer/test/IndexBlockTask.test.ts index 12f506a39..47213f251 100644 --- a/packages/indexer/test/IndexBlockTask.test.ts +++ b/packages/indexer/test/IndexBlockTask.test.ts @@ -54,8 +54,6 @@ describe("IndexBlockTask", () => { const storage = indexer.resolve("BlockStorage"); const latestBlock = await storage.getLatestBlock(); - expect(latestBlock?.block.hash).toBe( - block.block.hash - ); + expect(latestBlock?.block.hash).toBe(block.block.hash); }); }); diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index fce8274b2..073bc4959 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -141,7 +141,7 @@ async function sendTransactions( const txs = await mempool.getTxs(); console.log( "txs", - txs.map((tx) => tx.nonce.toBigInt()) + txs.map((tx) => tx.nonce) ); return await appChain.produceBlock(); diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 7fe7b3d4f..be0f0ddd7 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -53,9 +53,10 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { if (dbResult === null) { return undefined; } - const transactions = dbResult.transactions.map( - (txresult) => this.transactionResultMapper.mapIn([txresult, txresult.tx]) - ); + const transactions = + dbResult.transactions.map((txresult) => + this.transactionResultMapper.mapIn([txresult, txresult.tx]) + ); return { block: { @@ -221,11 +222,10 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { }); return blocks.map((block, index) => { - const transactions = block.transactions.map( - (txresult) => { + const transactions = + block.transactions.map((txresult) => { return this.transactionResultMapper.mapIn([txresult, txresult.tx]); - } - ); + }); const decodedBlock = this.blockMapper.mapIn(block); decodedBlock.transactions = transactions; diff --git a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts index 65dbb6bc4..623c6c484 100644 --- a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts @@ -1,4 +1,7 @@ -import { MessageStorage, PendingTransactionJSONType } from "@proto-kit/sequencer"; +import { + MessageStorage, + PendingTransactionJSONType, +} from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; import type { PrismaConnection } from "../../PrismaDatabaseConnection"; diff --git a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts index 05dbcce15..00411b2ac 100644 --- a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts @@ -1,6 +1,5 @@ import { inject, injectable } from "tsyringe"; import { - PendingTransaction, PendingTransactionJSONType, trace, Tracer, @@ -20,7 +19,9 @@ export class PrismaTransactionStorage implements TransactionStorage { ) {} @trace("db.txs.get") - public async getPendingUserTransactions(): Promise { + public async getPendingUserTransactions(): Promise< + PendingTransactionJSONType[] + > { const { prismaClient } = this.connection; const txs = await prismaClient.transaction.findMany({ @@ -52,7 +53,9 @@ export class PrismaTransactionStorage implements TransactionStorage { } } - public async pushUserTransaction(tx: PendingTransactionJSONType): Promise { + public async pushUserTransaction( + tx: PendingTransactionJSONType + ): Promise { const { prismaClient } = this.connection; const result = await prismaClient.transaction.createMany({ diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index 30fbb3e0b..d13fddbf4 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,9 +1,5 @@ import { singleton } from "tsyringe"; -import { - Block, - UntypedStateTransition, - UntypedStateTransitionJson, -} from "@proto-kit/sequencer"; +import { Block, UntypedStateTransitionJson } from "@proto-kit/sequencer"; import { Prisma, Block as PrismaBlock } from "@prisma/client"; import { NetworkStateJson } from "@proto-kit/protocol"; @@ -22,14 +18,8 @@ export class BlockMapper implements ObjectMapper { transactions: [], networkState: { - before: - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - input.beforeNetworkState as NetworkStateJson - , - during: - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - input.duringNetworkState as NetworkStateJson - + before: input.beforeNetworkState as NetworkStateJson, + during: input.duringNetworkState as NetworkStateJson, }, hash: input.hash, @@ -46,7 +36,8 @@ export class BlockMapper implements ObjectMapper { input.parentHash !== null ? input.parentHash : undefined, // This is cleaner to keep mapIn - beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as UntypedStateTransitionJson[] + beforeBlockStateTransitions: + input.beforeBlockStateTransitions as unknown as UntypedStateTransitionJson[], }; } @@ -67,7 +58,8 @@ export class BlockMapper implements ObjectMapper { parentHash: input.previousBlockHash ?? null, batchHeight: null, - beforeBlockStateTransitions: input.beforeBlockStateTransitions as unknown as Prisma.JsonArray + beforeBlockStateTransitions: + input.beforeBlockStateTransitions as unknown as Prisma.JsonArray, }; } } diff --git a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts index 1c31c974b..d8afc7d6c 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts @@ -1,5 +1,5 @@ import { singleton } from "tsyringe"; -import { BlockResult, UntypedStateTransition } from "@proto-kit/sequencer"; +import { BlockResult } from "@proto-kit/sequencer"; import { BlockResult as DBBlockResult, Prisma } from "@prisma/client"; import { BlockHashMerkleTreeWitnessJson, @@ -43,7 +43,8 @@ export class BlockResultMapper blockHashRoot: input.blockHashRoot.toString(), blockHashWitness: input.blockHashWitness, - afterBlockStateTransitions: input.afterBlockStateTransitions as unknown as Prisma.JsonArray, + afterBlockStateTransitions: + input.afterBlockStateTransitions as unknown as Prisma.JsonArray, afterNetworkState: input.afterNetworkState, witnessedRoots: [input.witnessedRoots[0].toString()], diff --git a/packages/persistance/src/services/prisma/mappers/EventMapper.ts b/packages/persistance/src/services/prisma/mappers/EventMapper.ts index 6f329c4b7..c80e7f6a6 100644 --- a/packages/persistance/src/services/prisma/mappers/EventMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/EventMapper.ts @@ -10,7 +10,9 @@ type EventDataJson = { }; @singleton() -export class EventMapper implements ObjectMapper { +export class EventMapper + implements ObjectMapper +{ public mapIn(input: Prisma.JsonObject): EventDataJson { return { eventName: input.eventName as string, @@ -64,4 +66,3 @@ export class EventArrayMapper ) as Prisma.JsonArray; } } - diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index 2dc05947b..2800427ff 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -12,7 +12,7 @@ export class StateTransitionMapper implements ObjectMapper { public mapIn(input: Prisma.JsonObject): UntypedStateTransitionJson { - // + // return input as unknown as UntypedStateTransitionJson; } @@ -29,7 +29,9 @@ export class StateTransitionArrayMapper { public constructor(private readonly stMapper: StateTransitionMapper) {} - public mapIn(input: Prisma.JsonValue | undefined): UntypedStateTransitionJson[] { + public mapIn( + input: Prisma.JsonValue | undefined + ): UntypedStateTransitionJson[] { if (input === undefined) return []; if (Array.isArray(input)) { diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index b234cc7a3..2867aed66 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -1,6 +1,5 @@ import { singleton, injectable } from "tsyringe"; import { - PendingTransaction, TransactionExecutionResultJson, PendingTransactionJSONType, } from "@proto-kit/sequencer"; diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index a3beb6c0f..52481d05a 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -2,7 +2,6 @@ import "reflect-metadata"; import { afterAll, beforeAll, describe, expect } from "@jest/globals"; import { expectDefined, log } from "@proto-kit/common"; import { BalancesKey, TokenId } from "@proto-kit/library"; -import { NetworkState } from "@proto-kit/protocol"; import { AppChainTransaction } from "@proto-kit/sdk"; import { Block, Batch } from "@proto-kit/sequencer"; import { PrivateKey, PublicKey } from "o1js"; @@ -101,9 +100,7 @@ describe("prisma integration", () => { block.transactions[0].tx.hash ); - expect(retrievedBlock.hash).toStrictEqual( - block.hash - ); + expect(retrievedBlock.hash).toStrictEqual(block.hash); // Check that events match expect(retrievedBlock.transactions[0].events).toHaveLength(1); @@ -115,8 +112,8 @@ describe("prisma integration", () => { block.networkState.before ); expect(retrievedBlock.networkState.during).toStrictEqual( - block.networkState.during) - + block.networkState.during + ); }); it("should save and retrieve the same batch", async () => { diff --git a/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts b/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts index b40f18fa8..9011686e4 100644 --- a/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts +++ b/packages/protocol/src/prover/block/accummulators/BlockHashMerkleTree.ts @@ -1,11 +1,5 @@ import { createMerkleTree } from "@proto-kit/common"; -import { - Bool, - Field, - InferJson, - Poseidon, - Struct, -} from "o1js"; +import { Bool, Field, InferJson, Poseidon, Struct } from "o1js"; export class BlockHashMerkleTree extends createMerkleTree(40) {} export class BlockHashMerkleTreeWitness extends BlockHashMerkleTree.WITNESS {} @@ -28,4 +22,6 @@ export class BlockHashTreeEntry extends Struct({ return Poseidon.hash([blockHash, ...this.closed.toFields()]); } } -export type BlockHashMerkleTreeWitnessJson = InferJson; +export type BlockHashMerkleTreeWitnessJson = InferJson< + typeof BlockHashMerkleTreeWitness +>; diff --git a/packages/protocol/src/utils/utils.ts b/packages/protocol/src/utils/utils.ts index 213500684..661477742 100644 --- a/packages/protocol/src/utils/utils.ts +++ b/packages/protocol/src/utils/utils.ts @@ -1,5 +1,6 @@ import { Bool, Field, Poseidon, Provable } from "o1js"; import floor from "lodash/floor"; + import { NetworkStateJson } from "../model/network/NetworkState"; export type ReturnType = FunctionType extends ( diff --git a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts index a38645d41..17b690c74 100644 --- a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts @@ -57,7 +57,7 @@ export class GraphqlNetworkStateTransportModule } try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return json as NetworkStateJson; } catch (e) { if (e instanceof Error) { diff --git a/packages/sdk/src/graphql/GraphqlTransactionSender.ts b/packages/sdk/src/graphql/GraphqlTransactionSender.ts index 6345816d2..d1e649cc7 100644 --- a/packages/sdk/src/graphql/GraphqlTransactionSender.ts +++ b/packages/sdk/src/graphql/GraphqlTransactionSender.ts @@ -1,5 +1,8 @@ import { inject, injectable } from "tsyringe"; -import { PendingTransaction, AppChainModule, PendingTransactionJSONType } from "@proto-kit/sequencer"; +import { + AppChainModule, + PendingTransactionJSONType, +} from "@proto-kit/sequencer"; import { gql } from "@urql/core"; import { TransactionSender } from "../transaction/InMemoryTransactionSender"; diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index f1edb9e24..a5fcec1d3 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -6,7 +6,7 @@ import { BatchStorage, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkState, NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkStateJson } from "@proto-kit/protocol"; import { ModuleContainerLike } from "@proto-kit/common"; @injectable() @@ -37,7 +37,9 @@ export class BlockStorageNetworkStateModule ); } - public async getUnprovenNetworkState(): Promise { + public async getUnprovenNetworkState(): Promise< + NetworkStateJson | undefined + > { const latestBlock = await this.unprovenStorage.getLatestBlock(); return latestBlock?.block.networkState.during; } diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index d1356b250..96915fe8a 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -10,7 +10,6 @@ import { InclusionStatus, } from "@proto-kit/sequencer"; import { ModuleContainerLike } from "@proto-kit/common"; -import { Field } from "o1js"; @injectable() export class InMemoryBlockExplorer @@ -81,7 +80,10 @@ export class InMemoryBlockExplorer return { hash: block.hash, - previousBlockHash: block.previousBlockHash!==undefined ? block.previousBlockHash: undefined, + previousBlockHash: + block.previousBlockHash !== undefined + ? block.previousBlockHash + : undefined, height: block.height, transactions: clientTransactions, transactionsHash: block.transactionsHash, diff --git a/packages/sdk/src/transaction/InMemoryTransactionSender.ts b/packages/sdk/src/transaction/InMemoryTransactionSender.ts index 7e77dbf24..96dc1ae69 100644 --- a/packages/sdk/src/transaction/InMemoryTransactionSender.ts +++ b/packages/sdk/src/transaction/InMemoryTransactionSender.ts @@ -1,6 +1,5 @@ import { PrivateMempool, - PendingTransaction, AppChainModule, PendingTransactionJSONType, } from "@proto-kit/sequencer"; diff --git a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts index 1c99198ce..61c1c2538 100644 --- a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts +++ b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts @@ -1,5 +1,3 @@ -import { Field } from "o1js"; - export interface ClientTransaction { tx: { hash: string; diff --git a/packages/sequencer/src/helpers/utils.ts b/packages/sequencer/src/helpers/utils.ts index a1dc946f7..e57c3db1e 100644 --- a/packages/sequencer/src/helpers/utils.ts +++ b/packages/sequencer/src/helpers/utils.ts @@ -200,8 +200,11 @@ export class PairProofTaskSerializer */ export type FieldString = string; /** - * + * * @param value Value to be converted to {@link Field}. - * @returns + * @returns */ -export const FieldString = (value: number | string | bigint | Field): FieldString => String(value); +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const FieldString = ( + value: number | string | bigint | Field +): FieldString => String(value); diff --git a/packages/sequencer/src/mempool/Mempool.ts b/packages/sequencer/src/mempool/Mempool.ts index 3f679d59e..028bdf377 100644 --- a/packages/sequencer/src/mempool/Mempool.ts +++ b/packages/sequencer/src/mempool/Mempool.ts @@ -1,6 +1,9 @@ import { EventEmittingComponent } from "@proto-kit/common"; -import type { PendingTransaction, PendingTransactionJSONType } from "./PendingTransaction"; +import type { + PendingTransaction, + PendingTransactionJSONType, +} from "./PendingTransaction"; export type MempoolEvents = { "mempool-transaction-added": [PendingTransaction]; diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 482e5cb8f..fcdaf12da 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -20,7 +20,10 @@ import { import { Field } from "o1js"; import type { Mempool, MempoolEvents } from "../Mempool"; -import { PendingTransaction, PendingTransactionJSONType } from "../PendingTransaction"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../PendingTransaction"; import { sequencerModule, SequencerModule, @@ -79,12 +82,13 @@ export class PrivateMempool if (txValid) { const success = await this.transactionStorage.pushUserTransaction(tx); if (success) { - this.events.emit("mempool-transaction-added", PendingTransaction.fromJSON(tx)); + this.events.emit( + "mempool-transaction-added", + PendingTransaction.fromJSON(tx) + ); log.trace(`Transaction added to mempool: ${tx.hash}`); } else { - log.error( - `Transaction ${tx.hash} rejected: already exists in mempool` - ); + log.error(`Transaction ${tx.hash} rejected: already exists in mempool`); } return success; @@ -126,9 +130,8 @@ export class PrivateMempool // Should provide NetworkState to checkTxValid. const stagedNetworkState = await this.getStagedNetworkState(); - const networkState = stagedNetworkState - ? stagedNetworkState - : NetworkState.toJSON(NetworkState.empty()); + const networkState = + stagedNetworkState || NetworkState.toJSON(NetworkState.empty()); const validationEnabled = this.config.validationEnabled ?? false; const sortedTxs = validationEnabled @@ -196,7 +199,7 @@ export class PrivateMempool const provableNetworkState = new NetworkState( NetworkState.fromJSON(networkState) ); - + let pendingTransaction: PendingTransaction; while ( @@ -254,10 +257,7 @@ export class PrivateMempool }); if (removeTxWhen) { // eslint-disable-next-line no-await-in-loop - await this.transactionStorage.removeTx( - [tx.hash], - "dropped" - ); + await this.transactionStorage.removeTx([tx.hash], "dropped"); log.trace( `Deleting tx ${tx.hash} from mempool because removeTransactionWhen condition is satisfied` ); @@ -265,9 +265,7 @@ export class PrivateMempool continue; } - log.trace( - `Skipped tx ${tx.hash} because ${statusMessage}` - ); + log.trace(`Skipped tx ${tx.hash} because ${statusMessage}`); if (!(tx.hash in skippedTransactions)) { skippedTransactions[tx.hash] = { transaction: tx, diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index 29aa2e2de..665b99511 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -5,7 +5,10 @@ import { RuntimeModulesRecord, } from "@proto-kit/module"; -import { PendingTransaction, PendingTransactionJSONType } from "../PendingTransaction"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../PendingTransaction"; @injectable() export class TransactionValidator { @@ -38,7 +41,9 @@ export class TransactionValidator { return undefined; } - public validateTx(tx: PendingTransactionJSONType): [boolean, string | undefined] { + public validateTx( + tx: PendingTransactionJSONType + ): [boolean, string | undefined] { const methodError = this.validateMethod(tx); if (methodError !== undefined) { diff --git a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts index 509641a2f..cc256a25a 100644 --- a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts +++ b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts @@ -7,7 +7,7 @@ import { sequencerModule, } from "../../sequencer/builder/SequencerModule"; import { IncomingMessageAdapter } from "../../settlement/messages/IncomingMessageAdapter"; -import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { OutgoingMessageAdapter } from "../../settlement/messages/outgoing/OutgoingMessageCollector"; import { Block } from "../../storage/model/Block"; diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index ecd433cde..36d72332f 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -3,19 +3,19 @@ import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; -export interface UntypedStateTransitionJson{ - path: string, - from:{ +export interface UntypedStateTransitionJson { + path: string; + from: { isSome: boolean; isForcedSome: boolean; value: string[]; - }, + }; to: { isSome: boolean; isForcedSome: boolean; value: string[]; - } -}; + }; +} /** * Generic state transition that constraints the current method circuit diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 38986f3ca..3f15e0366 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -86,18 +86,16 @@ export class BlockProducerModule extends SequencerModule { log.info("---------------------------------------"); log.info(`Transaction #${i}`); - log.info( - "Sender:", - tx.tx.sender, - "Nonce:", - tx.tx.nonce - ); + log.info("Sender:", tx.tx.sender, "Nonce:", tx.tx.nonce); log.info(`Method: ${methodName?.join(".")}`); log.info(); if (log.getLevel() <= log.levels.INFO) { Provable.log( "Arguments:", - paramEncoder.decode(tx.tx.argsFields.map((s) => Field(s)), tx.tx.auxiliaryData) + paramEncoder.decode( + tx.tx.argsFields.map((s) => Field(s)), + tx.tx.auxiliaryData + ) ); } log.info( diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 68483da0f..f342cfa08 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -124,7 +124,9 @@ export class BlockProductionService { Field(lastBlock.toEternalTransactionsHash) ), transactionList: new TransactionHashList(), - incomingMessages: new MinaActionsHashList(Field(lastBlock.toMessagesHash)), + incomingMessages: new MinaActionsHashList( + Field(lastBlock.toMessagesHash) + ), }; // Get used networkState by executing beforeBlock() hooks @@ -150,7 +152,9 @@ export class BlockProductionService { ); const previousBlockHash = - lastResult.blockHash === "0" ? undefined : FieldString(lastResult.blockHash); + lastResult.blockHash === "0" + ? undefined + : FieldString(lastResult.blockHash); if (executionResults.length === 0 && !allowEmptyBlocks) { log.info( @@ -167,10 +171,13 @@ export class BlockProductionService { transactions: includedTransactions, transactionsHash: FieldString(newBlockState.transactionList.commitment), fromEternalTransactionsHash: lastBlock.toEternalTransactionsHash, - toEternalTransactionsHash: - FieldString(newBlockState.eternalTransactionsList.commitment), + toEternalTransactionsHash: FieldString( + newBlockState.eternalTransactionsList.commitment + ), height: - FieldString(lastBlock.hash) !== "0" ? FieldString(BigInt(lastBlock.height) + 1n) : FieldString(0), + FieldString(lastBlock.hash) !== "0" + ? FieldString(BigInt(lastBlock.height) + 1n) + : FieldString(0), fromBlockHashRoot: FieldString(lastResult.blockHashRoot), fromMessagesHash: lastBlock.toMessagesHash, fromStateRoot: FieldString(lastResult.stateRoot), @@ -191,9 +198,8 @@ export class BlockProductionService { const includedTxs = executionResults.map((x) => { const txHash = match(x) .with({ status: "included" }, ({ result }) => result.tx) - .otherwise(({ tx }) => tx) - .hash; - + .otherwise(({ tx }) => tx).hash; + return { hash: txHash, type: x.status, diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 8de3098dd..b598a2a46 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -33,9 +33,9 @@ import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; import { AsyncLinkedLeafStore } from "../../../state/async/AsyncLinkedLeafStore"; import { CachedLinkedLeafStore } from "../../../state/lmt/CachedLinkedLeafStore"; +import { FieldString } from "../../../helpers/utils"; import { executeWithExecutionContext } from "./TransactionExecutionService"; -import { FieldString } from "../../../helpers/utils"; // This is ordered, because javascript maintains the order based on time of first insertion function collectOrderedStateDiff( @@ -58,8 +58,8 @@ function createCombinedOrderedStateDiff( .map((tx) => { const transitions = tx.stateTransitions .filter(({ applied }) => applied) - .flatMap(({ stateTransitions }) => - stateTransitions.map(st => UntypedStateTransition.fromJSON(st)) + .flatMap(({ stateTransitions }) => + stateTransitions.map((st) => UntypedStateTransition.fromJSON(st)) ); transitions.push(...blockHookSTs); diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index afd82765c..6fc269896 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -36,11 +36,13 @@ import { // eslint-disable-next-line import/no-extraneous-dependencies import zip from "lodash/zip"; -import { PendingTransaction, PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../../../mempool/PendingTransaction"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { StateTransitionBatch, - TransactionExecutionResult, TransactionExecutionResultJson, STBatchToJson, } from "../../../storage/model/Block"; @@ -106,7 +108,10 @@ async function decodeTransaction( module, methodName ); - const args = await parameterDecoder.decode(tx.argsFields.map(Field), tx.auxiliaryData); + const args = await parameterDecoder.decode( + tx.argsFields.map(Field), + tx.auxiliaryData + ); return { method, @@ -320,7 +325,8 @@ export class TransactionExecutionService { state: BlockTrackers, tx: PendingTransactionJSONType ): BlockTrackers { - const signedTransaction = PendingTransaction.fromJSON(tx).toProtocolTransaction(); + const signedTransaction = + PendingTransaction.fromJSON(tx).toProtocolTransaction(); // Add tx to commitments return this.blockProver.addTransactionToBundle( state, @@ -361,10 +367,7 @@ export class TransactionExecutionService { // If the hooks fail AND the tx is not a message (in which case we // have to still execute it), we skip this tx and don't add it to the block - if ( - !executionTrace.hooksStatus && - !executionTrace.tx.isMessage - ) { + if (!executionTrace.hooksStatus && !executionTrace.tx.isMessage) { const actionMessage = shouldRemove ? "removing as to removeWhen hooks" : "skipping"; @@ -420,7 +423,10 @@ export class TransactionExecutionService { }: { networkState: NetworkState; hash: Field }, state: BlockTrackers, newState: BlockTrackers - ): Promise<{ result: TransactionExecutionResultJson; shouldRemove: boolean }> { + ): Promise<{ + result: TransactionExecutionResultJson; + shouldRemove: boolean; + }> { // TODO Use RecordingStateService -> async asProver needed const recordingStateService = new CachedStateService(asyncStateService); @@ -432,7 +438,8 @@ export class TransactionExecutionService { const previousProofsEnabled = appChain.areProofsEnabled; appChain.setProofsEnabled(false); - const signedTransaction = PendingTransaction.fromJSON(tx).toProtocolTransaction(); + const signedTransaction = + PendingTransaction.fromJSON(tx).toProtocolTransaction(); const runtimeContextInputs = { transaction: signedTransaction.transaction, networkState, @@ -554,11 +561,13 @@ export class TransactionExecutionService { runtimeResult.statusMessage, stateTransitions: stateTransitions.map(STBatchToJson), - events: beforeHookEvents.concat(runtimeResultEvents, afterHookEvents).map(e => ({ - eventName: e.eventName, - data: e.data.map(f => f.toString()), - source: e.source, - })), + events: beforeHookEvents + .concat(runtimeResultEvents, afterHookEvents) + .map((e) => ({ + eventName: e.eventName, + data: e.data.map((f) => f.toString()), + source: e.source, + })), }, shouldRemove, }; diff --git a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts index 5a7bf61df..5d9d50104 100644 --- a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts @@ -21,7 +21,10 @@ import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PairingDerivedInput } from "../flow/ReductionTaskFlow"; -import { TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; +import { + TaskStateRecordJson, + taskStateRecordFromJson, +} from "../tracing/BlockTracingService"; import { NewBlockProvingParametersSerializer } from "./serializers/NewBlockProvingParametersSerializer"; import { executeWithPrefilledStateService } from "./TransactionProvingTask"; @@ -111,8 +114,12 @@ export class NewBlockTask ); // Convert from JSON to provable types at the proving boundary - const startingStateBeforeHookProvable = taskStateRecordFromJson(startingStateBeforeHook); - const startingStateAfterHookProvable = taskStateRecordFromJson(startingStateAfterHook); + const startingStateBeforeHookProvable = taskStateRecordFromJson( + startingStateBeforeHook + ); + const startingStateAfterHookProvable = taskStateRecordFromJson( + startingStateAfterHook + ); await executeWithPrefilledStateService( this.protocol.stateServiceProvider, diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 9bf070de5..0141301ee 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -17,8 +17,15 @@ import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; -import { PendingTransaction, PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; -import { TaskStateRecord, TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../../../mempool/PendingTransaction"; +import { + TaskStateRecord, + TaskStateRecordJson, + taskStateRecordFromJson, +} from "../tracing/BlockTracingService"; import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; @@ -63,10 +70,14 @@ export class RuntimeProvingTask return new ProofTaskSerializer(this.runtimeZkProgrammable[0].Proof); } - public async compute(input: RuntimeProofParametersJson): Promise { + public async compute( + input: RuntimeProofParametersJson + ): Promise { // Convert from JSON to provable types at the proving boundary const tx = PendingTransaction.fromJSON(input.tx); - const networkState = new NetworkState(NetworkState.fromJSON(input.networkState)); + const networkState = new NetworkState( + NetworkState.fromJSON(input.networkState) + ); const state = taskStateRecordFromJson(input.state); const method = this.runtime.getMethodById(tx.methodId.toString()); diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index 0882cc9e1..999549d79 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -18,7 +18,10 @@ import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskSerializer, Task } from "../../../worker/flow/Task"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; -import { TaskStateRecord, TaskStateRecordJson, taskStateRecordFromJson } from "../tracing/BlockTracingService"; +import { + TaskStateRecord, + taskStateRecordFromJson, +} from "../tracing/BlockTracingService"; import { TransactionProvingTaskParameterSerializer } from "./serializers/TransactionProvingTaskParameterSerializer"; import { @@ -93,8 +96,9 @@ export class TransactionProvingTask public async compute( input: TransactionProvingTaskParameters ): Promise { - - const startingStateProvable = input.parameters.startingState.map(taskStateRecordFromJson); + const startingStateProvable = input.parameters.startingState.map( + taskStateRecordFromJson + ); await executeWithPrefilledStateService( this.protocol.stateServiceProvider, diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts index 6b13b4687..d9494b638 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts @@ -32,7 +32,6 @@ interface JsonType { }; } - type NewBlockPayload = PairingDerivedInput< StateTransitionProof, BlockProof, @@ -69,7 +68,8 @@ export class NewBlockProvingParametersSerializer startingStateBeforeHook: input.params.startingStateBeforeHook, - startingStateAfterHook: input.params.startingStateAfterHook, deferSTProof: input.params.deferSTProof.toBoolean(), + startingStateAfterHook: input.params.startingStateAfterHook, + deferSTProof: input.params.deferSTProof.toBoolean(), afterBlockRootWitness: WitnessedRootWitness.toJSON( input.params.afterBlockRootWitness diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts index 1607841ef..73fee13c6 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts @@ -13,7 +13,7 @@ export class RuntimeProofParametersSerializer } public fromJSON(json: string): RuntimeProofParametersJson { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return JSON.parse(json) as RuntimeProofParametersJson; } } - diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts index 792f6fb2d..808bf57ed 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts @@ -18,7 +18,6 @@ import { } from "./types/TransactionProvingTypes"; import { RuntimeVerificationKeyAttestationSerializer } from "./RuntimeVerificationKeyAttestationSerializer"; - export type BlockProverTransactionArgumentsJSON = { transaction: ReturnType; signature: ReturnType; diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts index 3da24d473..ac4c72375 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts @@ -25,7 +25,6 @@ export interface TransactionProverTaskParameters< startingState: TaskStateRecordJson[]; } - export type TransactionProvingTaskParameters = | { type: TransactionProvingType.SINGLE; diff --git a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts index 10bfca965..8b04a8fb6 100644 --- a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts @@ -7,6 +7,7 @@ import { WitnessedRootHashList, } from "@proto-kit/protocol"; import { inject, injectable } from "tsyringe"; +import { Field } from "o1js"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { BlockWithResult } from "../../../storage/model/Block"; @@ -20,7 +21,6 @@ import { BlockTracingState, } from "./BlockTracingService"; import { StateTransitionTracingService } from "./StateTransitionTracingService"; -import { Field } from "o1js"; type BatchTracingState = Omit; @@ -46,8 +46,12 @@ export class BatchTracingService { eternalTransactionsList: new TransactionHashList( Field(block.block.fromEternalTransactionsHash) ), - incomingMessages: new MinaActionsHashList(Field(block.block.fromMessagesHash)), - networkState: new NetworkState(NetworkState.fromJSON(block.block.networkState.before)), + incomingMessages: new MinaActionsHashList( + Field(block.block.fromMessagesHash) + ), + networkState: new NetworkState( + NetworkState.fromJSON(block.block.networkState.before) + ), }; } diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 26afc53aa..0974ab3c1 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -12,36 +12,48 @@ import { yieldSequential } from "@proto-kit/common"; import chunk from "lodash/chunk"; import { inject, injectable } from "tsyringe"; -import { BlockWithResult, txResultFromJson } from "../../../storage/model/Block"; +import { BlockWithResult } from "../../../storage/model/Block"; import type { NewBlockProverParameters } from "../tasks/NewBlockTask"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; +import { + UntypedStateTransition, + UntypedStateTransitionJson, +} from "../helpers/UntypedStateTransition"; import { collectStartingState, TransactionTrace, TransactionTracingService, } from "./TransactionTracingService"; -import { UntypedStateTransition, UntypedStateTransitionJson } from "../helpers/UntypedStateTransition"; export type TaskStateRecord = Record; export type TaskStateRecordJson = Record; -export function taskStateRecordToJson(record: TaskStateRecord): TaskStateRecordJson { +export function taskStateRecordToJson( + record: TaskStateRecord +): TaskStateRecordJson { return Object.fromEntries( - Object.entries(record).map(([key, fields]) => [key, fields.map(f => f.toString())]) + Object.entries(record).map(([key, fields]) => [ + key, + fields.map((f) => f.toString()), + ]) ); } -export function taskStateRecordFromJson(json: TaskStateRecordJson): TaskStateRecord { +export function taskStateRecordFromJson( + json: TaskStateRecordJson +): TaskStateRecord { return Object.fromEntries( - Object.entries(json).map(([key, strings]) => [key, strings.map(s => Field(s))]) + Object.entries(json).map(([key, strings]) => [ + key, + strings.map((s) => Field(s)), + ]) ); } export type BlockTracingState = Pick< - BlockProverState, | "witnessedRoots" | "stateRoot" @@ -90,14 +102,16 @@ export class BlockTracingService { }); const startingStateBeforeHook = collectStartingState( - block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) + block.block.beforeBlockStateTransitions.map( + (st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) + ) ); const blockTrace = { publicInput, networkState: new NetworkState( NetworkState.fromJSON(block.block.networkState.before) - ) , + ), deferSTProof: Bool(!includeSTProof), blockWitness: new BlockHashMerkleTreeWitness( BlockHashMerkleTreeWitness.fromJSON(block.result.blockHashWitness) @@ -107,13 +121,16 @@ export class BlockTracingService { state.pendingSTBatches.push({ batchHash: toStateTransitionsHash( - block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) + block.block.beforeBlockStateTransitions.map( + (st: UntypedStateTransitionJson) => + UntypedStateTransition.fromJSON(st) + ) ), applied: Bool(true), }); state.networkState = new NetworkState( - NetworkState.fromJSON(block.block.networkState.during) - ) ; + NetworkState.fromJSON(block.block.networkState.during) + ); const [afterState, transactionTraces] = await yieldSequential( chunk(block.block.transactions, 2), @@ -157,11 +174,13 @@ export class BlockTracingService { } const startingStateAfterHook = collectStartingState( - block.result.afterBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)) + block.result.afterBlockStateTransitions.map( + (st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) + ) ); state.networkState = new NetworkState( - NetworkState.fromJSON(block.result.afterNetworkState) - ); + NetworkState.fromJSON(block.result.afterNetworkState) + ); return [ afterState, diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index 2242cb045..a7517f7bd 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -18,7 +18,10 @@ import { import { distinctByString } from "../../../helpers/utils"; import { BlockWithResult } from "../../../storage/model/Block"; -import { UntypedStateTransition, UntypedStateTransitionJson } from "../helpers/UntypedStateTransition"; +import { + UntypedStateTransition, + UntypedStateTransitionJson, +} from "../helpers/UntypedStateTransition"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; @@ -47,12 +50,17 @@ export class StateTransitionTracingService { return blocks.reduce((previous, block) => { const batches = [ { - stateTransitions: block.block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)), + stateTransitions: block.block.beforeBlockStateTransitions.map( + (st: UntypedStateTransitionJson) => + UntypedStateTransition.fromJSON(st) + ), applied: true, }, - ...block.block.transactions.flatMap((tx) => - tx.stateTransitions.map(batch => ({ - stateTransitions: batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st)), + ...block.block.transactions.flatMap((tx) => + tx.stateTransitions.map((batch) => ({ + stateTransitions: batch.stateTransitions.map((st) => + UntypedStateTransition.fromJSON(st) + ), applied: batch.applied, })) ), @@ -67,7 +75,10 @@ export class StateTransitionTracingService { } return batchBeforeWitnessing.concat({ - stateTransitions: block.result.afterBlockStateTransitions.map((st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st)), + stateTransitions: block.result.afterBlockStateTransitions.map( + (st: UntypedStateTransitionJson) => + UntypedStateTransition.fromJSON(st) + ), applied: true, witnessRoot: false, }); diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index d4e7f9924..416b118aa 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -14,7 +14,10 @@ import { MAX_FIELD } from "@proto-kit/common"; import { toStateTransitionsHash } from "@proto-kit/module"; import { inject, injectable } from "tsyringe"; -import { TransactionExecutionResultJson, STBatchFromJson } from "../../../storage/model/Block"; +import { + TransactionExecutionResultJson, + STBatchFromJson, +} from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; import type { RuntimeProofParametersJson } from "../tasks/RuntimeProvingTask"; import { @@ -24,7 +27,10 @@ import { import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { VerificationKeyService } from "../../runtime/RuntimeVerificationKeyService"; -import type { BlockTracingState, TaskStateRecordJson } from "./BlockTracingService"; +import type { + BlockTracingState, + TaskStateRecordJson, +} from "./BlockTracingService"; export type TransactionTrace = | { @@ -52,12 +58,14 @@ export function collectStartingState( // "state hasn't been set before" and has to correlate to a precondition on Field(0) // and for that the state has to be undefined .filter((st) => st.fromValue.isSome.toBoolean()) - .map((st) => [st.path.toString(), st.fromValue.value.map((f: Field) => f.toString())]); + .map((st) => [ + st.path.toString(), + st.fromValue.value.map((f: Field) => f.toString()), + ]); return Object.fromEntries(stateEntries); } - @injectable() export class TransactionTracingService { private readonly blockProver: BlockProverProgrammable; @@ -105,9 +113,8 @@ export class TransactionTracingService { previousState: BlockTracingState, transaction: TransactionExecutionResultJson ) { - const tx = PendingTransaction.fromJSON(transaction.tx); - + // TODO Remove this call and instead reuse results from sequencing ? const newState = this.blockProver.addTransactionToBundle( previousState, @@ -130,12 +137,11 @@ export class TransactionTracingService { tx: TransactionExecutionResultJson, networkState: NetworkState ): RuntimeProofParametersJson { - const stBatch = STBatchFromJson(tx.stateTransitions[1]); const startingState = collectStartingState(stBatch.stateTransitions); return { - tx: tx.tx, + tx: tx.tx, networkState: NetworkState.toJSON(networkState), state: startingState, }; @@ -146,7 +152,7 @@ export class TransactionTracingService { transaction: TransactionExecutionResultJson ) { const stBatches = transaction.stateTransitions.map(STBatchFromJson); - + const beforeHookStartingState = collectStartingState( stBatches[0].stateTransitions.flat() ); @@ -184,7 +190,9 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction: await this.getTransactionData(PendingTransaction.fromJSON(transaction.tx)), + transaction: await this.getTransactionData( + PendingTransaction.fromJSON(transaction.tx) + ), networkState: previousState.networkState, }, startingState, @@ -223,8 +231,12 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction1: await this.getTransactionData(PendingTransaction.fromJSON(transaction1.tx)), - transaction2: await this.getTransactionData(PendingTransaction.fromJSON(transaction2.tx)), + transaction1: await this.getTransactionData( + PendingTransaction.fromJSON(transaction1.tx) + ), + transaction2: await this.getTransactionData( + PendingTransaction.fromJSON(transaction2.tx) + ), networkState: previousState.networkState, }, startingState: [...startingState1, ...startingState2], diff --git a/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts b/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts index 9f6607b68..62717cc4a 100644 --- a/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts +++ b/packages/sequencer/src/protocol/runtime/RuntimeVerificationKeyService.ts @@ -81,10 +81,10 @@ export class VerificationKeyService extends ConfigurableModule<{}> { methodName ); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return [ - methodId, - new VerificationKey(artifact.verificationKey), - ] as [string, VerificationKey]; + return [methodId, new VerificationKey(artifact.verificationKey)] as [ + string, + VerificationKey, + ]; }); } ); diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 43c724830..ee80e33ff 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -24,7 +24,10 @@ import { SettlementContractModule, } from "@proto-kit/protocol"; -import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../../mempool/PendingTransaction"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; diff --git a/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts index e70fa5035..11f3b0207 100644 --- a/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/outgoing/DefaultOutgoingMessageAdapter.ts @@ -61,7 +61,7 @@ export class DefaultOutgoingMessageAdapter ) .map((event) => { const type = this.outgoingWithdrawalEvents[event.eventName]; - return type.eventType.fromFields(event.data.map(d => Field(d))); + return type.eventType.fromFields(event.data.map((d) => Field(d))); }) ); } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts index 102b53fa0..bc0e53cf6 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts @@ -65,9 +65,7 @@ export class InMemoryBlockStorage implements BlockStorage, BlockQueue { if (latestBatch !== undefined) { cursor = this.blocks.reduce( (c, block, index) => - latestBatch.blockHashes.includes(block.hash) - ? index + 1 - : c, + latestBatch.blockHashes.includes(block.hash) ? index + 1 : c, 0 ); } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts index 8f33605fa..b4f3df4e4 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts @@ -1,6 +1,6 @@ import { injectable } from "tsyringe"; -import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { MessageStorage } from "../repositories/MessageStorage"; @injectable() diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index 6efff1089..a8e85cf9b 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -1,7 +1,7 @@ import { inject, injectable } from "tsyringe"; import { TransactionStorage } from "../repositories/TransactionStorage"; -import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; import { BlockStorage } from "../repositories/BlockStorage"; import { InMemoryBatchStorage } from "./InMemoryBatchStorage"; @@ -21,12 +21,14 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async removeTx(hashes: string[]) { const hashSet = new Set(hashes); this.queue = this.queue.filter((tx) => { - const hash = tx.hash; + const { hash } = tx; return !hashSet.has(hash); }); } - public async getPendingUserTransactions(): Promise { + public async getPendingUserTransactions(): Promise< + PendingTransactionJSONType[] + > { const nextHeight = await this.blockStorage.getCurrentBlockHeight(); for ( let height = this.latestScannedBlock + 1; @@ -37,9 +39,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { const block = await this.blockStorage.getBlockAt(height); if (block !== undefined) { const hashes = block.transactions.map((tx) => tx.tx.hash); - this.queue = this.queue.filter( - (tx) => !hashes.includes(tx.hash) - ); + this.queue = this.queue.filter((tx) => !hashes.includes(tx.hash)); } } this.latestScannedBlock = nextHeight - 1; @@ -47,11 +47,11 @@ export class InMemoryTransactionStorage implements TransactionStorage { return this.queue.slice(); } - public async pushUserTransaction(tx: PendingTransactionJSONType): Promise { + public async pushUserTransaction( + tx: PendingTransactionJSONType + ): Promise { const notInQueue = - this.queue.find( - (tx2) => tx2.hash === tx.hash - ) === undefined; + this.queue.find((tx2) => tx2.hash === tx.hash) === undefined; if (notInQueue) { this.queue.push(tx); } @@ -98,9 +98,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { if (block === undefined) { return undefined; } - const txResult = block.transactions.find((tx) => - tx.tx.hash === hash - ); + const txResult = block.transactions.find((tx) => tx.tx.hash === hash); if (txResult !== undefined) { // eslint-disable-next-line no-await-in-loop const batch = await this.findBatch(block.hash); diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 31ab41c27..6db865573 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -9,7 +9,10 @@ import { } from "@proto-kit/protocol"; import { LinkedMerkleTree } from "@proto-kit/common"; -import { PendingTransaction, PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { + PendingTransaction, + PendingTransactionJSONType, +} from "../../mempool/PendingTransaction"; import { UntypedStateTransition, UntypedStateTransitionJson, @@ -47,7 +50,7 @@ export interface TransactionExecutionResultJson { statusMessage?: string; events: { eventName: string; - data: FieldString[]; + data: FieldString[]; source: "afterTxHook" | "beforeTxHook" | "runtime"; }[]; } @@ -144,7 +147,9 @@ export const BlockWithResult = { stateRoot: String(LinkedMerkleTree.EMPTY_ROOT), blockHashRoot: String(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], - blockHashWitness: BlockHashMerkleTreeWitness.toJSON(BlockHashMerkleTree.WITNESS.dummy()), + blockHashWitness: BlockHashMerkleTreeWitness.toJSON( + BlockHashMerkleTree.WITNESS.dummy() + ), blockHash: "0", witnessedRoots: [String(LinkedMerkleTree.EMPTY_ROOT)], }, @@ -215,5 +220,3 @@ export function STBatchFromJson( applied: stBatch.applied, }; } - - diff --git a/packages/sequencer/test/integration/BlockProduction-test.ts b/packages/sequencer/test/integration/BlockProduction-test.ts index 4ac501375..6c7e6733a 100644 --- a/packages/sequencer/test/integration/BlockProduction-test.ts +++ b/packages/sequencer/test/integration/BlockProduction-test.ts @@ -236,9 +236,7 @@ export function testBlockProduction< expectDefined(latestBlockWithResult); expectDefined(latestBlockWithResult.result); expect( - hashNetworkState( - latestBlockWithResult.result.afterNetworkState - ) + hashNetworkState(latestBlockWithResult.result.afterNetworkState) ).toStrictEqual(hashNetworkState(batch!.toNetworkState)); // Check if the batchstorage has received the block @@ -717,13 +715,17 @@ export function testBlockProduction< }; const firstEventReduced = { eventName: firstExpectedEvent.eventName, - data: firstExpectedEvent.eventType.toFields(firstExpectedEvent.event).map(f => f.toString()), + data: firstExpectedEvent.eventType + .toFields(firstExpectedEvent.event) + .map((f) => f.toString()), source: "runtime", }; const secondEventReduced = { eventName: secondExpectedEvent.eventName, - data: secondExpectedEvent.eventType.toFields(secondExpectedEvent.event).map(f => f.toString()), + data: secondExpectedEvent.eventType + .toFields(secondExpectedEvent.event) + .map((f) => f.toString()), source: "runtime", }; diff --git a/packages/sequencer/test/integration/Mempool.test.ts b/packages/sequencer/test/integration/Mempool.test.ts index 89faa7f2a..5b5b13b8d 100644 --- a/packages/sequencer/test/integration/Mempool.test.ts +++ b/packages/sequencer/test/integration/Mempool.test.ts @@ -242,4 +242,4 @@ describe.each([["InMemory", InMemoryDatabase]])( expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); } -); \ No newline at end of file +); diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 6f1563856..f8479104d 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -37,7 +37,10 @@ function checkStateDiffEquality(stateDiff: StateRecord, state: StateEntry[]) { return value === undefined; } if (value !== undefined) { - return entry.value.find((v, i) => !v.equals(value[i]).toBoolean()) === undefined; + return ( + entry.value.find((v, i) => !v.equals(value[i]).toBoolean()) === + undefined + ); } } return false; @@ -149,9 +152,7 @@ describe.each([["InMemory", InMemoryDatabase]])( const { block } = blocks[0]; - expect(block.hash).toStrictEqual( - generatedBlock.hash - ); + expect(block.hash).toStrictEqual(generatedBlock.hash); const blockStorage = sequencer.resolve("BlockStorage") as BlockStorage; const block2 = await blockStorage.getBlockAt( @@ -159,12 +160,14 @@ describe.each([["InMemory", InMemoryDatabase]])( ); expectDefined(block2); - expect(block2.hash).toStrictEqual( - generatedBlock.hash - ); + expect(block2.hash).toStrictEqual(generatedBlock.hash); const input = block.transactions.flatMap((tx) => - tx.stateTransitions.flatMap((batch) => batch.stateTransitions.map(st => UntypedStateTransition.fromJSON(st))) + tx.stateTransitions.flatMap((batch) => + batch.stateTransitions.map((st) => + UntypedStateTransition.fromJSON(st) + ) ) + ); const stateDiff = collectStateDiff(input); const state = await unprovenState.getMany( diff --git a/packages/sequencer/test/integration/utils.ts b/packages/sequencer/test/integration/utils.ts index ff29d11f0..877391d83 100644 --- a/packages/sequencer/test/integration/utils.ts +++ b/packages/sequencer/test/integration/utils.ts @@ -38,7 +38,9 @@ export function createTransaction(spec: { sender: spec.privateKey.toPublicKey(), nonce: UInt64.from(spec.nonce), isMessage: false, - }).sign(spec.privateKey).toJSON(); + }) + .sign(spec.privateKey) + .toJSON(); } export function collectStateDiff( diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index a8937690d..892f51f44 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -627,9 +627,9 @@ export const settlementTestFn = ( console.log(hashNetworkState(batch!.toNetworkState)); console.log(hashNetworkState(batch2!.fromNetworkState)); - expect( - hashNetworkState(batch!.toNetworkState) - ).toStrictEqual(hashNetworkState(batch2!.fromNetworkState)); + expect(hashNetworkState(batch!.toNetworkState)).toStrictEqual( + hashNetworkState(batch2!.fromNetworkState) + ); expect(batch2!.blockHashes).toHaveLength(1); From 2a37bb7086c6c7d47642876ab42f5154bf6dda28 Mon Sep 17 00:00:00 2001 From: saitunc Date: Thu, 15 Jan 2026 11:26:34 +0300 Subject: [PATCH 30/63] style: run lint fix --- packages/indexer/src/IndexerNotifier.ts | 3 +- .../indexer/src/tasks/IndexPendingTxTask.ts | 10 ++-- .../src/tasks/IndexPendingTxTaskParameters.ts | 6 +-- .../tracing/TransactionTracingService.ts | 1 - .../src/settlement/SettlementModule.ts | 52 ------------------- .../bridging/BridgingSettlementInteraction.ts | 5 +- .../vanilla/VanillaSettlementInteraction.ts | 5 +- .../messages/IncomingMessagesService.ts | 2 - .../test/settlement/Settlement-only.ts | 10 +++- .../sequencer/test/settlement/Settlement.ts | 1 - 10 files changed, 25 insertions(+), 70 deletions(-) diff --git a/packages/indexer/src/IndexerNotifier.ts b/packages/indexer/src/IndexerNotifier.ts index 13ae579db..87d92f578 100644 --- a/packages/indexer/src/IndexerNotifier.ts +++ b/packages/indexer/src/IndexerNotifier.ts @@ -66,7 +66,8 @@ export class IndexerNotifier extends SequencerModule> { const txQueue = await this.taskQueue.getQueue( this.indexPendingTxTask.name ); - const payload = await txInputSerializer.toJSON(tx); + // This part seems weird + const payload = await txInputSerializer.toJSON(tx.toJSON()); const sequencerId = this.sequencerIdProvider.getSequencerId(); const task: TaskPayload = { diff --git a/packages/indexer/src/tasks/IndexPendingTxTask.ts b/packages/indexer/src/tasks/IndexPendingTxTask.ts index db468660d..7583530ec 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTask.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTask.ts @@ -1,5 +1,5 @@ import { - PendingTransaction, + PendingTransactionJSONType, Task, TaskSerializer, TaskWorkerModule, @@ -13,7 +13,7 @@ import { IndexPendingTxTaskParametersSerializer } from "./IndexPendingTxTaskPara @injectable() export class IndexPendingTxTask extends TaskWorkerModule - implements Task + implements Task { public name = "index-pending-tx"; @@ -28,7 +28,9 @@ export class IndexPendingTxTask // eslint-disable-next-line @typescript-eslint/no-empty-function public async prepare(): Promise {} - public async compute(input: PendingTransaction): Promise { + public async compute( + input: PendingTransactionJSONType + ): Promise { try { await this.transactionStorage.pushUserTransaction(input); return ""; @@ -38,7 +40,7 @@ export class IndexPendingTxTask } } - public inputSerializer(): TaskSerializer { + public inputSerializer(): TaskSerializer { return this.taskSerializer; } diff --git a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts b/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts index 5c60be517..f35643347 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts @@ -1,4 +1,4 @@ -import { PendingTransaction } from "@proto-kit/sequencer"; +import { PendingTransactionJSONType } from "@proto-kit/sequencer"; import { TransactionMapper } from "@proto-kit/persistance"; import { injectable } from "tsyringe"; @@ -6,13 +6,13 @@ import { injectable } from "tsyringe"; export class IndexPendingTxTaskParametersSerializer { public constructor(public transactionMapper: TransactionMapper) {} - public toJSON(parameters: PendingTransaction): string { + public toJSON(parameters: PendingTransactionJSONType): string { return JSON.stringify({ tx: this.transactionMapper.mapOut(parameters), }); } - public fromJSON(json: string): PendingTransaction { + public fromJSON(json: string): PendingTransactionJSONType { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const parsed = JSON.parse(json) as { tx: ReturnType; diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 010ef1a54..d7bc60d8a 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -104,7 +104,6 @@ export class TransactionTracingService { previousState: BlockTracingState, transaction: TransactionExecutionResultJson ) { - const tx = PendingTransaction.fromJSON(transaction.tx); // TODO Remove this call and instead reuse results from sequencing const newState = addTransactionToBundle( diff --git a/packages/sequencer/src/settlement/SettlementModule.ts b/packages/sequencer/src/settlement/SettlementModule.ts index 32ece871e..3d9486e05 100644 --- a/packages/sequencer/src/settlement/SettlementModule.ts +++ b/packages/sequencer/src/settlement/SettlementModule.ts @@ -3,9 +3,6 @@ import { SettlementContractModule, MandatorySettlementModulesRecord, MandatoryProtocolModulesRecord, - SettlementSmartContractBase, - DynamicBlockProof, - NetworkState, type SettlementContractType, ContractArgsRegistry, SettlementContractArgs, @@ -150,55 +147,6 @@ export class SettlementModule ): Promise { log.debug("Preparing settlement"); - const lastSettlementL1BlockHeight = - settlementContract.lastSettlementL1BlockHeight.get().value; - const signature = this.signer.sign([ - BATCH_SIGNATURE_PREFIX, - lastSettlementL1BlockHeight, - ]); - - const latestSequenceStateHash = dispatch.account.actionState.get(); - - const blockProof = await this.blockProofSerializer - .getBlockProofSerializer() - .fromJSONProof(batch.proof); - - const dynamicBlockProof = DynamicBlockProof.fromProof(blockProof); - - const tx = await Mina.transaction( - { - sender: feepayer, - nonce: options?.nonce, - fee: this.feeStrategy.getFee(), - memo: "Protokit settle", - }, - async () => { - await settlementContract.settle( - dynamicBlockProof, - signature, - dispatch.address, - feepayer, - new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), - new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), - latestSequenceStateHash - ); - } - ); - - this.utils.signTransaction(tx, { - signingWithSignatureCheck: [...this.signer.getContractAddresses()], - }); - - const { hash: transactionHash } = - await this.transactionSender.proveAndSendTransaction(tx, "included"); - - log.info("Settlement transaction sent and included"); - - const settlement = { - batches: [batch.height], - promisedMessagesHash: latestSequenceStateHash.toString(), - transactionHash, - }; const bridgingModule = this.bridgingModule(); const interaction = bridgingModule !== undefined diff --git a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts index ee8b74983..2349b3b85 100644 --- a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts @@ -5,6 +5,7 @@ import { BridgingSettlementModulesRecord, DynamicBlockProof, MandatoryProtocolModulesRecord, + NetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -101,8 +102,8 @@ export class BridgingSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - batch.fromNetworkState, - batch.toNetworkState, + new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), + new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts index 096438ab5..665f9e7d0 100644 --- a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts @@ -5,6 +5,7 @@ import { BridgingSettlementModulesRecord, DynamicBlockProof, MandatoryProtocolModulesRecord, + NetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -93,8 +94,8 @@ export class VanillaSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - batch.fromNetworkState, - batch.toNetworkState, + new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), + new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts index 9f25ed3ab..3eec0720a 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts @@ -5,8 +5,6 @@ import { SettlementStorage } from "../../storage/repositories/SettlementStorage" import { MessageStorage } from "../../storage/repositories/MessageStorage"; import { BlockStorage } from "../../storage/repositories/BlockStorage"; import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; -import type { SettlementModule } from "../SettlementModule"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; import type { BridgingModule } from "../BridgingModule"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; diff --git a/packages/sequencer/test/settlement/Settlement-only.ts b/packages/sequencer/test/settlement/Settlement-only.ts index c894bfbcf..9ef519695 100644 --- a/packages/sequencer/test/settlement/Settlement-only.ts +++ b/packages/sequencer/test/settlement/Settlement-only.ts @@ -12,6 +12,7 @@ import { import { BlockProverPublicInput, ContractArgsRegistry, + NetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -155,6 +156,7 @@ export const settlementOnlyTestFn = ( async function createBatch( withTransactions: boolean, customNonce: number = 0, + // Why is it like this? txs: PendingTransaction[] = [] ) { const mempool = appChain.sequencer.resolve("Mempool") as PrivateMempool; @@ -171,7 +173,7 @@ export const settlementOnlyTestFn = ( await mempool.add(tx); } await mapSequential(txs, async (tx) => { - await mempool.add(tx); + await mempool.add(tx.toJSON()); }); const result = await trigger.produceBlockAndBatch(); @@ -275,10 +277,14 @@ export const settlementOnlyTestFn = ( address: settlementModule.getSettlementContractAddress(), }); const settlement = settlementModule.getSettlementContract(); + + const afterNetworkState = new NetworkState( + NetworkState.fromJSON(lastBlock!.result?.afterNetworkState!) + ); expectDefined(lastBlock); expectDefined(lastBlock.result); expect(settlement.networkStateHash.get().toString()).toStrictEqual( - lastBlock!.result.afterNetworkState.hash().toString() + afterNetworkState.hash().toString() ); expect(settlement.stateRoot.get().toString()).toStrictEqual( lastBlock!.result.stateRoot.toString() diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index cc1bd7eaf..a071be100 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -15,7 +15,6 @@ import { Protocol, ReturnType, SettlementContractModule, - SettlementSmartContractBase, hashNetworkState, } from "@proto-kit/protocol"; import { From f041a12c42593e279e93eb98a45f6728b566abcf Mon Sep 17 00:00:00 2001 From: chief Date: Thu, 15 Jan 2026 14:06:52 +0300 Subject: [PATCH 31/63] Delete planning file docs: remove mistakenyl pushed file --- Refactor Block Types Persistence.md | 1111 --------------------------- 1 file changed, 1111 deletions(-) delete mode 100644 Refactor Block Types Persistence.md diff --git a/Refactor Block Types Persistence.md b/Refactor Block Types Persistence.md deleted file mode 100644 index ff4ff32ff..000000000 --- a/Refactor Block Types Persistence.md +++ /dev/null @@ -1,1111 +0,0 @@ -# Chat Conversation - -## Block Production Flow: Provable vs Non-Provable - -### Overview Diagram - -``` -┌─────────────────────────────────────────────────────────────────────────────┐ -│ SEQUENCING (Non-Provable) │ -│ BlockProducerModule → BlockProductionService → TransactionExecutionService │ -│ │ -│ - Execute transactions │ -│ - Collect state transitions │ -│ - Create Block (with TransactionExecutionResult) │ -│ - Store to DB │ -└─────────────────────────────────────────────────────────────────────────────┘ - ↓ (Block stored) -┌─────────────────────────────────────────────────────────────────────────────┐ -│ TRACING (Non-Provable) │ -│ BatchProducerModule → BatchTracingService → BlockTracingService │ -│ → StateTransitionTracingService │ -│ → TransactionTracingService │ -│ │ -│ - Collect witnesses (merkle proofs, state values) │ -│ - Prepare inputs for provers │ -│ - Still uses o1js types (Field, Bool) but NOT in-circuit │ -└─────────────────────────────────────────────────────────────────────────────┘ - ↓ (Trace created) -┌─────────────────────────────────────────────────────────────────────────────┐ -│ PROVING (Provable/In-Circuit) │ -│ BatchFlow → StateTransitionFlow → StateTransitionTask.compute() │ -│ → BlockFlow → TransactionProvingTask.compute() │ -│ → NewBlockTask.compute() │ -│ │ -│ ⚡ THIS IS WHERE ZK PROOFS ARE GENERATED ⚡ │ -│ - StateTransitionProver.prove*() methods │ -│ - BlockProver.proveTransaction/proveBlock() methods │ -│ - executionContext.current().result.prove() │ -└─────────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -### Detailed Breakdown - -| Stage | File(s) | Provable? | Description | -|-------|---------|-----------|-------------| -| **1. Sequencing** | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | ❌ No | Executes transactions, creates [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) with `TransactionExecutionResult[]` | -| **2. Block Metadata** | [BlockResultService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts:0:0-0:0) | ❌ No | Generates [BlockResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:128:0-136:1) (state root, merkle witnesses) | -| **3. Tracing** | `BatchTracingService.ts`, [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0), `TransactionTracingService.ts`, [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) | ❌ No | Collects witnesses and prepares prover inputs. Uses `o1js` types but just for data construction, NOT in-circuit | -| **4. Flow Orchestration** | [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0), `BlockFlow.ts`, `StateTransitionFlow.ts` | ❌ No | Orchestrates the proving tasks, manages parallelism | -| **5. PROVING TASKS** | `NewBlockTask.compute()`, `TransactionProvingTask.compute()`, `StateTransitionTask.compute()`, `RuntimeProvingTask.compute()` | ✅ **YES** | **This is where ZK proofs are actually generated!** Calls methods like `blockProver.proveBlock()`, `stateTransitionProver.prove*()` | - ---- - -### Where Provable Code Actually Runs - -The **provable (in-circuit)** code is in the `@proto-kit/protocol` package: - -1. **[BlockProver](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:30:0-38:1)** - Proves block validity - - `proveBlock()` - - `proveTransaction()` - - `proveTransactions()` - -2. **`StateTransitionProver`** - Proves state transition validity - - Various prove methods for merkle tree updates - -3. **`Runtime`** (from `@proto-kit/module`) - Proves runtime method execution - - The actual user-defined runtime methods - -These provers are **ZkPrograms** that run inside the provable context. The [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) method in tasks like [NewBlockTask](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:46:0-130:1) calls these prover methods: - -```typescript -// NewBlockTask.compute() - Line 101-108 -await this.blockProver.proveBlock( - publicInput, - networkState, - blockWitness, - input1, - deferSTProof, - afterBlockRootWitness, - input2 -); - -// Then generate the actual proof -return await this.executionContext.current().result.prove(); -``` - ---- - -### Key Insight for Your Refactoring - -The **sequencing** and **block storage** layers ([Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1), [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1)) don't need provable types because: - -1. They run **before** proving happens -2. The tracing services **convert** from storage types (Json) back to provable types when needed -3. The actual proving happens in **worker tasks** that receive serialized (Json) inputs and deserialize them to provable types - -Your refactoring is correct - using Json types in `Block.transactions` and converting to provable types only in the tracing layer is the right approach! - -### User Input - -Okay. Now, as you've stated, there are provable code in non-provable part, namely in Sequencer and Tracer. I want to refactor them to be non-provable and convert to provable when they are only needed in Proving. - -Create a plan to do changes in steps. - -### Planner Response - -# Refactoring Plan: Non-Provable Types in Sequencer & Tracing Layers - -## Objective - -Refactor the Sequencer and Tracing layers to use **non-provable (JSON-serializable) types** for data storage and intermediate processing, converting to **provable types only at the proving boundary** (when data enters the `*Task.compute()` methods). - ---- - -## Current State Analysis - -### Provable Types Used in Non-Provable Code - -| Type | From | Used In | Impact | -|------|------|---------|--------| -| `Field` | `o1js` | State paths, hashes, commitments | High | -| `Bool` | `o1js` | Transaction status, flags | Medium | -| `UInt64` | `o1js` | Block heights, nonces | Medium | -| `Signature` | `o1js` | Transaction signatures | Medium | -| `PublicKey` | `o1js` | Sender addresses | Medium | -| `NetworkState` (Struct) | `@proto-kit/protocol` | Block network state | High | -| `PendingTransaction` (Class) | Sequencer | Mempool, execution | High - **Already done ✅** | -| [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1) | Sequencer | Block transactions | High - **Already done ✅** | -| `UntypedStateTransition` | Sequencer | State tracking | High - **Partially done** | - ---- - -## Phased Refactoring Plan - -### Phase 1: Complete Current Work (Block & Transaction Types) ✅ -**Status: DONE** - -- [x] [TransactionExecutionResultJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:41:0-52:1) interface -- [x] [StateTransitionBatchJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:36:0-39:1) interface -- [x] [txResultToJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:54:0-70:1) converter -- [x] [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) converter -- [x] Update `Block.transactions` to use `TransactionExecutionResultJson[]` -- [x] Update [BlockProductionService](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:46:0-212:1) to convert on block creation -- [x] Update tracing services to convert back when needed - ---- - -### Phase 2: Trackers & Block State Types -**Goal**: Remove `Field` usage from block production tracking structures - -#### 2.1 `BlockTrackers` in `TransactionExecutionService.ts` - -**Current:** -```typescript -export interface BlockTrackers { - blockHashRoot: Field; - eternalTransactionsList: TransactionHashList; - transactionList: TransactionHashList; - incomingMessages: MinaActionsHashList; -} -``` - -**Target:** -```typescript -export interface BlockTrackersJson { - blockHashRoot: string; - eternalTransactionsHash: string; - transactionsHash: string; - incomingMessagesHash: string; -} -``` - -**Files to change:** -- `TransactionExecutionService.ts` -- [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) - ---- - -### Phase 3: Tracing Service Outputs -**Goal**: Make tracing service outputs JSON-serializable - -#### 3.1 [TaskStateRecord](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:26:0-26:54) Type - -**Current (in [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0)):** -```typescript -export type TaskStateRecord = Record; -``` - -**Target:** -```typescript -export type TaskStateRecordJson = Record; -``` - -**Files to change:** -- [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) -- `TransactionTracingService.ts` -- [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) (convert at boundary) - -#### 3.2 [BlockTracingState](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:28:0-37:2) Type - -**Current:** -```typescript -export type BlockTracingState = Pick< - BlockProverState, - | "witnessedRoots" - | "stateRoot" - | "pendingSTBatches" - | "networkState" - | "transactionList" - | "eternalTransactionsList" - | "incomingMessages" ->; -``` - -This uses provable hash lists. These are needed for the proving pipeline but could potentially be replaced with simpler commitment tracking. - -**Recommendation:** Keep as-is for now, as it's tightly coupled to proving logic. - ---- - -### Phase 4: Batch Trace Types -**Goal**: Make `BatchTrace` JSON-serializable for worker serialization - -#### 4.1 `BatchTrace` in `BatchTracingService.ts` - -**Current:** -```typescript -export interface BatchTrace { - blocks: BlockTrace[]; - stateTransitionTrace: StateTransitionProofParameters[]; -} -``` - -Where [BlockTrace](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:39:0-44:2) contains: -```typescript -export type BlockTrace = { - blockParams: NewBlockProverParameters; - transactions: TransactionTrace[]; - height: string; -}; -``` - -And [NewBlockProverParameters](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:30:0-38:1) contains provable types like `NetworkState`, `Bool`, etc. - -**Target:** Create `*Json` variants for serialization. - -**Files to change:** -- `BatchTracingService.ts` -- [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) -- Task serializers (already exist but could be simplified) - ---- - -### Phase 5: Merkle Witness Types -**Goal**: Use JSON representations for merkle witnesses - -#### 5.1 `LinkedMerkleTreeWitness` - -**Current:** Uses `Field[]` internally - -**Target:** Already has [toJSON()](cci:1://file:///Users/saitunc/Desktop/framework/packages/indexer/src/tasks/IndexBlockTaskParameters.ts:18:2-26:3)/[fromJSON()](cci:1://file:///Users/saitunc/Desktop/framework/packages/indexer/src/tasks/IndexBlockTaskParameters.ts:28:2-47:3) - ensure these are used consistently - -**Files to check:** -- [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) -- [StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) - ---- - -### Phase 6: RuntimeProofParameters -**Goal**: Make runtime proving parameters JSON-serializable - -#### 6.1 `RuntimeProofParameters` in `TransactionTracingService.ts` - -**Current:** -```typescript -export interface RuntimeProofParameters { - tx: PendingTransaction; - networkState: NetworkState; - state: TaskStateRecord; -} -``` - -**Target:** -```typescript -export interface RuntimeProofParametersJson { - tx: PendingTransactionJSONType; - networkState: NetworkStateJson; - state: TaskStateRecordJson; -} -``` - -**Files to change:** -- `TransactionTracingService.ts` -- [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) (convert at boundary) - ---- - -## Implementation Order - -``` -Phase 2: BlockTrackers - ↓ -Phase 3: TaskStateRecord - ↓ -Phase 4: BatchTrace (depends on 2 & 3) - ↓ -Phase 5: Merkle Witnesses - ↓ -Phase 6: RuntimeProofParameters -``` - ---- - -## Detailed Steps for Each Phase - -### Phase 2: BlockTrackers (Recommended Next Step) - -| Step | File | Change | -|------|------|--------| -| 2.1.1 | `TransactionExecutionService.ts` | Create `BlockTrackersJson` interface | -| 2.1.2 | `TransactionExecutionService.ts` | Add `blockTrackersToJson()` helper | -| 2.1.3 | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | Use string hashes instead of `Field` for block state | -| 2.1.4 | [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) | Convert to `Field` only when calling protocol methods | - -### Phase 3: TaskStateRecord - -| Step | File | Change | -|------|------|--------| -| 3.1.1 | [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) | Create `TaskStateRecordJson` type | -| 3.1.2 | `TransactionTracingService.ts` | Update `collectStartingState()` to return Json | -| 3.1.3 | [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) | Convert `TaskStateRecordJson` → [TaskStateRecord](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:26:0-26:54) in [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) | -| 3.1.4 | [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) | Same conversion at boundary | - -### Phase 4: BatchTrace - -| Step | File | Change | -|------|------|--------| -| 4.1.1 | [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) | Create `BlockTraceJson`, `NewBlockProverParametersJson` | -| 4.1.2 | `BatchTracingService.ts` | Create `BatchTraceJson` | -| 4.1.3 | [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0) | Convert Json → Provable when pushing to tasks | -| 4.1.4 | Update task parameter serializers | Simplify (just JSON.stringify) | - ---- - -## Files Summary - -### High Priority (Phase 2-3) -1. `TransactionExecutionService.ts` - BlockTrackers -2. [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) - Uses BlockTrackers -3. [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) - TaskStateRecord, BlockTrace -4. `TransactionTracingService.ts` - collectStartingState, RuntimeProofParameters - -### Medium Priority (Phase 4-5) -5. `BatchTracingService.ts` - BatchTrace -6. [StateTransitionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts:0:0-0:0) - Merkle witnesses -7. [BatchFlow.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/flow/BatchFlow.ts:0:0-0:0) - Orchestration - -### Proving Boundary (Update Converters) -8. [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) - Convert at compute() -9. [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) - Convert at compute() -10. [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) - Convert at compute() -11. [StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) - Convert at compute() - ---- - -## Questions to Consider - -1. **Do you want to proceed phase by phase, or tackle a specific area first?** - -2. **Should we prioritize the tracing layer (which is more complex) or the simpler BlockTrackers first?** - -3. **Are there any specific files you've noticed issues with that you'd like to prioritize?** - ---- - -Would you like me to start implementing **Phase 2 (BlockTrackers)** or **Phase 3 (TaskStateRecord)** first? - -### User Input - -I have a concern, which you might solve. I will change types at so many steps, but mappers or task serializers are using the original types. When we do the change, do i expect to directly not use any mappers or task serializers ? - -### Planner Response - -Excellent question! Let me clarify the relationship between types, mappers, and task serializers: - -## The Two Serialization Boundaries - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ SEQUENCER PROCESS │ -│ │ -│ Domain Layer (your types) │ -│ ↓ │ -│ ┌─────────────────────┐ ┌─────────────────────┐ │ -│ │ PERSISTENCE LAYER │ │ WORKER DISPATCH │ │ -│ │ (Prisma/DB) │ │ (IPC/Network) │ │ -│ │ │ │ │ │ -│ │ Uses: Mappers │ │ Uses: Serializers │ │ -│ └──────────┬──────────┘ └──────────┬──────────┘ │ -└─────────────┼───────────────────────────────┼───────────────────────┘ - ↓ ↓ - ┌─────────┐ ┌─────────────┐ - │ DB │ │ WORKER │ - │ (JSON) │ │ PROCESS │ - └─────────┘ └─────────────┘ -``` - ---- - -## Current State vs Target State - -### 1. Persistence Mappers - -| Current | Target | -|---------|--------| -| Domain uses provable types (`Field`, `Bool`) | Domain uses Json types (`string`, `boolean`) | -| Mappers convert: `Field` → `string` | **No conversion needed** - just cast | -| Complex mapping logic | Simple `as unknown as Prisma.JsonArray` | - -**Result: Mappers become trivial or can be removed** - -You've already seen this with `Block.transactions`: -```typescript -// Before: Complex mapper converting Bool/Field to primitives -// After: Just a cast -transactions: input.transactions as unknown as Prisma.JsonArray -``` - ---- - -### 2. Task Serializers - -This is more nuanced. Let me show you: - -**Current Flow:** -``` -Provable Types (Field, Bool, NetworkState) - ↓ Custom Serializer (e.g., field.toString(), networkState.toJSON()) -JSON String - ↓ Send to worker - ↓ Custom Deserializer (e.g., Field(str), NetworkState.fromJSON()) -Provable Types → Used in proving -``` - -**Target Flow (with Json types):** -``` -Json Types (string, boolean, NetworkStateJson) - ↓ Simple JSON.stringify() -JSON String - ↓ Send to worker - ↓ Simple JSON.parse() -Json Types - ↓ Convert to Provable at boundary (new step!) -Provable Types → Used in proving -``` - ---- - -## The Key Insight - -**Task Serializers don't disappear - they become SIMPLER, and the conversion moves to the compute() method.** - -### Example: `NewBlockProvingParametersSerializer` - -**Current (complex):** -```typescript -class NewBlockProvingParametersSerializer { - toJSON(params: NewBlockProvingParameters): string { - return JSON.stringify({ - publicInput: this.publicInputSerializer.toJSON(params.publicInput), - networkState: NetworkState.toJSON(params.networkState), - blockWitness: BlockHashMerkleTreeWitness.toJSON(params.blockWitness), - deferSTProof: params.deferSTProof.toBoolean(), - // ... lots of custom conversion - }); - } - - fromJSON(json: string): NewBlockProvingParameters { - const parsed = JSON.parse(json); - return { - publicInput: this.publicInputSerializer.fromJSON(parsed.publicInput), - networkState: new NetworkState(NetworkState.fromJSON(parsed.networkState)), - // ... lots of custom reconstruction - }; - } -} -``` - -**Target (simple):** -```typescript -class NewBlockProvingParametersSerializer { - // Types are already Json-compatible! - toJSON(params: NewBlockProvingParametersJson): string { - return JSON.stringify(params); - } - - fromJSON(json: string): NewBlockProvingParametersJson { - return JSON.parse(json); - } -} -``` - -**But now the conversion happens in `NewBlockTask.compute()`:** -```typescript -class NewBlockTask { - async compute(input: NewBlockProvingParametersJson): Promise { - // Convert at the proving boundary - const provableParams = newBlockParamsFromJson(input); - - await this.blockProver.proveBlock( - provableParams.publicInput, - provableParams.networkState, - // ... - ); - } -} -``` - ---- - -## Summary: What Happens to Each - -| Component | Current Role | After Refactoring | -|-----------|--------------|-------------------| -| **Persistence Mappers** | Convert provable ↔ DB types | **Trivial casts or removed** | -| **Task Serializers** | Custom JSON conversion with provable handling | **Simple JSON.stringify/parse** | -| **New Converters** | Don't exist | **`*FromJson()` functions at proving boundary** | - ---- - -## The Trade-off - -**Before:** -- Conversion complexity is in serializers -- Serializers handle provable → JSON → provable - -**After:** -- Serializers are trivial (just JSON) -- Conversion is explicit at the proving boundary (`*FromJson()` functions) -- Clearer separation: _"data is JSON until it enters the prover"_ - ---- - -## Practical Impact - -1. **You CAN remove/simplify mappers** for types that become fully JSON-compatible -2. **Serializers simplify** but don't completely disappear (you still need JSON.stringify/parse) -3. **New converter functions** are needed at the proving boundary (like [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) you already have) - ---- - -## Recommendation - -For the refactoring plan, I suggest we: - -1. **Keep serializers** but make them trivial (just `JSON.stringify`/`parse`) -2. **Add `*FromJson()` converters** for each type that needs to become provable -3. **Call converters in `*.compute()` methods** of tasks - -This gives you: -- ✅ Simple serialization (JSON everywhere) -- ✅ Clean proving boundary (converters in one place) -- ✅ Easy persistence (no mappers needed) - -Would you like me to proceed with Phase 2 using this approach? - -### User Input - -Cool. Add detailed implementation steps for this conversion as well. - -### Planner Response - -# Complete Refactoring Plan: Non-Provable Types with Serializer Simplification - ---- - -## Phase 0: Serializer & Mapper Analysis (Pre-work) - -### Current Serializers Inventory - -| Serializer | Location | Serializes | -|------------|----------|------------| -| `NewBlockProvingParametersSerializer` | `tasks/serializers/` | [NewBlockProvingParameters](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:40:0-44:2) | -| `TransactionProvingTaskParameterSerializer` | `tasks/serializers/` | `TransactionProvingTaskParameters` | -| `StateTransitionProofParametersSerializer` | `tasks/serializers/` | `StateTransitionProofParameters` | -| `RuntimeProofParametersSerializer` | `tasks/serializers/` | `RuntimeProofParameters` | -| `BlockProofSerializer` | `tasks/serializers/` | [BlockProof](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:28:0-28:73) (proofs) | -| `ProofTaskSerializer` | `helpers/utils.ts` | Generic proof serializer | - -### Current Mappers Inventory - -| Mapper | Location | Maps | -|--------|----------|------| -| `BlockMapper` | `persistance/mappers/` | [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) ↔ [PrismaBlock](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/PrismaBlockStorage.ts:27:0-245:1) | -| `BlockResultMapper` | `persistance/mappers/` | [BlockResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:128:0-136:1) ↔ `PrismaBlockResult` | -| [TransactionExecutionResultMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:47:0-91:1) | `persistance/mappers/` | [TransactionExecutionResult](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:23:0-34:1) ↔ DB | -| [TransactionMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:16:0-45:1) | `persistance/mappers/` | `PendingTransaction` ↔ DB | -| `StateTransitionBatchArrayMapper` | `persistance/mappers/` | `StateTransitionBatch[]` ↔ DB | -| `EventArrayMapper` | `persistance/mappers/` | Events ↔ DB | - ---- - -## Phase 1: Type Definitions (Already Done ✅) - -- [x] [TransactionExecutionResultJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:41:0-52:1) -- [x] [StateTransitionBatchJson](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:36:0-39:1) -- [x] [txResultToJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:54:0-70:1) / [txResultFromJson()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:72:0-88:1) - ---- - -## Phase 2: BlockTrackers & Block Production - -### Step 2.1: Create `BlockTrackersJson` Type - -**File:** [packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts:0:0-0:0) - -```typescript -// NEW: JSON-compatible trackers -export interface BlockTrackersJson { - blockHashRoot: string; - eternalTransactionsHash: string; - transactionsHash: string; - incomingMessagesHash: string; -} - -// Keep provable version for internal computation -export interface BlockTrackers { - blockHashRoot: Field; - eternalTransactionsList: TransactionHashList; - transactionList: TransactionHashList; - incomingMessages: MinaActionsHashList; -} - -// Converter -export function blockTrackersToJson(trackers: BlockTrackers): BlockTrackersJson { - return { - blockHashRoot: trackers.blockHashRoot.toString(), - eternalTransactionsHash: trackers.eternalTransactionsList.commitment.toString(), - transactionsHash: trackers.transactionList.commitment.toString(), - incomingMessagesHash: trackers.incomingMessages.commitment.toString(), - }; -} -``` - -### Step 2.2: Update [BlockProductionService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts:0:0-0:0) - -Keep using provable `BlockTrackers` internally (needed for hash list operations), but extract JSON values for the [Block](cci:2://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/storage/model/Block.ts:92:0-112:1) object. - -**No change needed** - already uses `FieldString()` for Block fields. - ---- - -## Phase 3: TaskStateRecord - -### Step 3.1: Create `TaskStateRecordJson` Type - -**File:** [packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) - -```typescript -// Current (provable) -export type TaskStateRecord = Record; - -// NEW (JSON-compatible) -export type TaskStateRecordJson = Record; - -// Converters -export function taskStateRecordToJson(record: TaskStateRecord): TaskStateRecordJson { - return Object.fromEntries( - Object.entries(record).map(([key, fields]) => [ - key, - fields.map(f => f.toString()) - ]) - ); -} - -export function taskStateRecordFromJson(json: TaskStateRecordJson): TaskStateRecord { - return Object.fromEntries( - Object.entries(json).map(([key, strings]) => [ - key, - strings.map(s => Field(s)) - ]) - ); -} -``` - -### Step 3.2: Update `collectStartingState()` in `TransactionTracingService.ts` - -**Current:** -```typescript -export function collectStartingState( - stateTransitions: UntypedStateTransition[] -): TaskStateRecord { - // Returns Record -} -``` - -**Target:** -```typescript -export function collectStartingState( - stateTransitions: UntypedStateTransition[] -): TaskStateRecordJson { - const stateEntries = stateTransitions - .filter(...) - .filter(...) - .map((st) => [st.path.toString(), st.fromValue.value.map(f => f.toString())]); - return Object.fromEntries(stateEntries); -} -``` - -### Step 3.3: Update Task Compute Methods - -**Files:** -- [NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) -- [TransactionProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:0:0-0:0) - -**In [compute()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts:92:2-126:3) method:** -```typescript -// Convert at boundary -const startingStateBeforeHook = taskStateRecordFromJson(parameters.startingStateBeforeHook); -const startingStateAfterHook = taskStateRecordFromJson(parameters.startingStateAfterHook); - -await executeWithPrefilledStateService( - this.protocol.stateServiceProvider, - [startingStateBeforeHook, startingStateAfterHook], - async () => { /* ... */ } -); -``` - ---- - -## Phase 4: NewBlockProverParameters - -### Step 4.1: Create JSON Interface - -**File:** [packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts:0:0-0:0) - -```typescript -// Current (provable) -export interface NewBlockProverParameters { - publicInput: BlockProverPublicInput; - networkState: NetworkState; - blockWitness: BlockHashMerkleTreeWitness; - deferSTProof: Bool; - afterBlockRootWitness: WitnessedRootWitness; - startingStateBeforeHook: TaskStateRecord; - startingStateAfterHook: TaskStateRecord; -} - -// NEW (JSON-compatible) -export interface NewBlockProverParametersJson { - publicInput: BlockProverPublicInputJson; - networkState: NetworkStateJson; - blockWitness: BlockHashMerkleTreeWitnessJson; - deferSTProof: boolean; - afterBlockRootWitness: WitnessedRootWitnessJson; - startingStateBeforeHook: TaskStateRecordJson; - startingStateAfterHook: TaskStateRecordJson; -} - -// Converters -export function newBlockParamsToJson(params: NewBlockProverParameters): NewBlockProverParametersJson { - return { - publicInput: BlockProverPublicInput.toJSON(params.publicInput), - networkState: NetworkState.toJSON(params.networkState), - blockWitness: BlockHashMerkleTreeWitness.toJSON(params.blockWitness), - deferSTProof: params.deferSTProof.toBoolean(), - afterBlockRootWitness: witnessedRootWitnessToJson(params.afterBlockRootWitness), - startingStateBeforeHook: taskStateRecordToJson(params.startingStateBeforeHook), - startingStateAfterHook: taskStateRecordToJson(params.startingStateAfterHook), - }; -} - -export function newBlockParamsFromJson(json: NewBlockProverParametersJson): NewBlockProverParameters { - return { - publicInput: BlockProverPublicInput.fromJSON(json.publicInput), - networkState: new NetworkState(NetworkState.fromJSON(json.networkState)), - blockWitness: new BlockHashMerkleTreeWitness( - BlockHashMerkleTreeWitness.fromJSON(json.blockWitness) - ), - deferSTProof: Bool(json.deferSTProof), - afterBlockRootWitness: witnessedRootWitnessFromJson(json.afterBlockRootWitness), - startingStateBeforeHook: taskStateRecordFromJson(json.startingStateBeforeHook), - startingStateAfterHook: taskStateRecordFromJson(json.startingStateAfterHook), - }; -} -``` - -### Step 4.2: Update [BlockTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:0:0-0:0) - -Change [traceBlock()](cci:1://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts:57:2-162:3) to return JSON types: - -**Current:** -```typescript -public async traceBlock(...): Promise<[BlockTracingState, BlockTrace]> { - // Returns BlockTrace with provable NewBlockProverParameters -} -``` - -**Target:** -```typescript -public async traceBlock(...): Promise<[BlockTracingState, BlockTraceJson]> { - // Returns BlockTraceJson with NewBlockProverParametersJson -} - -export interface BlockTraceJson { - blockParams: NewBlockProverParametersJson; - transactions: TransactionTraceJson[]; - height: string; -} -``` - ---- - -## Phase 5: Simplify Serializers - -### Step 5.1: Simplify `NewBlockProvingParametersSerializer` - -**File:** [packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts:0:0-0:0) - -**Current (complex):** -```typescript -export class NewBlockProvingParametersSerializer { - constructor( - private readonly stProofSerializer: ProofTaskSerializer<...>, - private readonly blockProofSerializer: ProofTaskSerializer<...> - ) {} - - toJSON(input: NewBlockProvingParameters): string { - // Complex conversion of each field - } - - fromJSON(json: string): NewBlockProvingParameters { - // Complex reconstruction of each field - } -} -``` - -**Target (simple):** -```typescript -export class NewBlockProvingParametersSerializer - implements TaskSerializer { - - // Proofs still need special handling (they contain actual proof data) - constructor( - private readonly stProofSerializer: ProofTaskSerializer<...>, - private readonly blockProofSerializer: ProofTaskSerializer<...> - ) {} - - toJSON(input: NewBlockProvingParametersJson): string { - return JSON.stringify({ - params: input.params, // Already JSON-compatible! - input1: this.stProofSerializer.toJSON(input.input1), - input2: this.blockProofSerializer.toJSON(input.input2), - }); - } - - fromJSON(json: string): NewBlockProvingParametersJson { - const parsed = JSON.parse(json); - return { - params: parsed.params, // Already correct type - input1: this.stProofSerializer.fromJSON(parsed.input1), - input2: this.blockProofSerializer.fromJSON(parsed.input2), - }; - } -} -``` - -> **Note:** Proof objects (`input1`, `input2`) still need special serialization because they contain cryptographic proof data. The simplification is for the parameters, not the proofs. - -### Step 5.2: Repeat for Other Serializers - -Apply the same pattern to: - -| Serializer | Params become JSON | Proofs stay special | -|------------|-------------------|---------------------| -| `TransactionProvingTaskParameterSerializer` | `TransactionProverParameters` → JSON | `DynamicRuntimeProof` stays | -| `RuntimeProofParametersSerializer` | `RuntimeProofParameters` → JSON | N/A (no proofs) | -| `StateTransitionProofParametersSerializer` | `StateTransitionProofParameters` → JSON | Merkle witnesses already JSON | - ---- - -## Phase 6: Simplify Persistence Mappers - -### Step 6.1: [TransactionExecutionResultMapper](cci:2://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:47:0-91:1) - -**File:** [packages/persistance/src/services/prisma/mappers/TransactionMapper.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts:0:0-0:0) - -**Current (maps provable types):** -```typescript -export class TransactionExecutionResultMapper { - mapIn(input: [DBTransactionExecutionResult, DBTransaction]): TransactionExecutionResult { - return { - tx: this.transactionMapper.mapIn(input[1]), - status: Bool(executionResult.status), - hooksStatus: Bool(executionResult.hooksStatus), - // ... - }; - } - - mapOut(input: TransactionExecutionResult): [...] { - return { - status: input.status.toBoolean(), - hooksStatus: input.hooksStatus.toBoolean(), - // ... - }; - } -} -``` - -**Target (trivial - types already match):** -```typescript -export class TransactionExecutionResultMapper { - // Now Block.transactions is TransactionExecutionResultJson[] - // DB stores JSON - types are already compatible! - - mapIn(input: [DBTransactionExecutionResult, DBTransaction]): TransactionExecutionResultJson { - // Just restructure, no type conversion - return { - tx: { - hash: input[1].hash, - methodId: input[1].methodId, - // ... all already strings - }, - status: input[0].status, // Already boolean in DB - hooksStatus: input[0].hooksStatus, - // ... - }; - } - - mapOut(input: TransactionExecutionResultJson): [...] { - // No conversion needed - types match - return [ - { - status: input.status, - hooksStatus: input.hooksStatus, - stateTransitions: input.stateTransitions as Prisma.JsonArray, - events: input.events as Prisma.JsonArray, - // ... - }, - { - hash: input.tx.hash, - methodId: input.tx.methodId, - // ... - } - ]; - } -} -``` - -### Step 6.2: `BlockMapper` - -**Already largely simplified** - just needs `transactions` to be cast: - -```typescript -mapIn(input: PrismaBlock): Block { - return { - // ... - transactions: input.transactions as unknown as TransactionExecutionResultJson[], - // ... - }; -} - -mapOut(input: Block): PrismaBlock { - return { - // ... - transactions: input.transactions as unknown as Prisma.JsonArray, - // ... - }; -} -``` - ---- - -## Phase 7: RuntimeProofParameters - -### Step 7.1: Create JSON Interface - -**File:** [packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts:0:0-0:0) - -```typescript -// Current -export interface RuntimeProofParameters { - tx: PendingTransaction; - networkState: NetworkState; - state: TaskStateRecord; -} - -// NEW -export interface RuntimeProofParametersJson { - tx: PendingTransactionJSONType; - networkState: NetworkStateJson; - state: TaskStateRecordJson; -} - -// Converters -export function runtimeParamsToJson(params: RuntimeProofParameters): RuntimeProofParametersJson { - return { - tx: params.tx.toJSON(), - networkState: NetworkState.toJSON(params.networkState), - state: taskStateRecordToJson(params.state), - }; -} - -export function runtimeParamsFromJson(json: RuntimeProofParametersJson): RuntimeProofParameters { - return { - tx: PendingTransaction.fromJSON(json.tx), - networkState: new NetworkState(NetworkState.fromJSON(json.networkState)), - state: taskStateRecordFromJson(json.state), - }; -} -``` - -### Step 7.2: Update [RuntimeProvingTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts:0:0-0:0) - -```typescript -class RuntimeProvingTask { - // Input type changes to JSON - async compute(input: RuntimeProofParametersJson): Promise { - // Convert at boundary - const params = runtimeParamsFromJson(input); - - // Use provable types for proving - await this.runtime.prove(params.tx, params.networkState, params.state); - - return await this.executionContext.current().result.prove(); - } -} -``` - ---- - -## Phase 8: StateTransitionProofParameters - -### Step 8.1: Create JSON Interface - -**File:** [packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts](cci:7://file:///Users/saitunc/Desktop/framework/packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts:0:0-0:0) - -```typescript -// Current -export interface StateTransitionProofParameters { - batch: StateTransitionProvableBatch; - merkleWitnesses: LinkedMerkleTreeWitness[]; - publicInput: StateTransitionProverPublicInput; - batchState: AppliedStateTransitionBatchState; - witnessRoots: { values: Bool[] }; -} - -// NEW -export interface StateTransitionProofParametersJson { - batch: StateTransitionProvableBatchJson; // Need to define this - merkleWitnesses: LinkedMerkleTreeWitnessJson[]; - publicInput: StateTransitionProverPublicInputJson; - batchState: AppliedStateTransitionBatchStateJson; - witnessRoots: { values: boolean[] }; -} -``` - -> This is more complex because `StateTransitionProvableBatch` is a deeply nested provable structure. May need to defer this or create comprehensive converters. - ---- - -## Implementation Order Summary - -``` -Week 1: Foundation -├── Phase 2: BlockTrackers (if needed) -├── Phase 3: TaskStateRecord -│ └── Step 3.1: Types -│ └── Step 3.2: collectStartingState() -│ └── Step 3.3: Update Task compute() -│ -Week 2: Parameters -├── Phase 4: NewBlockProverParameters -│ └── Step 4.1: JSON types + converters -│ └── Step 4.2: Update BlockTracingService -│ -├── Phase 7: RuntimeProofParameters -│ └── Step 7.1: JSON types + converters -│ └── Step 7.2: Update RuntimeProvingTask -│ -Week 3: Serializers & Mappers -├── Phase 5: Simplify Serializers -│ └── Step 5.1: NewBlockProvingParametersSerializer -│ └── Step 5.2: Other serializers -│ -├── Phase 6: Simplify Mappers -│ └── Step 6.1: TransactionExecutionResultMapper -│ └── Step 6.2: BlockMapper -│ -Week 4: Complex Types (Optional) -└── Phase 8: StateTransitionProofParameters - └── Complex nested structures -``` - ---- - -## Verification Checklist - -After each phase, verify: - -- [ ] `npm run build` passes in sequencer package -- [ ] `npm run build` passes in persistance package -- [ ] `npm run build` passes at repo root -- [ ] Existing tests still pass -- [ ] No runtime type errors (if possible to test) - ---- - -Would you like me to start implementing Phase 3 (TaskStateRecord) as the next concrete step? \ No newline at end of file From 1989a195395de5a11ef59c8498ebf58cb5f1dd5f Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 01:57:52 +0300 Subject: [PATCH 32/63] refactor: rename NetworkState to ProvableNetworkState --- .../src/graphql/modules/QueryGraphqlModule.ts | 4 ++-- .../src/hooks/RuntimeFeeAnalyzerService.ts | 4 ++-- packages/library/test/math/State.test.ts | 4 ++-- packages/module/src/runtime/Runtime.ts | 4 ++-- packages/module/src/runtime/RuntimeModule.ts | 4 ++-- packages/module/test/Runtime.test.ts | 4 ++-- packages/module/test/modules/Balances.test.ts | 12 ++++++------ packages/module/test/modules/State.test.ts | 4 ++-- packages/module/test/runtimeMethod.test.ts | 8 ++++---- .../src/services/prisma/mappers/BlockMapper.ts | 6 +++--- .../prisma/mappers/BlockResultMapper.ts | 4 ++-- packages/protocol/src/hooks/BlockHeightHook.ts | 8 ++++---- .../src/hooks/LastStateRootBlockHook.ts | 10 +++++----- packages/protocol/src/hooks/NoopBlockHook.ts | 10 +++++----- .../protocol/src/model/network/NetworkState.ts | 6 +++--- .../protocol/src/protocol/ProvableBlockHook.ts | 10 +++++----- .../src/protocol/ProvableTransactionHook.ts | 8 ++++---- .../protocol/src/prover/block/BlockProvable.ts | 8 ++++---- .../protocol/src/prover/block/BlockProver.ts | 18 +++++++++--------- .../prover/transaction/TransactionProvable.ts | 12 ++++++------ .../prover/transaction/TransactionProver.ts | 4 ++-- .../settlement/BridgingSettlementContract.ts | 10 +++++----- .../contracts/settlement/SettlementBase.ts | 16 ++++++++-------- .../contracts/settlement/SettlementContract.ts | 6 +++--- .../modularity/ProvableSettlementHook.ts | 6 +++--- .../context/RuntimeMethodExecutionContext.ts | 6 +++--- packages/protocol/src/utils/utils.ts | 6 +++--- packages/protocol/test/BlockProver.test.ts | 6 +++--- packages/protocol/test/State.test.ts | 4 ++-- .../protocol/test/state/assert/assert.test.ts | 4 ++-- packages/sdk/src/client/ClientAppChain.ts | 4 ++-- .../GraphqlNetworkStateTransportModule.ts | 14 +++++++------- .../query/BlockStorageNetworkStateModule.ts | 10 +++++----- .../sdk/test/blockProof/blockProof.test.ts | 6 +++--- .../src/helpers/query/NetworkStateQuery.ts | 8 ++++---- .../query/NetworkStateTransportModule.ts | 8 ++++---- .../src/mempool/private/PrivateMempool.ts | 14 +++++++------- .../protocol/production/BatchProducerModule.ts | 6 +++--- .../sequencing/BlockProductionService.ts | 10 +++++----- .../sequencing/BlockResultService.ts | 10 +++++----- .../sequencing/TransactionExecutionService.ts | 6 +++--- .../protocol/production/tasks/NewBlockTask.ts | 4 ++-- .../production/tasks/RuntimeProvingTask.ts | 10 +++++----- .../NewBlockProvingParametersSerializer.ts | 10 +++++----- ...ransactionProvingTaskParameterSerializer.ts | 18 +++++++++--------- .../production/tracing/BatchTracingService.ts | 6 +++--- .../production/tracing/BlockTracingService.ts | 18 +++++++++--------- .../tracing/TransactionTracingService.ts | 6 +++--- .../bridging/BridgingSettlementInteraction.ts | 6 +++--- .../vanilla/VanillaSettlementInteraction.ts | 6 +++--- packages/sequencer/src/storage/model/Batch.ts | 6 +++--- packages/sequencer/src/storage/model/Block.ts | 14 +++++++------- .../test/settlement/Settlement-only.ts | 6 +++--- .../sequencer/test/settlement/Settlement.ts | 4 ++-- 54 files changed, 213 insertions(+), 213 deletions(-) diff --git a/packages/api/src/graphql/modules/QueryGraphqlModule.ts b/packages/api/src/graphql/modules/QueryGraphqlModule.ts index c7c427939..a645b3535 100644 --- a/packages/api/src/graphql/modules/QueryGraphqlModule.ts +++ b/packages/api/src/graphql/modules/QueryGraphqlModule.ts @@ -24,7 +24,7 @@ import { } from "@proto-kit/module"; import { MandatoryProtocolModulesRecord, - NetworkState, + ProvableNetworkState, Protocol, ProtocolModulesRecord, State, @@ -385,7 +385,7 @@ export class QueryGraphqlModule< this.networkStateTransportModule ); const networkType = this.flexiblePureToGraphql( - NetworkState, + ProvableNetworkState, "Network", this.jsonToGraphQl.bind(this) ); diff --git a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts index 22ec51bd1..47245baa1 100644 --- a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts +++ b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts @@ -8,7 +8,7 @@ import { container, inject } from "tsyringe"; import { RuntimeMethodExecutionContext, RuntimeTransaction, - NetworkState, + ProvableNetworkState, } from "@proto-kit/protocol"; import { Field, Poseidon, Struct } from "o1js"; @@ -77,7 +77,7 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule state", () => { const context = container.resolve(RuntimeMethodExecutionContext); context.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); const uint = await state.get(); diff --git a/packages/module/src/runtime/Runtime.ts b/packages/module/src/runtime/Runtime.ts index 468940e8e..27822b80b 100644 --- a/packages/module/src/runtime/Runtime.ts +++ b/packages/module/src/runtime/Runtime.ts @@ -19,7 +19,7 @@ import { SimpleAsyncStateService, RuntimeMethodExecutionContext, RuntimeTransaction, - NetworkState, + ProvableNetworkState, } from "@proto-kit/protocol"; import { @@ -388,7 +388,7 @@ export class Runtime const context = container.resolve(RuntimeMethodExecutionContext); context.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); return await this.zkProgrammable.compile(registry); } diff --git a/packages/module/src/runtime/RuntimeModule.ts b/packages/module/src/runtime/RuntimeModule.ts index 7267e4c60..d7b4793c9 100644 --- a/packages/module/src/runtime/RuntimeModule.ts +++ b/packages/module/src/runtime/RuntimeModule.ts @@ -1,7 +1,7 @@ import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common"; import { container, injectable } from "tsyringe"; import { - NetworkState, + ProvableNetworkState, RuntimeTransaction, RuntimeMethodExecutionContext, RuntimeMethodExecutionData, @@ -112,7 +112,7 @@ export class RuntimeModule< return this.getInputs().transaction; } - public get network(): NetworkState { + public get network(): ProvableNetworkState { return this.getInputs().networkState; } } diff --git a/packages/module/test/Runtime.test.ts b/packages/module/test/Runtime.test.ts index 28ba7f24e..58d45dcf2 100644 --- a/packages/module/test/Runtime.test.ts +++ b/packages/module/test/Runtime.test.ts @@ -10,7 +10,7 @@ describe("noop", () => { // import { // RuntimeMethodExecutionContext, // RuntimeTransaction, -// NetworkState, +// ProvableNetworkState, // } from "@proto-kit/protocol"; // // import { MethodIdResolver } from "../src"; @@ -62,7 +62,7 @@ describe("noop", () => { // const context = container.resolve(RuntimeMethodExecutionContext); // context.setup({ // transaction: RuntimeTransaction.dummyTransaction(), -// networkState: NetworkState.empty(), +// networkState: ProvableNetworkState.empty(), // }); // // await runtime.zkProgrammable.zkProgram.analyzeMethods(); diff --git a/packages/module/test/modules/Balances.test.ts b/packages/module/test/modules/Balances.test.ts index d61f6a3d9..0706df416 100644 --- a/packages/module/test/modules/Balances.test.ts +++ b/packages/module/test/modules/Balances.test.ts @@ -8,7 +8,7 @@ import { SimpleAsyncStateService, RuntimeMethodExecutionContext, RuntimeTransaction, - NetworkState, + ProvableNetworkState, PROTOKIT_PREFIXES, } from "@proto-kit/protocol"; @@ -74,7 +74,7 @@ describe("balances", () => { const executionContext = container.resolve(RuntimeMethodExecutionContext); executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); const expectedStateTransitionsHash = @@ -114,7 +114,7 @@ describe("balances", () => { ); executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); await balances.getTotalSupply(); @@ -177,7 +177,7 @@ describe("balances", () => { ); executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); await balances.getTotalSupply(); @@ -236,7 +236,7 @@ describe("balances", () => { ); executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); await balances.setTotalSupply(); @@ -305,7 +305,7 @@ describe("balances", () => { ); executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); await balances.getBalance(address); diff --git a/packages/module/test/modules/State.test.ts b/packages/module/test/modules/State.test.ts index 8f5f55533..684c1d613 100644 --- a/packages/module/test/modules/State.test.ts +++ b/packages/module/test/modules/State.test.ts @@ -2,7 +2,7 @@ import "reflect-metadata"; import { PublicKey, UInt64 } from "o1js"; import { container } from "tsyringe"; import { - NetworkState, + ProvableNetworkState, Option, RuntimeMethodExecutionContext, RuntimeTransaction, @@ -56,7 +56,7 @@ describe("state", () => { const executionContext = container.resolve(RuntimeMethodExecutionContext); executionContext.setup({ - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), transaction: RuntimeTransaction.dummyTransaction(), }); await balances.transientState(); diff --git a/packages/module/test/runtimeMethod.test.ts b/packages/module/test/runtimeMethod.test.ts index ca895ae31..37da9dab5 100644 --- a/packages/module/test/runtimeMethod.test.ts +++ b/packages/module/test/runtimeMethod.test.ts @@ -10,7 +10,7 @@ import { } from "o1js"; import { MethodPublicOutput, - NetworkState, + ProvableNetworkState, RuntimeMethodExecutionContext, RuntimeTransaction, } from "@proto-kit/protocol"; @@ -118,7 +118,7 @@ describe("runtimeMethod", () => { context.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); const module = runtime.resolve("Balances"); @@ -126,7 +126,7 @@ describe("runtimeMethod", () => { context.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); await expect(context.current().result.prover!()).rejects.toThrow( @@ -158,7 +158,7 @@ describe("runtimeMethod", () => { methodId: Field(eventMakerMethodId), argsHash: Poseidon.hash([]), }), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); const module = runtime.resolve("EventMaker"); diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index d13fddbf4..9b5576fe4 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,7 +1,7 @@ import { singleton } from "tsyringe"; import { Block, UntypedStateTransitionJson } from "@proto-kit/sequencer"; import { Prisma, Block as PrismaBlock } from "@prisma/client"; -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -18,8 +18,8 @@ export class BlockMapper implements ObjectMapper { transactions: [], networkState: { - before: input.beforeNetworkState as NetworkStateJson, - during: input.duringNetworkState as NetworkStateJson, + before: input.beforeNetworkState as NetworkState, + during: input.duringNetworkState as NetworkState, }, hash: input.hash, diff --git a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts index d8afc7d6c..64f351576 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts @@ -3,7 +3,7 @@ import { BlockResult } from "@proto-kit/sequencer"; import { BlockResult as DBBlockResult, Prisma } from "@prisma/client"; import { BlockHashMerkleTreeWitnessJson, - NetworkStateJson, + NetworkState, } from "@proto-kit/protocol"; import { ObjectMapper } from "../../../ObjectMapper"; @@ -20,7 +20,7 @@ export class BlockResultMapper public mapIn(input: DBBlockResult): BlockResult { return { - afterNetworkState: input.afterNetworkState as NetworkStateJson, + afterNetworkState: input.afterNetworkState as NetworkState, stateRoot: input.stateRoot, blockHashRoot: input.blockHashRoot, diff --git a/packages/protocol/src/hooks/BlockHeightHook.ts b/packages/protocol/src/hooks/BlockHeightHook.ts index d08d48124..e46d89221 100644 --- a/packages/protocol/src/hooks/BlockHeightHook.ts +++ b/packages/protocol/src/hooks/BlockHeightHook.ts @@ -1,9 +1,9 @@ -import { NetworkState } from "../model/network/NetworkState"; +import { ProvableNetworkState } from "../model/network/NetworkState"; import { ProvableBlockHook } from "../protocol/ProvableBlockHook"; export class BlockHeightHook extends ProvableBlockHook> { - public async afterBlock(networkState: NetworkState): Promise { - return new NetworkState({ + public async afterBlock(networkState: ProvableNetworkState): Promise { + return new ProvableNetworkState({ block: { height: networkState.block.height.add(1), }, @@ -11,7 +11,7 @@ export class BlockHeightHook extends ProvableBlockHook> { }); } - public async beforeBlock(networkState: NetworkState): Promise { + public async beforeBlock(networkState: ProvableNetworkState): Promise { return networkState; } } diff --git a/packages/protocol/src/hooks/LastStateRootBlockHook.ts b/packages/protocol/src/hooks/LastStateRootBlockHook.ts index 4c7cf8091..cc06f60ac 100644 --- a/packages/protocol/src/hooks/LastStateRootBlockHook.ts +++ b/packages/protocol/src/hooks/LastStateRootBlockHook.ts @@ -2,16 +2,16 @@ import { AfterBlockHookArguments, ProvableBlockHook, } from "../protocol/ProvableBlockHook"; -import { NetworkState } from "../model/network/NetworkState"; +import { ProvableNetworkState } from "../model/network/NetworkState"; export class LastStateRootBlockHook extends ProvableBlockHook< Record > { public async afterBlock( - networkState: NetworkState, + networkState: ProvableNetworkState, { stateRoot }: AfterBlockHookArguments - ): Promise { - return new NetworkState({ + ): Promise { + return new ProvableNetworkState({ block: networkState.block, previous: { rootHash: stateRoot, @@ -19,7 +19,7 @@ export class LastStateRootBlockHook extends ProvableBlockHook< }); } - public async beforeBlock(networkState: NetworkState): Promise { + public async beforeBlock(networkState: ProvableNetworkState): Promise { return networkState; } } diff --git a/packages/protocol/src/hooks/NoopBlockHook.ts b/packages/protocol/src/hooks/NoopBlockHook.ts index a836edc81..9c6c4b26a 100644 --- a/packages/protocol/src/hooks/NoopBlockHook.ts +++ b/packages/protocol/src/hooks/NoopBlockHook.ts @@ -5,20 +5,20 @@ import { BeforeBlockHookArguments, ProvableBlockHook, } from "../protocol/ProvableBlockHook"; -import { NetworkState } from "../model/network/NetworkState"; +import { ProvableNetworkState } from "../model/network/NetworkState"; export class NoopBlockHook extends ProvableBlockHook { public async afterBlock( - networkState: NetworkState, + networkState: ProvableNetworkState, state: AfterBlockHookArguments - ): Promise { + ): Promise { return networkState; } public async beforeBlock( - networkState: NetworkState, + networkState: ProvableNetworkState, state: BeforeBlockHookArguments - ): Promise { + ): Promise { return networkState; } } diff --git a/packages/protocol/src/model/network/NetworkState.ts b/packages/protocol/src/model/network/NetworkState.ts index 87c8be710..ef0ca8e5c 100644 --- a/packages/protocol/src/model/network/NetworkState.ts +++ b/packages/protocol/src/model/network/NetworkState.ts @@ -9,7 +9,7 @@ export class PreviousBlock extends Struct({ rootHash: Field, }) {} -export class NetworkState extends Struct({ +export class ProvableNetworkState extends Struct({ block: CurrentBlock, previous: PreviousBlock, }) { @@ -21,7 +21,7 @@ export class NetworkState extends Struct({ } public static empty() { - return new NetworkState({ + return new ProvableNetworkState({ block: { height: UInt64.zero, }, @@ -32,4 +32,4 @@ export class NetworkState extends Struct({ } } -export type NetworkStateJson = InferJson; +export type NetworkState = InferJson; diff --git a/packages/protocol/src/protocol/ProvableBlockHook.ts b/packages/protocol/src/protocol/ProvableBlockHook.ts index 7ba6dcd32..b6248dbac 100644 --- a/packages/protocol/src/protocol/ProvableBlockHook.ts +++ b/packages/protocol/src/protocol/ProvableBlockHook.ts @@ -1,7 +1,7 @@ import { Field } from "o1js"; import { NoConfig } from "@proto-kit/common"; -import { NetworkState } from "../model/network/NetworkState"; +import { ProvableNetworkState } from "../model/network/NetworkState"; import { BlockProverState, BlockProverPublicInput, @@ -51,12 +51,12 @@ export abstract class ProvableBlockHook< Config = NoConfig, > extends TransitioningProtocolModule { public abstract beforeBlock( - networkState: NetworkState, + networkState: ProvableNetworkState, state: BeforeBlockHookArguments - ): Promise; + ): Promise; public abstract afterBlock( - networkState: NetworkState, + networkState: ProvableNetworkState, state: AfterBlockHookArguments - ): Promise; + ): Promise; } diff --git a/packages/protocol/src/protocol/ProvableTransactionHook.ts b/packages/protocol/src/protocol/ProvableTransactionHook.ts index 68fa3bedf..c6337bc05 100644 --- a/packages/protocol/src/protocol/ProvableTransactionHook.ts +++ b/packages/protocol/src/protocol/ProvableTransactionHook.ts @@ -2,7 +2,7 @@ import { NoConfig } from "@proto-kit/common"; import { Signature } from "o1js"; import { RuntimeTransaction } from "../model/transaction/RuntimeTransaction"; -import { NetworkState } from "../model/network/NetworkState"; +import { ProvableNetworkState } from "../model/network/NetworkState"; import { MethodPublicOutput } from "../model/MethodPublicOutput"; import { TransactionProverPublicInput, @@ -36,7 +36,7 @@ export function toBeforeTransactionHookArgument( TransactionProverTransactionArguments, "verificationKeyAttestation" >, - networkState: NetworkState, + networkState: ProvableNetworkState, state: Parameters[0] ): BeforeTransactionHookArguments { const { transaction, signature } = executionData; @@ -54,7 +54,7 @@ export function toAfterTransactionHookArgument( TransactionProverTransactionArguments, "verificationKeyAttestation" >, - networkState: NetworkState, + networkState: ProvableNetworkState, state: Parameters[0], runtimeResult: MethodPublicOutput ): AfterTransactionHookArguments { @@ -77,7 +77,7 @@ export type TransactionResult = Omit< export interface BeforeTransactionHookArguments { transaction: RuntimeTransaction; signature: Signature; - networkState: NetworkState; + networkState: ProvableNetworkState; prover: ProvableHookTransactionState; } diff --git a/packages/protocol/src/prover/block/BlockProvable.ts b/packages/protocol/src/prover/block/BlockProvable.ts index dbcb311fe..3c90302e1 100644 --- a/packages/protocol/src/prover/block/BlockProvable.ts +++ b/packages/protocol/src/prover/block/BlockProvable.ts @@ -2,7 +2,7 @@ import { Bool, Field, Proof, Struct } from "o1js"; import { CompilableModule, WithZkProgrammable } from "@proto-kit/common"; import { StateTransitionProof } from "../statetransition/StateTransitionProvable"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; import { TransactionHashList } from "../accumulators/TransactionHashList"; import { MinaActionsHashList } from "../../utils/MinaPrefixedProvableHashList"; import { AppliedBatchHashList } from "../accumulators/AppliedBatchHashList"; @@ -34,7 +34,7 @@ export class BlockProverState extends TransactionProverState { constructor(args: { transactionList: TransactionHashList; - networkState: NetworkState; + networkState: ProvableNetworkState; eternalTransactionsList: TransactionHashList; pendingSTBatches: AppliedBatchHashList; incomingMessages: MinaActionsHashList; @@ -60,7 +60,7 @@ export class BlockProverState extends TransactionProverState { public static fromCommitments( publicInput: BlockProverPublicInput, - networkState: NetworkState + networkState: ProvableNetworkState ): BlockProverState { return new BlockProverState({ ...super.fromCommitments(publicInput, networkState), @@ -105,7 +105,7 @@ export interface BlockProvable CompilableModule { proveBlock: ( publicInput: BlockProverPublicInput, - networkState: NetworkState, + networkState: ProvableNetworkState, blockWitness: BlockHashMerkleTreeWitness, stateTransitionProof: StateTransitionProof, deferSTs: Bool, diff --git a/packages/protocol/src/prover/block/BlockProver.ts b/packages/protocol/src/prover/block/BlockProver.ts index ede4ea8c9..acb692276 100644 --- a/packages/protocol/src/prover/block/BlockProver.ts +++ b/packages/protocol/src/prover/block/BlockProver.ts @@ -28,7 +28,7 @@ import { ProvableBlockHook, toProvableHookBlockState, } from "../../protocol/ProvableBlockHook"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; import { assertEqualsIf } from "../../utils/utils"; import { WitnessedRootWitness } from "../accumulators/WitnessedRootHashList"; import { StateServiceProvider } from "../../state/StateServiceProvider"; @@ -99,11 +99,11 @@ export class BlockProverProgrammable extends ZkProgrammable< >( hook: ( module: ProvableBlockHook, - networkState: NetworkState, + networkState: ProvableNetworkState, args: T - ) => Promise, + ) => Promise, hookArguments: T, - inputNetworkState: NetworkState + inputNetworkState: ProvableNetworkState ) { const transaction = RuntimeTransaction.dummyTransaction(); const startingInputs = { @@ -114,7 +114,7 @@ export class BlockProverProgrammable extends ZkProgrammable< return await executeHooks(startingInputs, async () => { const executionContext = container.resolve(RuntimeMethodExecutionContext); - return await this.blockHooks.reduce>( + return await this.blockHooks.reduce>( async (networkStatePromise, blockHook) => { const networkState = await networkStatePromise; @@ -218,7 +218,7 @@ export class BlockProverProgrammable extends ZkProgrammable< @provableMethod() public async proveBlock( publicInput: BlockProverPublicInput, - networkState: NetworkState, + networkState: ProvableNetworkState, blockWitness: BlockHashMerkleTreeWitness, stateTransitionProof: StateTransitionProof, deferSTProof: Bool, @@ -566,7 +566,7 @@ export class BlockProverProgrammable extends ZkProgrammable< methods: { proveBlock: { privateInputs: [ - NetworkState, + ProvableNetworkState, BlockHashMerkleTreeWitness, StateTransitionProofClass, Bool, @@ -575,7 +575,7 @@ export class BlockProverProgrammable extends ZkProgrammable< ], async method( publicInput: BlockProverPublicInput, - networkState: NetworkState, + networkState: ProvableNetworkState, blockWitness: BlockHashMerkleTreeWitness, stateTransitionProof: StateTransitionProof, deferSTs: Bool, @@ -685,7 +685,7 @@ export class BlockProver public proveBlock( publicInput: BlockProverPublicInput, - networkState: NetworkState, + networkState: ProvableNetworkState, blockWitness: BlockHashMerkleTreeWitness, stateTransitionProof: StateTransitionProof, deferSTs: Bool, diff --git a/packages/protocol/src/prover/transaction/TransactionProvable.ts b/packages/protocol/src/prover/transaction/TransactionProvable.ts index 4180fd906..9c9f68768 100644 --- a/packages/protocol/src/prover/transaction/TransactionProvable.ts +++ b/packages/protocol/src/prover/transaction/TransactionProvable.ts @@ -5,7 +5,7 @@ import { DynamicProof, Field, Proof, Signature, Struct, Void } from "o1js"; import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction"; import { RuntimeVerificationKeyAttestation } from "../block/accummulators/RuntimeVerificationKeyTree"; import { MethodPublicOutput } from "../../model/MethodPublicOutput"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; import { TransactionHashList } from "../accumulators/TransactionHashList"; import { AppliedBatchHashList } from "../accumulators/AppliedBatchHashList"; import { MinaActionsHashList } from "../../utils/MinaPrefixedProvableHashList"; @@ -22,7 +22,7 @@ export class TransactionProverState { * The network state which gives access to values such as blockHeight * This value is the same for the whole batch (L2 block) */ - networkState: NetworkState; + networkState: ProvableNetworkState; /** * A variant of the transactionsHash that is never reset. @@ -39,7 +39,7 @@ export class TransactionProverState { constructor(args: { transactionList: TransactionHashList; - networkState: NetworkState; + networkState: ProvableNetworkState; eternalTransactionsList: TransactionHashList; pendingSTBatches: AppliedBatchHashList; incomingMessages: MinaActionsHashList; @@ -66,7 +66,7 @@ export class TransactionProverState { public static fromCommitments( publicInput: TransactionProverPublicInput, - networkState: NetworkState + networkState: ProvableNetworkState ): TransactionProverState { publicInput.networkStateHash.assertEquals( networkState.hash(), @@ -137,13 +137,13 @@ export class DynamicRuntimeProof extends DynamicProof< export class BlockProverSingleTransactionExecutionData extends Struct({ transaction: TransactionProverTransactionArguments, - networkState: NetworkState, + networkState: ProvableNetworkState, }) {} export class BlockProverMultiTransactionExecutionData extends Struct({ transaction1: TransactionProverTransactionArguments, transaction2: TransactionProverTransactionArguments, - networkState: NetworkState, + networkState: ProvableNetworkState, }) {} export type TransactionProof = Proof< diff --git a/packages/protocol/src/prover/transaction/TransactionProver.ts b/packages/protocol/src/prover/transaction/TransactionProver.ts index 6c686ba17..0d91a7071 100644 --- a/packages/protocol/src/prover/transaction/TransactionProver.ts +++ b/packages/protocol/src/prover/transaction/TransactionProver.ts @@ -11,7 +11,7 @@ import { import { Bool, Field, SelfProof, VerificationKey, ZkProgram } from "o1js"; import { inject, injectable, injectAll } from "tsyringe"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; import { ProtocolModule } from "../../protocol/ProtocolModule"; import { MethodPublicOutput } from "../../model/MethodPublicOutput"; import { @@ -102,7 +102,7 @@ export class TransactionProverZkProgrammable extends ZkProgrammable< fromState: TransactionProverState, runtimeOutput: MethodPublicOutput, executionData: ApplyTransactionArguments, - networkState: NetworkState + networkState: ProvableNetworkState ): Promise { const { transaction, signature } = executionData; diff --git a/packages/protocol/src/settlement/contracts/settlement/BridgingSettlementContract.ts b/packages/protocol/src/settlement/contracts/settlement/BridgingSettlementContract.ts index 4865e4ec5..66e4d845a 100644 --- a/packages/protocol/src/settlement/contracts/settlement/BridgingSettlementContract.ts +++ b/packages/protocol/src/settlement/contracts/settlement/BridgingSettlementContract.ts @@ -19,7 +19,7 @@ import { } from "o1js"; import { container } from "tsyringe"; -import { NetworkState } from "../../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../../model/network/NetworkState"; import { DispatchContractType } from "../DispatchSmartContract"; import { BridgeContractType } from "../BridgeContract"; import { TokenBridgeDeploymentAuth } from "../authorizations/TokenBridgeDeploymentAuth"; @@ -168,8 +168,8 @@ export abstract class BridgingSettlementContractBase blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ) { await super.settleBase( @@ -265,8 +265,8 @@ export class BridgingSettlementContract blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ) { return await this.settleBaseBridging( diff --git a/packages/protocol/src/settlement/contracts/settlement/SettlementBase.ts b/packages/protocol/src/settlement/contracts/settlement/SettlementBase.ts index cc6401c03..152c6eda0 100644 --- a/packages/protocol/src/settlement/contracts/settlement/SettlementBase.ts +++ b/packages/protocol/src/settlement/contracts/settlement/SettlementBase.ts @@ -20,7 +20,7 @@ import { import { container } from "tsyringe"; import { BlockHashMerkleTree } from "../../../prover/block/accummulators/BlockHashMerkleTree"; -import { NetworkState } from "../../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../../model/network/NetworkState"; import { ProvableSettlementHook, SettlementHookInputs, @@ -70,8 +70,8 @@ export interface SettlementContractType { blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ) => Promise; } @@ -111,15 +111,15 @@ export abstract class SettlementBase this.sequencerKey.set(sequencer.x); this.stateRoot.set(LinkedMerkleTree.EMPTY_ROOT); this.blockHashRoot.set(Field(BlockHashMerkleTree.EMPTY_ROOT)); - this.networkStateHash.set(NetworkState.empty().hash()); + this.networkStateHash.set(ProvableNetworkState.empty().hash()); } abstract settle( blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ): Promise; @@ -134,8 +134,8 @@ export abstract class SettlementBase blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ) { const { diff --git a/packages/protocol/src/settlement/contracts/settlement/SettlementContract.ts b/packages/protocol/src/settlement/contracts/settlement/SettlementContract.ts index 95321684f..2fa4a2476 100644 --- a/packages/protocol/src/settlement/contracts/settlement/SettlementContract.ts +++ b/packages/protocol/src/settlement/contracts/settlement/SettlementContract.ts @@ -12,7 +12,7 @@ import { } from "o1js"; import { O1PublicKeyOption } from "@proto-kit/common"; -import { NetworkState } from "../../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../../model/network/NetworkState"; import { DynamicBlockProof, @@ -59,8 +59,8 @@ export class SettlementContract blockProof: DynamicBlockProof, signature: Signature, publicKey: PublicKey, - inputNetworkState: NetworkState, - outputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, + outputNetworkState: ProvableNetworkState, newPromisedMessagesHash: Field ): Promise { await super.settleBase( diff --git a/packages/protocol/src/settlement/modularity/ProvableSettlementHook.ts b/packages/protocol/src/settlement/modularity/ProvableSettlementHook.ts index 67148bfa1..9b3cd3c33 100644 --- a/packages/protocol/src/settlement/modularity/ProvableSettlementHook.ts +++ b/packages/protocol/src/settlement/modularity/ProvableSettlementHook.ts @@ -2,7 +2,7 @@ import { Field, PublicKey, UInt32 } from "o1js"; import { InferProofBase } from "@proto-kit/common"; import { ProtocolModule } from "../../protocol/ProtocolModule"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; import type { BlockProof } from "../../prover/block/BlockProvable"; import type { SettlementContractType } from "../contracts/settlement/SettlementBase"; @@ -19,8 +19,8 @@ export type SettlementStateRecord = { export type SettlementHookInputs = { blockProof: InputBlockProof; - fromNetworkState: NetworkState; - toNetworkState: NetworkState; + fromNetworkState: ProvableNetworkState; + toNetworkState: ProvableNetworkState; newPromisedMessagesHash: Field; contractState: SettlementStateRecord; currentL1BlockHeight: UInt32; diff --git a/packages/protocol/src/state/context/RuntimeMethodExecutionContext.ts b/packages/protocol/src/state/context/RuntimeMethodExecutionContext.ts index a497533c0..cad75f50d 100644 --- a/packages/protocol/src/state/context/RuntimeMethodExecutionContext.ts +++ b/packages/protocol/src/state/context/RuntimeMethodExecutionContext.ts @@ -7,7 +7,7 @@ import { import { StateTransition } from "../../model/StateTransition"; import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction"; -import { NetworkState } from "../../model/network/NetworkState"; +import { ProvableNetworkState } from "../../model/network/NetworkState"; const errors = { setupNotCalled: () => @@ -35,13 +35,13 @@ export class RuntimeProvableMethodExecutionResult extends ProvableMethodExecutio export interface RuntimeMethodExecutionData { transaction: RuntimeTransaction; - networkState: NetworkState; + networkState: ProvableNetworkState; } export class RuntimeMethodExecutionDataStruct extends Struct({ transaction: RuntimeTransaction, - networkState: NetworkState, + networkState: ProvableNetworkState, }) implements RuntimeMethodExecutionData {} diff --git a/packages/protocol/src/utils/utils.ts b/packages/protocol/src/utils/utils.ts index 661477742..7ebb8022e 100644 --- a/packages/protocol/src/utils/utils.ts +++ b/packages/protocol/src/utils/utils.ts @@ -1,7 +1,7 @@ import { Bool, Field, Poseidon, Provable } from "o1js"; import floor from "lodash/floor"; -import { NetworkStateJson } from "../model/network/NetworkState"; +import { NetworkState } from "../model/network/NetworkState"; export type ReturnType = FunctionType extends ( ...args: any[] @@ -35,11 +35,11 @@ export function notInCircuit(): MethodDecorator { }; } -export function networkStateToFields(json: NetworkStateJson): Field[] { +export function networkStateToFields(json: NetworkState): Field[] { return [Field(json.block.height), Field(json.previous.rootHash)]; } -export function hashNetworkState(json: NetworkStateJson): string { +export function hashNetworkState(json: NetworkState): string { return Poseidon.hash(networkStateToFields(json)).toString(); } diff --git a/packages/protocol/test/BlockProver.test.ts b/packages/protocol/test/BlockProver.test.ts index 44b49dc6b..d52cc235c 100644 --- a/packages/protocol/test/BlockProver.test.ts +++ b/packages/protocol/test/BlockProver.test.ts @@ -9,7 +9,7 @@ import "reflect-metadata"; import { MethodPublicOutput, - NetworkState, + ProvableNetworkState, SignedTransaction, StateTransitionProverPublicInput, StateTransitionProverPublicOutput, @@ -59,7 +59,7 @@ class RuntimeZkProgrammable extends ZkProgrammable< } describe("blockProver", () => { - const networkState = new NetworkState({ + const networkState = new ProvableNetworkState({ block: { height: UInt64.zero, }, @@ -78,7 +78,7 @@ describe("blockProver", () => { protocolHash: Field, tx: SignedTransaction, // eslint-disable-next-line @typescript-eslint/no-shadow - networkState: NetworkState + networkState: ProvableNetworkState ): BlockProverProofPair { const transactionHash = tx.transaction.hash(); const sthash = Field(123); diff --git a/packages/protocol/test/State.test.ts b/packages/protocol/test/State.test.ts index cc51bc5de..e645b3156 100644 --- a/packages/protocol/test/State.test.ts +++ b/packages/protocol/test/State.test.ts @@ -4,7 +4,7 @@ import { Bool, Field, UInt64 } from "o1js"; import { container } from "tsyringe"; import { - NetworkState, + ProvableNetworkState, RuntimeMethodExecutionContext, RuntimeTransaction, State, @@ -18,7 +18,7 @@ describe("state", () => { executionContext.setup({ transaction: undefined as unknown as RuntimeTransaction, - networkState: undefined as unknown as NetworkState, + networkState: undefined as unknown as ProvableNetworkState, }); }); diff --git a/packages/protocol/test/state/assert/assert.test.ts b/packages/protocol/test/state/assert/assert.test.ts index 475959073..18d769a27 100644 --- a/packages/protocol/test/state/assert/assert.test.ts +++ b/packages/protocol/test/state/assert/assert.test.ts @@ -6,7 +6,7 @@ import { container } from "tsyringe"; import { assert } from "../../../src/state/assert/assert"; import { RuntimeMethodExecutionContext } from "../../../src/state/context/RuntimeMethodExecutionContext"; import { RuntimeTransaction } from "../../../src/model/transaction/RuntimeTransaction"; -import { NetworkState } from "../../../src/model/network/NetworkState"; +import { ProvableNetworkState } from "../../../src/model/network/NetworkState"; describe("assert", () => { const defaultStatusMessage = "something went wrong"; @@ -17,7 +17,7 @@ describe("assert", () => { executionContext.setup({ transaction: undefined as unknown as RuntimeTransaction, - networkState: undefined as unknown as NetworkState, + networkState: undefined as unknown as ProvableNetworkState, }); }); diff --git a/packages/sdk/src/client/ClientAppChain.ts b/packages/sdk/src/client/ClientAppChain.ts index e46414d1b..14507050e 100644 --- a/packages/sdk/src/client/ClientAppChain.ts +++ b/packages/sdk/src/client/ClientAppChain.ts @@ -9,7 +9,7 @@ import { } from "@proto-kit/module"; import { MandatoryProtocolModulesRecord, - NetworkState, + ProvableNetworkState, Protocol, ProtocolModule, ProtocolModulesRecord, @@ -112,7 +112,7 @@ export class ClientAppChain< executionContext.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); executionContext.setSimulated(true); diff --git a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts index 17b690c74..f140f8371 100644 --- a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts @@ -3,7 +3,7 @@ import { NetworkStateTransportModule, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; import { gql } from "@urql/core"; import { GraphqlClient } from "./GraphqlClient"; @@ -28,9 +28,9 @@ export class GraphqlNetworkStateTransportModule super(); } - private async retrieveNetworkState(path: string): Promise { + private async retrieveNetworkState(path: string): Promise { const query = gql` - query NetworkState { + query ProvableNetworkState { network { ${path} { block { @@ -58,7 +58,7 @@ export class GraphqlNetworkStateTransportModule try { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return json as NetworkStateJson; + return json as NetworkState; } catch (e) { if (e instanceof Error) { throw errors.receivedResultMalformed(e.message); @@ -69,15 +69,15 @@ export class GraphqlNetworkStateTransportModule throw new Error(queryResult.error.message); } - public async getProvenNetworkState(): Promise { + public async getProvenNetworkState(): Promise { return await this.retrieveNetworkState("proven"); } - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { return await this.retrieveNetworkState("staged"); } - public async getUnprovenNetworkState(): Promise { + public async getUnprovenNetworkState(): Promise { return await this.retrieveNetworkState("unproven"); } } diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index a5fcec1d3..66b746a3e 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -6,7 +6,7 @@ import { BatchStorage, AppChainModule, } from "@proto-kit/sequencer"; -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; import { ModuleContainerLike } from "@proto-kit/common"; @injectable() @@ -38,7 +38,7 @@ export class BlockStorageNetworkStateModule } public async getUnprovenNetworkState(): Promise< - NetworkStateJson | undefined + NetworkState | undefined > { const latestBlock = await this.unprovenStorage.getLatestBlock(); return latestBlock?.block.networkState.during; @@ -48,12 +48,12 @@ export class BlockStorageNetworkStateModule * Staged network state is the networkstate after the latest unproven block * with afterBundle() hooks executed */ - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { const result = await this.unprovenStorage.getLatestBlock(); return result?.result.afterNetworkState; } - public async getProvenNetworkState(): Promise { + public async getProvenNetworkState(): Promise { const batch = await this.provenStorage.getLatestBatch(); if (batch !== undefined) { @@ -73,7 +73,7 @@ export class BlockStorageNetworkStateModule } return block.networkState.during; // TODO Probably metadata.after? } - // TODO Replace by NetworkState.empty() across the whole application + // TODO Replace by ProvableNetworkState.empty() across the whole application return undefined; } } diff --git a/packages/sdk/test/blockProof/blockProof.test.ts b/packages/sdk/test/blockProof/blockProof.test.ts index 21fed17b6..b5a711302 100644 --- a/packages/sdk/test/blockProof/blockProof.test.ts +++ b/packages/sdk/test/blockProof/blockProof.test.ts @@ -7,7 +7,7 @@ import { import { Field, PrivateKey, UInt64 as O1UInt64, Signature } from "o1js"; import { BlockProverPublicOutput, - NetworkState, + ProvableNetworkState, ProvableTransactionHook, RuntimeMethodExecutionContext, RuntimeTransaction, @@ -74,7 +74,7 @@ describe.skip("blockProof", () => { context.setup({ transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), }); const balancesMethodId = appChain.runtime.methodIdResolver.getMethodId( @@ -95,7 +95,7 @@ describe.skip("blockProof", () => { methodId: Field(balancesMethodId), argsHash: Field(0), }), - networkState: NetworkState.empty(), + networkState: ProvableNetworkState.empty(), signature: Signature.create(PrivateKey.random(), [Field(0)]), prover: { incomingMessagesHash: Field(0), diff --git a/packages/sequencer/src/helpers/query/NetworkStateQuery.ts b/packages/sequencer/src/helpers/query/NetworkStateQuery.ts index 878be0916..c11e2d6f1 100644 --- a/packages/sequencer/src/helpers/query/NetworkStateQuery.ts +++ b/packages/sequencer/src/helpers/query/NetworkStateQuery.ts @@ -1,4 +1,4 @@ -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; import { NetworkStateTransportModule } from "./NetworkStateTransportModule"; @@ -7,15 +7,15 @@ export class NetworkStateQuery { private readonly transportModule: NetworkStateTransportModule ) {} - public get unproven(): Promise { + public get unproven(): Promise { return this.transportModule.getUnprovenNetworkState(); } - public get stagedUnproven(): Promise { + public get stagedUnproven(): Promise { return this.transportModule.getStagedNetworkState(); } - public get proven(): Promise { + public get proven(): Promise { return this.transportModule.getProvenNetworkState(); } } diff --git a/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts b/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts index 9e01c5df9..1a6cd91d4 100644 --- a/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts +++ b/packages/sequencer/src/helpers/query/NetworkStateTransportModule.ts @@ -1,7 +1,7 @@ -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; export interface NetworkStateTransportModule { - getUnprovenNetworkState: () => Promise; - getStagedNetworkState: () => Promise; - getProvenNetworkState: () => Promise; + getUnprovenNetworkState: () => Promise; + getStagedNetworkState: () => Promise; + getProvenNetworkState: () => Promise; } diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index fcdaf12da..d3cee93f3 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -9,8 +9,8 @@ import { AccountStateHook, BlockHashMerkleTree, MandatoryProtocolModulesRecord, + ProvableNetworkState, NetworkState, - NetworkStateJson, Protocol, ProvableHookBlockState, RuntimeMethodExecutionContext, @@ -110,7 +110,7 @@ export class PrivateMempool ); } - public async getStagedNetworkState(): Promise { + public async getStagedNetworkState(): Promise { const result = await this.unprovenQueue.getLatestBlock(); return result?.result.afterNetworkState; } @@ -127,11 +127,11 @@ export class PrivateMempool const baseCachedStateService = new CachedStateService(this.stateService); - // Should provide NetworkState to checkTxValid. + // Should provide ProvableNetworkState to checkTxValid. const stagedNetworkState = await this.getStagedNetworkState(); const networkState = - stagedNetworkState || NetworkState.toJSON(NetworkState.empty()); + stagedNetworkState || ProvableNetworkState.toJSON(ProvableNetworkState.empty()); const validationEnabled = this.config.validationEnabled ?? false; const sortedTxs = validationEnabled @@ -160,7 +160,7 @@ export class PrivateMempool transactions: PendingTransactionJSONType[], baseService: CachedStateService, stateServiceProvider: StateServiceProvider, - networkState: NetworkStateJson, + networkState: NetworkState, limit?: number ) { const executionContext = container.resolve( @@ -196,8 +196,8 @@ export class PrivateMempool : Field(0), }; - const provableNetworkState = new NetworkState( - NetworkState.fromJSON(networkState) + const provableNetworkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(networkState) ); let pendingTransaction: PendingTransaction; diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 9208bed58..3fd090156 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -2,7 +2,7 @@ import { inject } from "tsyringe"; import { BlockProverPublicInput, BlockProverPublicOutput, - NetworkStateJson, + NetworkState, } from "@proto-kit/protocol"; import { Field, Proof } from "o1js"; import { log, noop } from "@proto-kit/common"; @@ -179,8 +179,8 @@ export class BatchProducerModule extends SequencerModule { ): Promise<{ proof: Proof; changes: CachedLinkedLeafStore; - fromNetworkState: NetworkStateJson; - toNetworkState: NetworkStateJson; + fromNetworkState: NetworkState; + toNetworkState: NetworkState; }> { if (blocks.length === 0 || blocks.flat(1).length === 0) { throw errors.blockWithoutTxs(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index f342cfa08..622c5fca2 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -3,7 +3,7 @@ import { BeforeBlockHookArguments, MandatoryProtocolModulesRecord, MinaActionsHashList, - NetworkState, + ProvableNetworkState, Protocol, ProtocolModulesRecord, ProvableBlockHook, @@ -64,7 +64,7 @@ export class BlockProductionService { @trace("block.hook.before") public async executeBeforeBlockHook( args: BeforeBlockHookArguments, - inputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, cachedStateService: CachedStateService ) { this.stateServiceProvider.setCurrentStateService(cachedStateService); @@ -77,7 +77,7 @@ export class BlockProductionService { const executionResult = await executeWithExecutionContext( async () => - await this.blockHooks.reduce>( + await this.blockHooks.reduce>( async (networkState, hook) => await hook.beforeBlock(await networkState, args), Promise.resolve(inputNetworkState) @@ -132,7 +132,7 @@ export class BlockProductionService { // Get used networkState by executing beforeBlock() hooks const beforeHookResult = await this.executeBeforeBlockHook( toProvableHookBlockState(blockState), - new NetworkState(NetworkState.fromJSON(lastResult.afterNetworkState)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(lastResult.afterNetworkState)), stateService ); @@ -186,7 +186,7 @@ export class BlockProductionService { networkState: { before: lastResult.afterNetworkState, - during: NetworkState.toJSON(networkState), + during: ProvableNetworkState.toJSON(networkState), }, beforeBlockStateTransitions: beforeBlockStateTransitions.map( (st: UntypedStateTransition) => st.toJSON() diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index b598a2a46..aa7b79552 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -6,7 +6,7 @@ import { BlockHashMerkleTreeWitness, BlockHashTreeEntry, MandatoryProtocolModulesRecord, - NetworkState, + ProvableNetworkState, Protocol, ProtocolModulesRecord, ProvableBlockHook, @@ -92,7 +92,7 @@ export class BlockResultService { @trace("block.hook.after") public async executeAfterBlockHook( args: AfterBlockHookArguments, - inputNetworkState: NetworkState, + inputNetworkState: ProvableNetworkState, asyncStateService: AsyncStateService ) { const cachedStateService = new CachedStateService(asyncStateService); @@ -106,7 +106,7 @@ export class BlockResultService { const executionResult = await executeWithExecutionContext( async () => - await this.blockHooks.reduce>( + await this.blockHooks.reduce>( async (networkState, hook) => await hook.afterBlock(await networkState, args), Promise.resolve(inputNetworkState) @@ -228,7 +228,7 @@ export class BlockResultService { transactionsHash: Field(block.transactionsHash), eternalTransactionsHash: Field(block.toEternalTransactionsHash), }, - new NetworkState(NetworkState.fromJSON(block.networkState.during)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(block.networkState.during)), stateService ); @@ -246,7 +246,7 @@ export class BlockResultService { return { result: { - afterNetworkState: NetworkState.toJSON(methodResult), + afterNetworkState: ProvableNetworkState.toJSON(methodResult), // This is the state root after the last tx and the afterBlock hook stateRoot: FieldString(stateRoot), witnessedRoots: [FieldString(witnessedStateRoot)], diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 1aa48733f..0f83057d7 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -2,7 +2,7 @@ import assert from "node:assert"; import { container, inject, injectable, Lifecycle, scoped } from "tsyringe"; import { - NetworkState, + ProvableNetworkState, Protocol, ProtocolModulesRecord, ProvableTransactionHook, @@ -334,7 +334,7 @@ export class TransactionExecutionService { public async createExecutionTraces( asyncStateService: CachedStateService, transactions: PendingTransactionJSONType[], - networkState: NetworkState, + networkState: ProvableNetworkState, state: BlockTrackers ): Promise<{ blockState: BlockTrackers; @@ -415,7 +415,7 @@ export class TransactionExecutionService { { networkState, hash: networkStateHash, - }: { networkState: NetworkState; hash: Field }, + }: { networkState: ProvableNetworkState; hash: Field }, state: BlockTrackers, newState: BlockTrackers ): Promise<{ diff --git a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts index f49b40f99..eea3e14ff 100644 --- a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts @@ -2,7 +2,7 @@ import { inject, injectable, Lifecycle, scoped } from "tsyringe"; import { BlockProvable, BlockProverPublicInput, - NetworkState, + ProvableNetworkState, Protocol, StateTransitionProof, StateTransitionProvable, @@ -33,7 +33,7 @@ import { executeWithPrefilledStateService } from "./TransactionProvingTask"; export interface NewBlockProverParameters { publicInput: BlockProverPublicInput; - networkState: NetworkState; + networkState: ProvableNetworkState; blockWitness: BlockHashMerkleTreeWitness; deferSTProof: Bool; afterBlockRootWitness: WitnessedRootWitness; diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 0141301ee..8f58319a5 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -6,8 +6,8 @@ import { } from "@proto-kit/module"; import { MethodPublicOutput, + ProvableNetworkState, NetworkState, - NetworkStateJson, RuntimeMethodExecutionContext, } from "@proto-kit/protocol"; import { Proof } from "o1js"; @@ -33,13 +33,13 @@ type RuntimeProof = Proof; export interface RuntimeProofParameters { tx: PendingTransaction; - networkState: NetworkState; + networkState: ProvableNetworkState; state: TaskStateRecord; } export interface RuntimeProofParametersJson { tx: PendingTransactionJSONType; - networkState: NetworkStateJson; + networkState: NetworkState; state: TaskStateRecordJson; } @@ -75,8 +75,8 @@ export class RuntimeProvingTask ): Promise { // Convert from JSON to provable types at the proving boundary const tx = PendingTransaction.fromJSON(input.tx); - const networkState = new NetworkState( - NetworkState.fromJSON(input.networkState) + const networkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(input.networkState) ); const state = taskStateRecordFromJson(input.state); diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts index 164f5d474..01f587593 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts @@ -1,7 +1,7 @@ import { BlockHashMerkleTreeWitness, BlockProverPublicInput, - NetworkState, + ProvableNetworkState, ReturnType, StateTransitionProof, StateTransitionProverPublicInput, @@ -24,7 +24,7 @@ interface JsonType { input2: string; params: { publicInput: ReturnType; - networkState: ReturnType; + networkState: ReturnType; blockWitness: ReturnType; startingStateBeforeHook: TaskStateRecordJson; startingStateAfterHook: TaskStateRecordJson; @@ -61,7 +61,7 @@ export class NewBlockProvingParametersSerializer params: { publicInput: BlockProverPublicInput.toJSON(input.params.publicInput), - networkState: NetworkState.toJSON(input.params.networkState), + networkState: ProvableNetworkState.toJSON(input.params.networkState), blockWitness: BlockHashMerkleTreeWitness.toJSON( input.params.blockWitness @@ -91,8 +91,8 @@ export class NewBlockProvingParametersSerializer jsonObject.params.publicInput ), - networkState: new NetworkState( - NetworkState.fromJSON(jsonObject.params.networkState) + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(jsonObject.params.networkState) ), blockWitness: new BlockHashMerkleTreeWitness( diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts index d057221af..7cf7c45e1 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts @@ -1,7 +1,7 @@ import { BlockProverPublicInput, MethodPublicOutput, - NetworkState, + ProvableNetworkState, ReturnType, RuntimeTransaction, TransactionProverTransactionArguments, @@ -28,13 +28,13 @@ export type TransactionProverTransactionArgumentsJSON = { export type SingleExecutionDataJSON = { transaction: TransactionProverTransactionArgumentsJSON; - networkState: ReturnType; + networkState: ReturnType; }; export type MultiExecutionDataJSON = { transaction1: TransactionProverTransactionArgumentsJSON; transaction2: TransactionProverTransactionArgumentsJSON; - networkState: ReturnType; + networkState: ReturnType; }; export type TransactionProverTaskParametersJSON< @@ -114,7 +114,7 @@ export class TransactionProvingTaskParameterSerializer if (type === TransactionProvingType.SINGLE) { const { executionData } = parameters; const executionDataJson: SingleExecutionDataJSON = { - networkState: NetworkState.toJSON(executionData.networkState), + networkState: ProvableNetworkState.toJSON(executionData.networkState), transaction: this.transactionProverArgumentsToJson( executionData.transaction ), @@ -131,7 +131,7 @@ export class TransactionProvingTaskParameterSerializer } else { const { executionData } = parameters; const executionDataJson: MultiExecutionDataJSON = { - networkState: NetworkState.toJSON(executionData.networkState), + networkState: ProvableNetworkState.toJSON(executionData.networkState), transaction1: this.transactionProverArgumentsToJson( executionData.transaction1 ), @@ -181,8 +181,8 @@ export class TransactionProvingTaskParameterSerializer transaction: this.transactionProverArgumentsFromJson( parameters.executionData.transaction ), - networkState: new NetworkState( - NetworkState.fromJSON(parameters.executionData.networkState) + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(parameters.executionData.networkState) ), }, }, @@ -206,8 +206,8 @@ export class TransactionProvingTaskParameterSerializer transaction2: this.transactionProverArgumentsFromJson( parameters.executionData.transaction2 ), - networkState: new NetworkState( - NetworkState.fromJSON(parameters.executionData.networkState) + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(parameters.executionData.networkState) ), }, }, diff --git a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts index 8b04a8fb6..b489c557f 100644 --- a/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BatchTracingService.ts @@ -2,7 +2,7 @@ import { log, yieldSequential } from "@proto-kit/common"; import { AppliedBatchHashList, MinaActionsHashList, - NetworkState, + ProvableNetworkState, TransactionHashList, WitnessedRootHashList, } from "@proto-kit/protocol"; @@ -49,8 +49,8 @@ export class BatchTracingService { incomingMessages: new MinaActionsHashList( Field(block.block.fromMessagesHash) ), - networkState: new NetworkState( - NetworkState.fromJSON(block.block.networkState.before) + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.block.networkState.before) ), }; } diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 0974ab3c1..ca7710355 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -2,7 +2,7 @@ import { BlockHashMerkleTreeWitness, BlockProverPublicInput, BlockProverState, - NetworkState, + ProvableNetworkState, WitnessedRootWitness, } from "@proto-kit/protocol"; import { Bool, Field } from "o1js"; @@ -94,8 +94,8 @@ export class BlockTracingService { eternalTransactionsHash: Field(block.block.fromEternalTransactionsHash), incomingMessagesHash: Field(block.block.fromMessagesHash), transactionsHash: Field(0), - networkStateHash: new NetworkState( - NetworkState.fromJSON(block.block.networkState.before) + networkStateHash: new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.block.networkState.before) ).hash(), witnessedRootsHash: state.witnessedRoots.commitment, pendingSTBatchesHash: state.pendingSTBatches.commitment, @@ -109,8 +109,8 @@ export class BlockTracingService { const blockTrace = { publicInput, - networkState: new NetworkState( - NetworkState.fromJSON(block.block.networkState.before) + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.block.networkState.before) ), deferSTProof: Bool(!includeSTProof), blockWitness: new BlockHashMerkleTreeWitness( @@ -128,8 +128,8 @@ export class BlockTracingService { ), applied: Bool(true), }); - state.networkState = new NetworkState( - NetworkState.fromJSON(block.block.networkState.during) + state.networkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.block.networkState.during) ); const [afterState, transactionTraces] = await yieldSequential( @@ -178,8 +178,8 @@ export class BlockTracingService { (st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) ) ); - state.networkState = new NetworkState( - NetworkState.fromJSON(block.result.afterNetworkState) + state.networkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.result.afterNetworkState) ); return [ diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index d7bc60d8a..95c34ac57 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -3,7 +3,7 @@ import { BlockProverMultiTransactionExecutionData, BlockProverPublicInput, BlockProverSingleTransactionExecutionData, - NetworkState, + ProvableNetworkState, TransactionProverTransactionArguments, } from "@proto-kit/protocol"; import { Bool, Field } from "o1js"; @@ -125,14 +125,14 @@ export class TransactionTracingService { private createRuntimeProofParams( tx: TransactionExecutionResultJson, - networkState: NetworkState + networkState: ProvableNetworkState ): RuntimeProofParametersJson { const stBatch = STBatchFromJson(tx.stateTransitions[1]); const startingState = collectStartingState(stBatch.stateTransitions); return { tx: tx.tx, - networkState: NetworkState.toJSON(networkState), + networkState: ProvableNetworkState.toJSON(networkState), state: startingState, }; } diff --git a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts index 2349b3b85..764f80dfe 100644 --- a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts @@ -5,7 +5,7 @@ import { BridgingSettlementModulesRecord, DynamicBlockProof, MandatoryProtocolModulesRecord, - NetworkState, + ProvableNetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -102,8 +102,8 @@ export class BridgingSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), - new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.fromNetworkState)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.toNetworkState)), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts index 665f9e7d0..38b1ad1a0 100644 --- a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts @@ -5,7 +5,7 @@ import { BridgingSettlementModulesRecord, DynamicBlockProof, MandatoryProtocolModulesRecord, - NetworkState, + ProvableNetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -94,8 +94,8 @@ export class VanillaSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - new NetworkState(NetworkState.fromJSON(batch.fromNetworkState)), - new NetworkState(NetworkState.fromJSON(batch.toNetworkState)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.fromNetworkState)), + new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.toNetworkState)), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/storage/model/Batch.ts b/packages/sequencer/src/storage/model/Batch.ts index a14685c42..731b14718 100644 --- a/packages/sequencer/src/storage/model/Batch.ts +++ b/packages/sequencer/src/storage/model/Batch.ts @@ -1,5 +1,5 @@ import { JsonProof } from "o1js"; -import { NetworkStateJson } from "@proto-kit/protocol"; +import { NetworkState } from "@proto-kit/protocol"; import { PendingTransaction } from "../../mempool/PendingTransaction"; @@ -16,6 +16,6 @@ export interface Batch { } export interface SettleableBatch extends Batch { - fromNetworkState: NetworkStateJson; - toNetworkState: NetworkStateJson; + fromNetworkState: NetworkState; + toNetworkState: NetworkState; } diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 6db865573..b76fe23fc 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -4,8 +4,8 @@ import { BlockHashMerkleTree, BlockHashMerkleTreeWitness, BlockHashMerkleTreeWitnessJson, + ProvableNetworkState, NetworkState, - NetworkStateJson, } from "@proto-kit/protocol"; import { LinkedMerkleTree } from "@proto-kit/common"; @@ -62,8 +62,8 @@ export interface Block { previousBlockHash: FieldString | undefined; height: FieldString; networkState: { - before: NetworkStateJson; - during: NetworkStateJson; + before: NetworkState; + during: NetworkState; }; transactions: TransactionExecutionResultJson[]; @@ -98,7 +98,7 @@ export interface BlockResult { witnessedRoots: [string]; stateRoot: string; blockHashRoot: string; - afterNetworkState: NetworkStateJson; + afterNetworkState: NetworkState; afterBlockStateTransitions: UntypedStateTransitionJson[]; blockHashWitness: BlockHashMerkleTreeWitnessJson; } @@ -131,8 +131,8 @@ export const BlockWithResult = { toEternalTransactionsHash: FieldString(0), transactions: [], networkState: { - before: NetworkState.toJSON(NetworkState.empty()), - during: NetworkState.toJSON(NetworkState.empty()), + before: ProvableNetworkState.toJSON(ProvableNetworkState.empty()), + during: ProvableNetworkState.toJSON(ProvableNetworkState.empty()), }, fromBlockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), fromMessagesHash: FieldString(0), @@ -143,7 +143,7 @@ export const BlockWithResult = { previousBlockHash: undefined, }, result: { - afterNetworkState: NetworkState.toJSON(NetworkState.empty()), + afterNetworkState: ProvableNetworkState.toJSON(ProvableNetworkState.empty()), stateRoot: String(LinkedMerkleTree.EMPTY_ROOT), blockHashRoot: String(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], diff --git a/packages/sequencer/test/settlement/Settlement-only.ts b/packages/sequencer/test/settlement/Settlement-only.ts index 9ef519695..7339f7906 100644 --- a/packages/sequencer/test/settlement/Settlement-only.ts +++ b/packages/sequencer/test/settlement/Settlement-only.ts @@ -12,7 +12,7 @@ import { import { BlockProverPublicInput, ContractArgsRegistry, - NetworkState, + ProvableNetworkState, Protocol, SettlementContractModule, } from "@proto-kit/protocol"; @@ -278,8 +278,8 @@ export const settlementOnlyTestFn = ( }); const settlement = settlementModule.getSettlementContract(); - const afterNetworkState = new NetworkState( - NetworkState.fromJSON(lastBlock!.result?.afterNetworkState!) + const afterNetworkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(lastBlock!.result?.afterNetworkState!) ); expectDefined(lastBlock); expectDefined(lastBlock.result); diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index a071be100..0b50b82e7 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -11,7 +11,7 @@ import { BridgeContract, ContractArgsRegistry, DispatchSmartContract, - NetworkState, + ProvableNetworkState, Protocol, ReturnType, SettlementContractModule, @@ -650,7 +650,7 @@ export const settlementTestFn = ( console.log(networkstateHash.zkapp!.appState.map((x) => x.toString())); console.log( - `Empty Network State ${NetworkState.empty().hash().toString()}` + `Empty Network State ${ProvableNetworkState.empty().hash().toString()}` ); console.log(hashNetworkState(batch!.toNetworkState)); console.log(hashNetworkState(batch2!.fromNetworkState)); From 9b8bd332ebf25d46b866b8152b9b391df0118e51 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 12:26:55 +0300 Subject: [PATCH 33/63] refactor: remove hashNetworkState, use .hash() of ProvableNetworkState --- packages/protocol/src/utils/utils.ts | 10 ----- .../test/integration/BlockProduction-test.ts | 18 +++++++-- .../sequencer/test/settlement/Settlement.ts | 37 ++++++++++++++++--- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/packages/protocol/src/utils/utils.ts b/packages/protocol/src/utils/utils.ts index 7ebb8022e..660d8c456 100644 --- a/packages/protocol/src/utils/utils.ts +++ b/packages/protocol/src/utils/utils.ts @@ -1,8 +1,6 @@ import { Bool, Field, Poseidon, Provable } from "o1js"; import floor from "lodash/floor"; -import { NetworkState } from "../model/network/NetworkState"; - export type ReturnType = FunctionType extends ( ...args: any[] ) => infer Return @@ -35,14 +33,6 @@ export function notInCircuit(): MethodDecorator { }; } -export function networkStateToFields(json: NetworkState): Field[] { - return [Field(json.block.height), Field(json.previous.rootHash)]; -} - -export function hashNetworkState(json: NetworkState): string { - return Poseidon.hash(networkStateToFields(json)).toString(); -} - export function stringToField(value: string) { const fieldSize = Field.sizeInBytes - 1; diff --git a/packages/sequencer/test/integration/BlockProduction-test.ts b/packages/sequencer/test/integration/BlockProduction-test.ts index 3113bd743..bc0417f95 100644 --- a/packages/sequencer/test/integration/BlockProduction-test.ts +++ b/packages/sequencer/test/integration/BlockProduction-test.ts @@ -20,7 +20,7 @@ import { Path, Protocol, PROTOKIT_PREFIXES, - hashNetworkState, + ProvableNetworkState, } from "@proto-kit/protocol"; import { Bool, Field, PrivateKey, PublicKey, Struct, UInt64 } from "o1js"; import "reflect-metadata"; @@ -232,8 +232,20 @@ export function testBlockProduction< expectDefined(latestBlockWithResult); expectDefined(latestBlockWithResult.result); expect( - hashNetworkState(latestBlockWithResult.result.afterNetworkState) - ).toStrictEqual(hashNetworkState(batch!.toNetworkState)); + new ProvableNetworkState( + ProvableNetworkState.fromJSON( + latestBlockWithResult.result.afterNetworkState + ) + ) + .hash() + .toString() + ).toStrictEqual( + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch!.toNetworkState) + ) + .hash() + .toString() + ); // Check if the batchstorage has received the block const batchStorage = sequencer.resolve("BatchStorage") as BatchStorage; diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 0b50b82e7..48f597699 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -15,7 +15,6 @@ import { Protocol, ReturnType, SettlementContractModule, - hashNetworkState, } from "@proto-kit/protocol"; import { ClientAppChain, @@ -533,7 +532,11 @@ export const settlementTestFn = ( expectDefined(lastBlock); expectDefined(lastBlock.result); expect(settlement.networkStateHash.get().toString()).toStrictEqual( - hashNetworkState(lastBlock!.result.afterNetworkState).toString() + new ProvableNetworkState( + ProvableNetworkState.fromJSON(lastBlock!.result.afterNetworkState) + ) + .hash() + .toString() ); expect(settlement.stateRoot.get().toString()).toStrictEqual( lastBlock!.result.stateRoot.toString() @@ -652,11 +655,33 @@ export const settlementTestFn = ( console.log( `Empty Network State ${ProvableNetworkState.empty().hash().toString()}` ); - console.log(hashNetworkState(batch!.toNetworkState)); - console.log(hashNetworkState(batch2!.fromNetworkState)); + console.log( + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch!.toNetworkState) + ) + .hash() + .toString() + ); + console.log( + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch2!.fromNetworkState) + ) + .hash() + .toString() + ); - expect(hashNetworkState(batch!.toNetworkState)).toStrictEqual( - hashNetworkState(batch2!.fromNetworkState) + expect( + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch!.toNetworkState) + ) + .hash() + .toString() + ).toStrictEqual( + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch2!.fromNetworkState) + ) + .hash() + .toString() ); expect(batch2!.blockHashes).toHaveLength(1); From ffdf8dd32a478411a3ac8b68d8956987caac28da Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 13:00:46 +0300 Subject: [PATCH 34/63] refactor: change type of block height from string to number --- packages/api/src/metrics/SequencerInstrumentation.ts | 2 +- packages/indexer/test/IndexerNotifier.test.ts | 2 +- .../src/services/prisma/mappers/BlockMapper.ts | 2 +- .../graphql/GraphqlBlockExplorerTransportModule.ts | 2 +- .../helpers/query/BlockExplorerTransportModule.ts | 2 +- .../src/protocol/production/flow/TransactionFlow.ts | 2 +- .../production/sequencing/BlockProductionService.ts | 6 +++--- .../production/tracing/BlockTracingService.ts | 2 +- packages/sequencer/src/storage/model/Block.ts | 12 ++++++------ .../sequencing/atomic-block-production.test.ts | 2 +- packages/stack/test/graphql/graphql.test.ts | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/api/src/metrics/SequencerInstrumentation.ts b/packages/api/src/metrics/SequencerInstrumentation.ts index 956a2a69b..491a74912 100644 --- a/packages/api/src/metrics/SequencerInstrumentation.ts +++ b/packages/api/src/metrics/SequencerInstrumentation.ts @@ -15,7 +15,7 @@ export class SequencerInstrumentation extends InstrumentationBase<{}> { super("protokit", "canary", {}); if (trigger !== undefined) { trigger.events.on("block-produced", (block) => { - this.blockProduced(parseInt(block.height, 10)); + this.blockProduced(block.height); }); } } diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 073bc4959..f75bdeca9 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -183,7 +183,7 @@ describe.skip("IndexerNotifier", () => { .resolve(IndexBlockTaskParametersSerializer) .fromJSON(addTaskSpy.mock.lastCall?.[0].payload!); - expect(block.height).toBe("0"); + expect(block.height).toBe(0); expect(block.transactions.length).toBe(2); }); }); diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index 9b5576fe4..228503120 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -23,7 +23,7 @@ export class BlockMapper implements ObjectMapper { }, hash: input.hash, - height: input.height.toString(), + height: input.height, fromEternalTransactionsHash: input.fromEternalTransactionsHash, toEternalTransactionsHash: input.toEternalTransactionsHash, fromBlockHashRoot: input.fromBlockHashRoot, diff --git a/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts b/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts index 4537db272..d9b13cdde 100644 --- a/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlBlockExplorerTransportModule.ts @@ -110,7 +110,7 @@ export class GraphqlBlockExplorerTransportModule return { hash: blockData.hash, - height: blockData.height.toString(), + height: blockData.height, previousBlockHash, transactionsHash: blockData.transactionsHash, transactions: blockData.txs, diff --git a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts index 61c1c2538..b7830d07a 100644 --- a/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts +++ b/packages/sequencer/src/helpers/query/BlockExplorerTransportModule.ts @@ -19,7 +19,7 @@ export interface ClientTransaction { export interface ClientBlock { hash: string; previousBlockHash: string | undefined; - height: string; + height: number; transactions: ClientTransaction[]; transactionsHash: string; } diff --git a/packages/sequencer/src/protocol/production/flow/TransactionFlow.ts b/packages/sequencer/src/protocol/production/flow/TransactionFlow.ts index d124a352c..728524a3d 100644 --- a/packages/sequencer/src/protocol/production/flow/TransactionFlow.ts +++ b/packages/sequencer/src/protocol/production/flow/TransactionFlow.ts @@ -53,7 +53,7 @@ export class TransactionFlow { public async proveRuntimes( trace: TransactionTrace, - blockHeight: string, + blockHeight: number, txIndex: number, callback: (params: TransactionProvingTaskParameters) => Promise ) { diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 622c5fca2..6764edf99 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -175,9 +175,9 @@ export class BlockProductionService { newBlockState.eternalTransactionsList.commitment ), height: - FieldString(lastBlock.hash) !== "0" - ? FieldString(BigInt(lastBlock.height) + 1n) - : FieldString(0), + (lastBlock.hash) !== "0" + ? lastBlock.height + 1 + : 0, fromBlockHashRoot: FieldString(lastResult.blockHashRoot), fromMessagesHash: lastBlock.toMessagesHash, fromStateRoot: FieldString(lastResult.stateRoot), diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index ca7710355..b55b724ee 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -68,7 +68,7 @@ export type BlockTrace = { blockParams: NewBlockProverParameters; transactions: TransactionTrace[]; // Only for debugging and logging - height: string; + height: number; }; @injectable() diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index b76fe23fc..5b42c5959 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -60,7 +60,7 @@ export interface TransactionExecutionResultJson { export interface Block { hash: FieldString; previousBlockHash: FieldString | undefined; - height: FieldString; + height: number; networkState: { before: NetworkState; during: NetworkState; @@ -94,10 +94,10 @@ export const Block = { }; export interface BlockResult { - blockHash: string; - witnessedRoots: [string]; - stateRoot: string; - blockHashRoot: string; + blockHash: FieldString; + witnessedRoots: [FieldString]; + stateRoot: FieldString; + blockHashRoot: FieldString; afterNetworkState: NetworkState; afterBlockStateTransitions: UntypedStateTransitionJson[]; blockHashWitness: BlockHashMerkleTreeWitnessJson; @@ -125,7 +125,7 @@ export const BlockWithResult = { block: { hash: FieldString(0), - height: FieldString(0), + height: 0, transactionsHash: FieldString(0), fromEternalTransactionsHash: FieldString(0), toEternalTransactionsHash: FieldString(0), diff --git a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts index bcb8ab6ac..1606cb97f 100644 --- a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts +++ b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts @@ -115,6 +115,6 @@ describe("atomic block production", () => { const block = await trigger.produceBlock(); expectDefined(block); - expect(block.height).toBe("1"); + expect(block.height).toBe(1); }); }); diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index bc8405f14..5a60ef9bf 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -238,7 +238,7 @@ describe("graphql client test", () => { expect(block?.hash).toBe(heightResult?.hash.toString()); // Block heights should match - expect(block?.height).toBe(heightResult?.height.toString()); + expect(block?.height).toBe(heightResult?.height); // Previous block hashes should match expect(block?.previousBlockHash).toBe( From ebed33ec237fedc5f24358acc5f8b09a03686994 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 14:13:42 +0300 Subject: [PATCH 35/63] refactor: simplify ClientBlock construction and fix type in Block --- .../sdk/src/query/InMemoryBlockExplorer.ts | 22 ++----------------- packages/sequencer/src/storage/model/Block.ts | 4 ++-- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index 96915fe8a..51b695c61 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -60,33 +60,15 @@ export class InMemoryBlockExplorer return undefined; } - // Convert block.transactions to ClientTransaction format - const clientTransactions: ClientTransaction[] = block.transactions.map( - (txResult) => ({ - tx: { - hash: txResult.tx.hash, - methodId: txResult.tx.methodId, - nonce: txResult.tx.nonce, - sender: txResult.tx.sender, - argsFields: txResult.tx.argsFields, - auxiliaryData: txResult.tx.auxiliaryData, - signature: txResult.tx.signature, - isMessage: txResult.tx.isMessage, - }, - status: txResult.status, - statusMessage: txResult.statusMessage, - }) - ); + const clientTransactions: ClientTransaction[] = block.transactions; return { - hash: block.hash, + ...block, previousBlockHash: block.previousBlockHash !== undefined ? block.previousBlockHash : undefined, - height: block.height, transactions: clientTransactions, - transactionsHash: block.transactionsHash, }; } } diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 5b42c5959..229300146 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -144,8 +144,8 @@ export const BlockWithResult = { }, result: { afterNetworkState: ProvableNetworkState.toJSON(ProvableNetworkState.empty()), - stateRoot: String(LinkedMerkleTree.EMPTY_ROOT), - blockHashRoot: String(BlockHashMerkleTree.EMPTY_ROOT), + stateRoot: FieldString(LinkedMerkleTree.EMPTY_ROOT), + blockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], blockHashWitness: BlockHashMerkleTreeWitness.toJSON( BlockHashMerkleTree.WITNESS.dummy() From 11f7b854b8937c0e7552b1163e85aa8477bee1e2 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 20:29:36 +0300 Subject: [PATCH 36/63] refactor: update UntypedStateTranisition and UntypedOption --- .../production/helpers/UntypedOption.ts | 49 ++++++++++------ .../helpers/UntypedStateTransition.ts | 58 +++++-------------- 2 files changed, 45 insertions(+), 62 deletions(-) diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts index bad6e485f..6e2c8f796 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts @@ -1,15 +1,30 @@ -import { Bool, Field } from "o1js"; +import { Bool, Field, Poseidon } from "o1js"; import { Option, OptionBase } from "@proto-kit/protocol"; /** * Option facilitating in-circuit values that may or may not exist. */ -export class UntypedOption extends OptionBase { +export class UntypedOption { + public constructor( + public isSome: boolean, + public value: string[], + public isForcedSome: boolean + ) {} + + public get treeValue() { + const treeValue = Poseidon.hash(this.encodeValueToFields()); + + if(this.isSome && !this.isForcedSome){ + return treeValue.toString(); + } + return "0"; + } + public static fromOption(option: Option | Option) { return new UntypedOption( - option.isSome, - option.encodeValueToFields(), - option.isForcedSome + option.isSome.toBoolean(), + option.encodeValueToFields().map((f) => f.toString()), + option.isForcedSome.toBoolean() ); } @@ -22,26 +37,22 @@ export class UntypedOption extends OptionBase { value: string[]; isForcedSome: boolean; }): UntypedOption { - return new UntypedOption( - Bool(isSome), - value.map((fieldString) => Field(fieldString)), - Bool(isForcedSome) - ); + return new UntypedOption(isSome, value, isForcedSome); } - public constructor( - isSome: Bool, - public value: Field[], - enforceEmpty: Bool - ) { - super(isSome, enforceEmpty); + public toJSON(){ + return { + isSome: this.isSome, + value: this.value, + isForcedSome: this.isForcedSome + }; } public clone() { return new UntypedOption(this.isSome, this.value, this.isForcedSome); } - protected encodeValueToFields(): Field[] { - return this.value; + public encodeValueToFields(): Field[] { + return this.value.map((fieldString) => Field(fieldString)) } -} +} \ No newline at end of file diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index 36d72332f..5923c3eb5 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -1,22 +1,8 @@ import { Field } from "o1js"; -import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; +import { ProvableOption, ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; -export interface UntypedStateTransitionJson { - path: string; - from: { - isSome: boolean; - isForcedSome: boolean; - value: string[]; - }; - to: { - isSome: boolean; - isForcedSome: boolean; - value: string[]; - }; -} - /** * Generic state transition that constraints the current method circuit * to external state, by providing a state anchor. @@ -24,7 +10,7 @@ export interface UntypedStateTransitionJson { export class UntypedStateTransition { public static fromStateTransition(st: StateTransition) { return new UntypedStateTransition( - st.path, + st.path.toString(), UntypedOption.fromOption(st.fromValue), UntypedOption.fromOption(st.toValue) ); @@ -40,45 +26,31 @@ export class UntypedStateTransition { to: Parameters[0]; }): UntypedStateTransition { return new UntypedStateTransition( - Field(path), + path, UntypedOption.fromJSON(from), UntypedOption.fromJSON(to) ); } public constructor( - public path: Field, - public fromValue: UntypedOption, - public toValue: UntypedOption + public path: string, + public from: UntypedOption, + public to: UntypedOption ) {} - public get from() { - const from = this.fromValue.clone(); - from.forceSome(); - return from; - } - - public get to() { - return this.toValue.clone(); + public toJSON() { + return { + path: this.path, + from: this.from.toJSON(), + to: this.to.toJSON(), + }; } - /** - * Converts a StateTransition to a ProvableStateTransition, - * while enforcing the 'from' property to be 'Some' in all cases. - */ public toProvable(): ProvableStateTransition { return new ProvableStateTransition({ - path: this.path, - from: this.from.toProvable(), - to: this.to.toProvable(), + path: Field(this.path), + from: new ProvableOption(ProvableOption.fromFields(this.from.value.map(Field))), + to: new ProvableOption(ProvableOption.fromFields(this.to.value.map(Field))) }); } - - public toJSON() { - return { - path: this.path.toString(), - from: this.fromValue.toJSON(), - to: this.toValue.toJSON(), - }; - } } From 4a77e29d6bcd71bb88eff62fd848aec86f263bac Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 22:20:44 +0300 Subject: [PATCH 37/63] refactor: refactor away inheritance of PendingTransaction --- .../src/mempool/PendingTransaction.ts | 97 +++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index 09ac55639..c22f7572f 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -13,6 +13,7 @@ import { SignedTransaction, UInt64Option, } from "@proto-kit/protocol"; +import { FieldString } from "../helpers/utils"; export type UnsignedTransactionBody = { methodId: Field; @@ -105,17 +106,17 @@ export class UnsignedTransaction implements UnsignedTransactionBody { } public signed(signature: Signature): PendingTransaction { - // eslint-disable-next-line @typescript-eslint/no-use-before-define return new PendingTransaction({ - methodId: this.methodId, - sender: this.sender, - nonce: this.nonce, - signature, - argsFields: this.argsFields, + hash: this.hash().toString(), + methodId: this.methodId.toString(), + sender: this.sender.toBase58(), + nonce: this.nonce.toString(), + signature: { r: signature.r.toJSON(), s: signature.s.toJSON() }, + argsFields: this.argsFields.map((f) => f.toString()), auxiliaryData: this.auxiliaryData, isMessage: this.isMessage, }); - } +} } export interface PendingTransactionJSONType { @@ -132,64 +133,62 @@ export interface PendingTransactionJSONType { isMessage: boolean; } -export class PendingTransaction extends UnsignedTransaction { +export class PendingTransaction { public static fromJSON( object: PendingTransactionJSONType ): PendingTransaction { - return new PendingTransaction( - { - methodId: Field.fromJSON(object.methodId), - nonce: UInt64.from(object.nonce), - sender: PublicKey.fromBase58(object.sender), - argsFields: object.argsFields.map((x) => Field.fromJSON(x)), - signature: Signature.fromJSON(object.signature), - auxiliaryData: object.auxiliaryData.slice(), - isMessage: object.isMessage, - }, - Field(object.hash) - ); + return new PendingTransaction({ + hash: object.hash, + methodId: object.methodId, + nonce: object.nonce, + sender: object.sender, + argsFields: object.argsFields.slice(), + auxiliaryData: object.auxiliaryData.slice(), + signature: { r: object.signature.r, s: object.signature.s }, + isMessage: object.isMessage, + }); } - public signature: Signature; - public constructor( - data: { - methodId: Field; - nonce: UInt64; - sender: PublicKey; - signature: Signature; - argsFields: Field[]; + public data: { + hash: FieldString; + methodId: FieldString; + nonce: string; + sender: string; + argsFields: FieldString[]; auxiliaryData: string[]; + signature: { r: string; s: string }; isMessage: boolean; - }, - memoizedHash?: Field - ) { - super(data, memoizedHash); - this.signature = data.signature; - } + } + ) {} public toJSON(): PendingTransactionJSONType { return { - hash: this.hash().toString(), - methodId: this.methodId.toJSON(), - nonce: this.nonce.toString(), - sender: this.sender.toBase58(), - argsFields: this.argsFields.map((x) => x.toJSON()), - auxiliaryData: this.auxiliaryData.slice(), - isMessage: this.isMessage, - - signature: { - r: this.signature.r.toJSON(), - - s: this.signature.s.toJSON(), - }, + hash: this.data.hash, + methodId: this.data.methodId, + nonce: this.data.nonce, + sender: this.data.sender, + argsFields: this.data.argsFields.slice(), + auxiliaryData: this.data.auxiliaryData.slice(), + signature: { r: this.data.signature.r, s: this.data.signature.s }, + isMessage: this.data.isMessage, }; } + public toRuntimeTransaction(): RuntimeTransaction { + const isSome = Bool(!this.data.isMessage); + return new RuntimeTransaction({ + methodId: Field(this.data.methodId), + argsHash: Poseidon.hash(this.data.argsFields.map((f) => Field(f))), + nonce: new UInt64Option({ value: UInt64.from(this.data.nonce), isSome }), + sender: new PublicKeyOption({ value: PublicKey.fromBase58(this.data.sender), isSome }), + }); + } + public toProtocolTransaction(): SignedTransaction { return new SignedTransaction({ transaction: this.toRuntimeTransaction(), - signature: this.signature, + signature: Signature.fromJSON(this.data.signature), }); } -} +} \ No newline at end of file From 231d6548081199b819d6b4022bd966f3495855a5 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sat, 17 Jan 2026 23:31:35 +0300 Subject: [PATCH 38/63] refactor: make original types non-provable and remove unnecessary code --- packages/sequencer/src/storage/model/Block.ts | 91 +------------------ 1 file changed, 3 insertions(+), 88 deletions(-) diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 229300146..57a0957cb 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -11,11 +11,9 @@ import { LinkedMerkleTree } from "@proto-kit/common"; import { PendingTransaction, - PendingTransactionJSONType, } from "../../mempool/PendingTransaction"; import { UntypedStateTransition, - UntypedStateTransitionJson, } from "../../protocol/production/helpers/UntypedStateTransition"; import { FieldString } from "../../helpers/utils"; @@ -27,24 +25,6 @@ export interface StateTransitionBatch { export interface TransactionExecutionResult { tx: PendingTransaction; stateTransitions: StateTransitionBatch[]; - status: Bool; - hooksStatus: Bool; - statusMessage?: string; - events: { - eventName: string; - data: Field[]; - source: "afterTxHook" | "beforeTxHook" | "runtime"; - }[]; -} - -export interface StateTransitionBatchJson { - stateTransitions: UntypedStateTransitionJson[]; - applied: boolean; -} - -export interface TransactionExecutionResultJson { - tx: PendingTransactionJSONType; - stateTransitions: StateTransitionBatchJson[]; status: boolean; hooksStatus: boolean; statusMessage?: string; @@ -66,7 +46,7 @@ export interface Block { during: NetworkState; }; - transactions: TransactionExecutionResultJson[]; + transactions: TransactionExecutionResult[]; transactionsHash: FieldString; fromEternalTransactionsHash: FieldString; @@ -76,7 +56,7 @@ export interface Block { toEternalTransactionsHash: FieldString; toMessagesHash: FieldString; - beforeBlockStateTransitions: UntypedStateTransitionJson[]; + beforeBlockStateTransitions: UntypedStateTransition[]; } // eslint-disable-next-line @typescript-eslint/no-redeclare @@ -99,7 +79,7 @@ export interface BlockResult { stateRoot: FieldString; blockHashRoot: FieldString; afterNetworkState: NetworkState; - afterBlockStateTransitions: UntypedStateTransitionJson[]; + afterBlockStateTransitions: UntypedStateTransition[]; blockHashWitness: BlockHashMerkleTreeWitnessJson; } @@ -155,68 +135,3 @@ export const BlockWithResult = { }, }) satisfies BlockWithResult, }; - -export function txResultToJson( - txResult: TransactionExecutionResult -): TransactionExecutionResultJson { - return { - tx: txResult.tx.toJSON(), - stateTransitions: txResult.stateTransitions.map((batch) => ({ - stateTransitions: batch.stateTransitions.map((st) => st.toJSON()), - applied: batch.applied, - })), - status: txResult.status.toBoolean(), - hooksStatus: txResult.hooksStatus.toBoolean(), - statusMessage: txResult.statusMessage, - events: txResult.events.map((e) => ({ - eventName: e.eventName, - data: e.data.map((f) => f.toString()), - source: e.source, - })), - }; -} - -export function txResultFromJson( - json: TransactionExecutionResultJson -): TransactionExecutionResult { - return { - tx: PendingTransaction.fromJSON(json.tx), - stateTransitions: json.stateTransitions.map((batch) => ({ - stateTransitions: batch.stateTransitions.map((st) => - UntypedStateTransition.fromJSON(st) - ), - applied: batch.applied, - })), - status: Bool(json.status), - hooksStatus: Bool(json.hooksStatus), - statusMessage: json.statusMessage, - events: json.events.map((e) => ({ - eventName: e.eventName, - data: e.data.map((f) => Field(f)), - source: e.source, - })), - }; -} - -export function STBatchToJson( - stBatch: StateTransitionBatch -): StateTransitionBatchJson { - return { - stateTransitions: stBatch.stateTransitions.map( - (untypedST: UntypedStateTransition) => untypedST.toJSON() - ), - applied: stBatch.applied, - }; -} - -export function STBatchFromJson( - stBatch: StateTransitionBatchJson -): StateTransitionBatch { - return { - stateTransitions: stBatch.stateTransitions.map( - (untypedST: UntypedStateTransitionJson) => - UntypedStateTransition.fromJSON(untypedST) - ), - applied: stBatch.applied, - }; -} From b9267b8f98f8a88570d02cd4bad55d50616330d0 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 17:02:10 +0300 Subject: [PATCH 39/63] refactor: replace PendingTransactionJSONType with PendingTransaction --- .../api/src/graphql/modules/BlockResolver.ts | 2 +- .../src/graphql/modules/MempoolResolver.ts | 8 ++-- .../indexer/src/tasks/IndexPendingTxTask.ts | 8 ++-- .../src/tasks/IndexPendingTxTaskParameters.ts | 6 +-- .../services/prisma/PrismaMessageStorage.ts | 8 ++-- .../prisma/PrismaTransactionStorage.ts | 8 ++-- .../prisma/mappers/TransactionMapper.ts | 38 ++++++++-------- .../src/graphql/GraphqlTransactionSender.ts | 4 +- .../src/transaction/AppChainTransaction.ts | 2 +- .../transaction/InMemoryTransactionSender.ts | 6 +-- packages/sequencer/src/mempool/Mempool.ts | 5 +-- .../src/mempool/private/PrivateMempool.ts | 44 +++++++++---------- .../verification/TransactionValidator.ts | 24 ++++++---- .../src/protocol/baselayer/NoopBaseLayer.ts | 4 +- .../sequencing/BlockProducerModule.ts | 14 +++--- .../production/tasks/RuntimeProvingTask.ts | 35 ++++++--------- .../messages/IncomingMessageAdapter.ts | 4 +- .../messages/IncomingMessagesService.ts | 8 ++-- .../messages/MinaIncomingMessageAdapter.ts | 26 +++++++---- .../inmemory/InMemoryMessageStorage.ts | 10 ++--- .../inmemory/InMemoryTransactionStorage.ts | 23 +++++----- .../storage/repositories/MessageStorage.ts | 8 ++-- .../repositories/TransactionStorage.ts | 8 ++-- packages/sequencer/test/integration/utils.ts | 9 ++-- .../sequencer/test/settlement/Settlement.ts | 4 +- 25 files changed, 157 insertions(+), 159 deletions(-) diff --git a/packages/api/src/graphql/modules/BlockResolver.ts b/packages/api/src/graphql/modules/BlockResolver.ts index 257b3a9d0..0379478ff 100644 --- a/packages/api/src/graphql/modules/BlockResolver.ts +++ b/packages/api/src/graphql/modules/BlockResolver.ts @@ -13,7 +13,7 @@ export class BlockModel { Number(block.networkState.during.block.height), block.transactions.map((tx) => BatchTransactionModel.fromServiceLayerModel({ - tx: PendingTransaction.fromJSON(tx.tx), + tx: tx.tx, status: tx.status, statusMessage: tx.statusMessage, }) diff --git a/packages/api/src/graphql/modules/MempoolResolver.ts b/packages/api/src/graphql/modules/MempoolResolver.ts index 17b871af0..d26c85541 100644 --- a/packages/api/src/graphql/modules/MempoolResolver.ts +++ b/packages/api/src/graphql/modules/MempoolResolver.ts @@ -49,7 +49,7 @@ export class TransactionObject { isMessage, } = pt.toJSON(); return new TransactionObject( - pt.hash().toString(), + pt.data.hash, methodId, sender, nonce, @@ -125,10 +125,10 @@ export class MempoolResolver extends GraphqlModule { description: "Adds a transaction to the mempool and validates it", }) public async submitTx(@Arg("tx") tx: TransactionObject): Promise { - const decoded = PendingTransaction.fromJSON(tx).toJSON(); + const decoded = PendingTransaction.fromJSON(tx); await this.mempool.add(decoded); - return decoded.hash; + return decoded.data.hash; } // TODO Add retrieval of pending messages somewhere as well @@ -162,6 +162,6 @@ export class MempoolResolver extends GraphqlModule { }) public async transactions() { const txs = await this.transactionStorage.getPendingUserTransactions(); - return txs.map((x) => x.hash); + return txs.map((x) => x.data.hash); } } diff --git a/packages/indexer/src/tasks/IndexPendingTxTask.ts b/packages/indexer/src/tasks/IndexPendingTxTask.ts index 7583530ec..eddabbaa5 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTask.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTask.ts @@ -1,5 +1,5 @@ import { - PendingTransactionJSONType, + PendingTransaction, Task, TaskSerializer, TaskWorkerModule, @@ -13,7 +13,7 @@ import { IndexPendingTxTaskParametersSerializer } from "./IndexPendingTxTaskPara @injectable() export class IndexPendingTxTask extends TaskWorkerModule - implements Task + implements Task { public name = "index-pending-tx"; @@ -29,7 +29,7 @@ export class IndexPendingTxTask public async prepare(): Promise {} public async compute( - input: PendingTransactionJSONType + input: PendingTransaction ): Promise { try { await this.transactionStorage.pushUserTransaction(input); @@ -40,7 +40,7 @@ export class IndexPendingTxTask } } - public inputSerializer(): TaskSerializer { + public inputSerializer(): TaskSerializer { return this.taskSerializer; } diff --git a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts b/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts index f35643347..5c60be517 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts @@ -1,4 +1,4 @@ -import { PendingTransactionJSONType } from "@proto-kit/sequencer"; +import { PendingTransaction } from "@proto-kit/sequencer"; import { TransactionMapper } from "@proto-kit/persistance"; import { injectable } from "tsyringe"; @@ -6,13 +6,13 @@ import { injectable } from "tsyringe"; export class IndexPendingTxTaskParametersSerializer { public constructor(public transactionMapper: TransactionMapper) {} - public toJSON(parameters: PendingTransactionJSONType): string { + public toJSON(parameters: PendingTransaction): string { return JSON.stringify({ tx: this.transactionMapper.mapOut(parameters), }); } - public fromJSON(json: string): PendingTransactionJSONType { + public fromJSON(json: string): PendingTransaction { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const parsed = JSON.parse(json) as { tx: ReturnType; diff --git a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts index 623c6c484..d93b79769 100644 --- a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts @@ -1,6 +1,6 @@ import { MessageStorage, - PendingTransactionJSONType, + PendingTransaction, } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; @@ -24,7 +24,7 @@ export class PrismaMessageStorage implements MessageStorage { const batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }[] = []; let currentHash = fromMessagesHash; @@ -46,7 +46,7 @@ export class PrismaMessageStorage implements MessageStorage { | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; } | undefined > { @@ -87,7 +87,7 @@ export class PrismaMessageStorage implements MessageStorage { public async pushMessages( fromMessageHash: string, toMessageHash: string, - messages: PendingTransactionJSONType[] + messages: PendingTransaction[] ): Promise { const transactions = messages.map((message) => this.transactionMapper.mapOut(message) diff --git a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts index 00411b2ac..10a5b47e0 100644 --- a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts @@ -1,6 +1,6 @@ import { inject, injectable } from "tsyringe"; import { - PendingTransactionJSONType, + PendingTransaction, trace, Tracer, TransactionStorage, @@ -20,7 +20,7 @@ export class PrismaTransactionStorage implements TransactionStorage { @trace("db.txs.get") public async getPendingUserTransactions(): Promise< - PendingTransactionJSONType[] + PendingTransaction[] > { const { prismaClient } = this.connection; @@ -54,7 +54,7 @@ export class PrismaTransactionStorage implements TransactionStorage { } public async pushUserTransaction( - tx: PendingTransactionJSONType + tx: PendingTransaction ): Promise { const { prismaClient } = this.connection; @@ -68,7 +68,7 @@ export class PrismaTransactionStorage implements TransactionStorage { public async findTransaction(hash: string): Promise< | { - transaction: PendingTransactionJSONType; + transaction: PendingTransaction; block?: string; batch?: number; } diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index 2867aed66..b59bdf396 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -1,7 +1,7 @@ import { singleton, injectable } from "tsyringe"; import { - TransactionExecutionResultJson, - PendingTransactionJSONType, + TransactionExecutionResult, + PendingTransaction, } from "@proto-kit/sequencer"; import { Transaction as DBTransaction, @@ -16,10 +16,10 @@ import { EventArrayMapper } from "./EventMapper"; @singleton() @injectable() export class TransactionMapper - implements ObjectMapper + implements ObjectMapper { - public mapIn(input: DBTransaction): PendingTransactionJSONType { - return { + public mapIn(input: DBTransaction): PendingTransaction { + return new PendingTransaction({ hash: input.hash, methodId: input.methodId, nonce: input.nonce, @@ -31,20 +31,20 @@ export class TransactionMapper r: input.signature_r, s: input.signature_s, }, - }; + }); } - public mapOut(input: PendingTransactionJSONType): DBTransaction { + public mapOut(input: PendingTransaction): DBTransaction { return { - hash: input.hash, - methodId: input.methodId, - nonce: input.nonce, - sender: input.sender, - argsFields: input.argsFields, - auxiliaryData: input.auxiliaryData, - isMessage: input.isMessage, - signature_r: input.signature.r, - signature_s: input.signature.s, + hash: input.data.hash, + methodId: input.data.methodId, + nonce: input.data.nonce, + sender: input.data.sender, + argsFields: input.data.argsFields, + auxiliaryData: input.data.auxiliaryData, + isMessage: input.data.isMessage, + signature_r: input.data.signature.r, + signature_s: input.data.signature.s, }; } } @@ -53,7 +53,7 @@ export class TransactionMapper export class TransactionExecutionResultMapper implements ObjectMapper< - TransactionExecutionResultJson, + TransactionExecutionResult, [Omit, DBTransaction] > { @@ -65,7 +65,7 @@ export class TransactionExecutionResultMapper public mapIn( input: [Omit, DBTransaction] - ): TransactionExecutionResultJson { + ): TransactionExecutionResult { const executionResult = input[0]; return { tx: this.transactionMapper.mapIn(input[1]), @@ -80,7 +80,7 @@ export class TransactionExecutionResultMapper } mapOut( - input: TransactionExecutionResultJson + input: TransactionExecutionResult ): [Omit, DBTransaction] { const tx = this.transactionMapper.mapOut(input.tx); const executionResult = { diff --git a/packages/sdk/src/graphql/GraphqlTransactionSender.ts b/packages/sdk/src/graphql/GraphqlTransactionSender.ts index d1e649cc7..dfbcefb87 100644 --- a/packages/sdk/src/graphql/GraphqlTransactionSender.ts +++ b/packages/sdk/src/graphql/GraphqlTransactionSender.ts @@ -1,7 +1,7 @@ import { inject, injectable } from "tsyringe"; import { AppChainModule, - PendingTransactionJSONType, + PendingTransaction, } from "@proto-kit/sequencer"; import { gql } from "@urql/core"; @@ -20,7 +20,7 @@ export class GraphqlTransactionSender super(); } - public async send(transaction: PendingTransactionJSONType): Promise { + public async send(transaction: PendingTransaction): Promise { const query = gql` mutation SubmitTx($tx: TransactionObjectInput!) { submitTx(tx: $tx) diff --git a/packages/sdk/src/transaction/AppChainTransaction.ts b/packages/sdk/src/transaction/AppChainTransaction.ts index 1d9f30d08..ab6ea9ab5 100644 --- a/packages/sdk/src/transaction/AppChainTransaction.ts +++ b/packages/sdk/src/transaction/AppChainTransaction.ts @@ -48,6 +48,6 @@ export class AppChainTransaction { public async send() { this.hasPendingTransaction(this.transaction); // Wait for next commit - await this.transactionSender.send(this.transaction.toJSON()); + await this.transactionSender.send(this.transaction); } } diff --git a/packages/sdk/src/transaction/InMemoryTransactionSender.ts b/packages/sdk/src/transaction/InMemoryTransactionSender.ts index 96dc1ae69..50a76f9b9 100644 --- a/packages/sdk/src/transaction/InMemoryTransactionSender.ts +++ b/packages/sdk/src/transaction/InMemoryTransactionSender.ts @@ -1,13 +1,13 @@ import { PrivateMempool, AppChainModule, - PendingTransactionJSONType, + PendingTransaction, } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; import { ModuleContainerLike } from "@proto-kit/common"; export interface TransactionSender extends AppChainModule { - send: (transaction: PendingTransactionJSONType) => Promise; + send: (transaction: PendingTransaction) => Promise; } @injectable() @@ -25,7 +25,7 @@ export class InMemoryTransactionSender this.mempool = this.sequencer.resolveOrFail("Mempool", PrivateMempool); } - public async send(transaction: PendingTransactionJSONType) { + public async send(transaction: PendingTransaction) { await this.mempool.add(transaction); } } diff --git a/packages/sequencer/src/mempool/Mempool.ts b/packages/sequencer/src/mempool/Mempool.ts index 028bdf377..12b005043 100644 --- a/packages/sequencer/src/mempool/Mempool.ts +++ b/packages/sequencer/src/mempool/Mempool.ts @@ -2,7 +2,6 @@ import { EventEmittingComponent } from "@proto-kit/common"; import type { PendingTransaction, - PendingTransactionJSONType, } from "./PendingTransaction"; export type MempoolEvents = { @@ -15,12 +14,12 @@ export interface Mempool * Add a transaction to the mempool * @returns The new commitment to the mempool */ - add: (tx: PendingTransactionJSONType) => Promise; + add: (tx: PendingTransaction) => Promise; /** * Retrieve all transactions that are currently in the mempool */ - getTxs: (limit?: number) => Promise; + getTxs: (limit?: number) => Promise; removeTxs: (included: string[], dropped: string[]) => Promise; } diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index d3cee93f3..ca6179d17 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -22,7 +22,6 @@ import { Field } from "o1js"; import type { Mempool, MempoolEvents } from "../Mempool"; import { PendingTransaction, - PendingTransactionJSONType, } from "../PendingTransaction"; import { sequencerModule, @@ -38,7 +37,7 @@ import { Tracer } from "../../logging/Tracer"; import { trace } from "../../logging/trace"; type MempoolTransactionPaths = { - transaction: PendingTransactionJSONType; + transaction: PendingTransaction; paths: string[]; }; @@ -77,30 +76,30 @@ export class PrivateMempool return txs.length; } - public async add(tx: PendingTransactionJSONType): Promise { + public async add(tx: PendingTransaction): Promise { const [txValid, error] = this.transactionValidator.validateTx(tx); if (txValid) { const success = await this.transactionStorage.pushUserTransaction(tx); if (success) { this.events.emit( "mempool-transaction-added", - PendingTransaction.fromJSON(tx) + tx ); - log.trace(`Transaction added to mempool: ${tx.hash}`); + log.trace(`Transaction added to mempool: ${tx.data.hash}`); } else { - log.error(`Transaction ${tx.hash} rejected: already exists in mempool`); + log.error(`Transaction ${tx.data.hash} rejected: already exists in mempool`); } return success; } log.error( - `Validation of tx ${tx.hash} failed:`, + `Validation of tx ${tx.data.hash} failed:`, `${error ?? "unknown error"}` ); throw new Error( - `Validation of tx ${tx.hash} failed: ${error ?? "unknown error"}` + `Validation of tx ${tx.data.hash} failed: ${error ?? "unknown error"}` ); } @@ -121,7 +120,7 @@ export class PrivateMempool } @trace("mempool.get_txs") - public async getTxs(limit?: number): Promise { + public async getTxs(limit?: number): Promise { // TODO Add limit to the storage (or do something smarter entirely) const txs = await this.transactionStorage.getPendingUserTransactions(); @@ -157,7 +156,7 @@ export class PrivateMempool @trace("mempool.validate_txs") // eslint-disable-next-line sonarjs/cognitive-complexity private async checkTxValid( - transactions: PendingTransactionJSONType[], + transactions: PendingTransaction[], baseService: CachedStateService, stateServiceProvider: StateServiceProvider, networkState: NetworkState, @@ -169,10 +168,10 @@ export class PrivateMempool executionContext.clear(); // Initialize starting state - const sortedTransactions: PendingTransactionJSONType[] = []; + const sortedTransactions: PendingTransaction[] = []; const skippedTransactions: Record = {}; - let queue: PendingTransactionJSONType[] = [...transactions]; + let queue: PendingTransaction[] = [...transactions]; const previousBlock = await this.unprovenQueue.getLatestBlock(); @@ -200,23 +199,20 @@ export class PrivateMempool ProvableNetworkState.fromJSON(networkState) ); - let pendingTransaction: PendingTransaction; - while ( queue.length > 0 && sortedTransactions.length < (limit ?? Number.MAX_VALUE) ) { const [tx] = queue.splice(0, 1); - pendingTransaction = PendingTransaction.fromJSON(tx); const txStateService = new CachedStateService(baseService); stateServiceProvider.setCurrentStateService(txStateService); const contextInputs: RuntimeMethodExecutionData = { networkState: provableNetworkState, - transaction: pendingTransaction.toProtocolTransaction().transaction, + transaction: tx.toProtocolTransaction().transaction, }; executionContext.setup(contextInputs); - const signedTransaction = pendingTransaction.toProtocolTransaction(); + const signedTransaction = tx.toProtocolTransaction(); // eslint-disable-next-line no-await-in-loop await this.accountStateHook.beforeTransaction({ @@ -229,13 +225,13 @@ export class PrivateMempool executionContext.current().result; if (status.toBoolean()) { - log.trace(`Accepted tx ${tx.hash}`); + log.trace(`Accepted tx ${tx.data.hash}`); sortedTransactions.push(tx); // eslint-disable-next-line no-await-in-loop await txStateService.applyStateTransitions(stateTransitions); // eslint-disable-next-line no-await-in-loop await txStateService.mergeIntoParent(); - delete skippedTransactions[tx.hash]; + delete skippedTransactions[tx.data.hash]; if (Object.entries(skippedTransactions).length > 0) { // eslint-disable-next-line @typescript-eslint/no-loop-func stateTransitions.forEach((st) => { @@ -257,17 +253,17 @@ export class PrivateMempool }); if (removeTxWhen) { // eslint-disable-next-line no-await-in-loop - await this.transactionStorage.removeTx([tx.hash], "dropped"); + await this.transactionStorage.removeTx([tx.data.hash], "dropped"); log.trace( - `Deleting tx ${tx.hash} from mempool because removeTransactionWhen condition is satisfied` + `Deleting tx ${tx.data.hash} from mempool because removeTransactionWhen condition is satisfied` ); // eslint-disable-next-line no-continue continue; } - log.trace(`Skipped tx ${tx.hash} because ${statusMessage}`); - if (!(tx.hash in skippedTransactions)) { - skippedTransactions[tx.hash] = { + log.trace(`Skipped tx ${tx.data.hash} because ${statusMessage}`); + if (!(tx.data.hash in skippedTransactions)) { + skippedTransactions[tx.data.hash] = { transaction: tx, paths: stateTransitions .map((x) => x.path) diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index 665b99511..ecc2730b2 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -7,8 +7,9 @@ import { import { PendingTransaction, - PendingTransactionJSONType, } from "../PendingTransaction"; +import { Field, Poseidon, PublicKey, Signature, UInt64 } from "o1js"; +import { SignedTransaction } from "packages/protocol/dist"; @injectable() export class TransactionValidator { @@ -16,18 +17,18 @@ export class TransactionValidator { @inject("Runtime") private readonly runtime: Runtime ) {} - private validateMethod(tx: PendingTransactionJSONType): string | undefined { + private validateMethod(tx: PendingTransaction): string | undefined { // Check if method exists // We don't actually need to use runtime.getMethodById here, bcs the // module name validation happens inside getMethodNameFromId // and also in the next step const methodPath = this.runtime.methodIdResolver.getMethodNameFromId( - tx.methodId + tx.data.methodId ); if (methodPath === undefined) { - return `Method with id ${tx.methodId} does not exist`; + return `Method with id ${tx.data.methodId} does not exist`; } // Check if parameters are decodable @@ -42,7 +43,7 @@ export class TransactionValidator { } public validateTx( - tx: PendingTransactionJSONType + tx: PendingTransaction ): [boolean, string | undefined] { const methodError = this.validateMethod(tx); @@ -50,11 +51,16 @@ export class TransactionValidator { return [false, methodError]; } - const transaction = PendingTransaction.fromJSON(tx); + const signature = Signature.fromJSON(tx.data.signature) + const signatureData = SignedTransaction.getSignatureData({ + nonce: UInt64.from(tx.data.nonce), + methodId: Field(tx.data.methodId), + argsHash: Poseidon.hash(tx.data.argsFields.map((f) => Field(f))), + }); - const validSignature = transaction.signature.verify( - transaction.sender, - transaction.getSignatureData() + const validSignature = signature.verify( + PublicKey.fromBase58(tx.data.sender), + signatureData ); if (!validSignature.toBoolean()) { diff --git a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts index cc256a25a..9e64f6996 100644 --- a/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts +++ b/packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts @@ -7,7 +7,7 @@ import { sequencerModule, } from "../../sequencer/builder/SequencerModule"; import { IncomingMessageAdapter } from "../../settlement/messages/IncomingMessageAdapter"; -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; import { OutgoingMessageAdapter } from "../../settlement/messages/outgoing/OutgoingMessageCollector"; import { Block } from "../../storage/model/Block"; @@ -23,7 +23,7 @@ class NoopIncomingMessageAdapter implements IncomingMessageAdapter { ): Promise<{ from: string; to: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }> { return { from: "0", diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 3f15e0366..000f2bbb6 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -14,7 +14,7 @@ import { SequencerModule, } from "../../../sequencer/builder/SequencerModule"; import { BlockQueue } from "../../../storage/repositories/BlockStorage"; -import { PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../../mempool/PendingTransaction"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { @@ -74,7 +74,7 @@ export class BlockProducerModule extends SequencerModule { private prettyPrintBlockContents(block: Block) { block.transactions.forEach((tx, i) => { const methodName = this.methodIdResolver.getMethodNameFromId( - tx.tx.methodId + tx.tx.data.methodId ); if (!methodName) return; @@ -86,15 +86,15 @@ export class BlockProducerModule extends SequencerModule { log.info("---------------------------------------"); log.info(`Transaction #${i}`); - log.info("Sender:", tx.tx.sender, "Nonce:", tx.tx.nonce); + log.info("Sender:", tx.tx.data.sender, "Nonce:", tx.tx.data.nonce); log.info(`Method: ${methodName?.join(".")}`); log.info(); if (log.getLevel() <= log.levels.INFO) { Provable.log( "Arguments:", paramEncoder.decode( - tx.tx.argsFields.map((s) => Field(s)), - tx.tx.auxiliaryData + tx.tx.data.argsFields.map((s) => Field(s)), + tx.tx.data.auxiliaryData ) ); } @@ -175,7 +175,7 @@ export class BlockProducerModule extends SequencerModule { // Idea: Create a service that aggregates a bunch of different sources @trace("block.collect_inputs") private async collectProductionData(): Promise<{ - txs: PendingTransactionJSONType[]; + txs: PendingTransaction[]; metadata: BlockWithResult; }> { const txs = await this.mempool.getTxs(this.maximumBlockSize()); @@ -201,7 +201,7 @@ export class BlockProducerModule extends SequencerModule { }; } - let messages: PendingTransactionJSONType[] = []; + let messages: PendingTransaction[] = []; if (this.messageService !== undefined) { messages = await this.messageService.getPendingMessages(); } diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 8f58319a5..49f183819 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -10,7 +10,7 @@ import { NetworkState, RuntimeMethodExecutionContext, } from "@proto-kit/protocol"; -import { Proof } from "o1js"; +import { Field, Proof } from "o1js"; import { CompileRegistry } from "@proto-kit/common"; import { Task, TaskSerializer } from "../../../worker/flow/Task"; @@ -19,12 +19,9 @@ import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { PendingTransaction, - PendingTransactionJSONType, } from "../../../mempool/PendingTransaction"; import { TaskStateRecord, - TaskStateRecordJson, - taskStateRecordFromJson, } from "../tracing/BlockTracingService"; import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; @@ -37,17 +34,12 @@ export interface RuntimeProofParameters { state: TaskStateRecord; } -export interface RuntimeProofParametersJson { - tx: PendingTransactionJSONType; - networkState: NetworkState; - state: TaskStateRecordJson; -} @injectable() @scoped(Lifecycle.ContainerScoped) export class RuntimeProvingTask extends TaskWorkerModule - implements Task + implements Task { protected readonly runtimeZkProgrammable = this.runtime.zkProgrammable.zkProgram; @@ -62,7 +54,7 @@ export class RuntimeProvingTask super(); } - public inputSerializer(): TaskSerializer { + public inputSerializer(): TaskSerializer { return new RuntimeProofParametersSerializer(); } @@ -71,23 +63,22 @@ export class RuntimeProvingTask } public async compute( - input: RuntimeProofParametersJson + input: RuntimeProofParameters ): Promise { // Convert from JSON to provable types at the proving boundary - const tx = PendingTransaction.fromJSON(input.tx); - const networkState = new ProvableNetworkState( - ProvableNetworkState.fromJSON(input.networkState) - ); - const state = taskStateRecordFromJson(input.state); + const tx = input.tx; + const networkState = input.networkState; + + const state = input.state; - const method = this.runtime.getMethodById(tx.methodId.toString()); + const method = this.runtime.getMethodById(tx.data.methodId.toString()); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(tx.methodId.toString()); + .getMethodNameFromId(tx.data.methodId.toString()); if (methodDescriptors === undefined || method === undefined) { - throw new Error(`MethodId not found ${tx.methodId.toString()}`); + throw new Error(`MethodId not found ${tx.data.methodId}`); } const [moduleName, methodName] = methodDescriptors; @@ -97,8 +88,8 @@ export class RuntimeProvingTask methodName ); const decodedArguments = await parameterEncoder.decode( - tx.argsFields, - tx.auxiliaryData + tx.data.argsFields.map(Field), + tx.data.auxiliaryData ); const prefilledStateService = new PreFilledStateService(state); diff --git a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts index f552fdc53..363ff410b 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts @@ -1,6 +1,6 @@ import { PublicKey } from "o1js"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; /** * An interface provided by the BaseLayer via DependencyFactory, @@ -19,6 +19,6 @@ export interface IncomingMessageAdapter { ) => Promise<{ from: string; to: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }>; } diff --git a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts index 3eec0720a..6311cb30a 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessagesService.ts @@ -4,7 +4,7 @@ import { ACTIONS_EMPTY_HASH } from "@proto-kit/protocol"; import { SettlementStorage } from "../../storage/repositories/SettlementStorage"; import { MessageStorage } from "../../storage/repositories/MessageStorage"; import { BlockStorage } from "../../storage/repositories/BlockStorage"; -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; import type { BridgingModule } from "../BridgingModule"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; @@ -53,7 +53,7 @@ export class IncomingMessagesService { private isComplete( messages: - | { toMessagesHash: string; messages: PendingTransactionJSONType[] } + | { toMessagesHash: string; messages: PendingTransaction[] } | undefined, targetMessagesHash: string ) { @@ -64,7 +64,7 @@ export class IncomingMessagesService { private async ensureMessageCompleteness( messages: - | { toMessagesHash: string; messages: PendingTransactionJSONType[] } + | { toMessagesHash: string; messages: PendingTransaction[] } | undefined, fromMessagesHash: string, targetMessagesHash: string @@ -90,7 +90,7 @@ export class IncomingMessagesService { batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }[] ) { return { diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index ee80e33ff..150bc64c4 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -26,7 +26,6 @@ import { import { PendingTransaction, - PendingTransactionJSONType, } from "../../mempool/PendingTransaction"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; @@ -70,7 +69,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { private async mapActionToTransactions( tx: RuntimeTransaction, fieldArgs: Field[] - ): Promise { + ): Promise { const { methodId } = tx; const methodPointer = this.runtime.methodIdResolver.getMethodNameFromId( @@ -90,16 +89,25 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { const args = await methodEncoder.decode(fieldArgs, []); const { fields, auxiliary } = methodEncoder.encode(args); + const signature = Signature.create(PrivateKey.random(), [Field(0)]); + const hash = Poseidon.hash([ + methodId, + ...EMPTY_PUBLICKEY.toFields(), + ...UInt64.zero.toFields(), + Poseidon.hash(fields), + ]).toString(); + return new PendingTransaction({ - methodId, - sender: EMPTY_PUBLICKEY, - nonce: UInt64.zero, - signature: Signature.create(PrivateKey.random(), [Field(0)]), - argsFields: fields, + hash, + methodId: methodId.toString(), + sender: EMPTY_PUBLICKEY.toBase58(), + nonce: UInt64.zero.toString(), + signature: { r: signature.r.toJSON(), s: signature.s.toJSON() }, + argsFields: fields.map((f) => f.toString()), auxiliaryData: auxiliary, isMessage: true, - }).toJSON(); + }); } public async fetchPendingMessages( @@ -112,7 +120,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { ): Promise<{ from: string; to: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }> { const { network } = this.baseLayer; if (network === undefined) { diff --git a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts index b4f3df4e4..1bf671315 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryMessageStorage.ts @@ -1,6 +1,6 @@ import { injectable } from "tsyringe"; -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; import { MessageStorage } from "../repositories/MessageStorage"; @injectable() @@ -8,7 +8,7 @@ export class InMemoryMessageStorage implements MessageStorage { private messages: { [key: string]: { toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }; } = {}; @@ -16,7 +16,7 @@ export class InMemoryMessageStorage implements MessageStorage { | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; } | undefined > { @@ -37,7 +37,7 @@ export class InMemoryMessageStorage implements MessageStorage { const batches: { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }[] = []; let currentHash = fromMessagesHash; @@ -61,7 +61,7 @@ export class InMemoryMessageStorage implements MessageStorage { public async pushMessages( fromMessagesHash: string, toMessagesHash: string, - messages: PendingTransactionJSONType[] + messages: PendingTransaction[] ): Promise { this.messages[fromMessagesHash] = { messages, diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index a8e85cf9b..54dbb867b 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -1,14 +1,14 @@ import { inject, injectable } from "tsyringe"; import { TransactionStorage } from "../repositories/TransactionStorage"; -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; import { BlockStorage } from "../repositories/BlockStorage"; import { InMemoryBatchStorage } from "./InMemoryBatchStorage"; @injectable() export class InMemoryTransactionStorage implements TransactionStorage { - private queue: PendingTransactionJSONType[] = []; + private queue: PendingTransaction[] = []; private latestScannedBlock = -1; @@ -21,13 +21,12 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async removeTx(hashes: string[]) { const hashSet = new Set(hashes); this.queue = this.queue.filter((tx) => { - const { hash } = tx; - return !hashSet.has(hash); + return !hashSet.has(tx.data.hash); }); } public async getPendingUserTransactions(): Promise< - PendingTransactionJSONType[] + PendingTransaction[] > { const nextHeight = await this.blockStorage.getCurrentBlockHeight(); for ( @@ -38,8 +37,8 @@ export class InMemoryTransactionStorage implements TransactionStorage { // eslint-disable-next-line no-await-in-loop const block = await this.blockStorage.getBlockAt(height); if (block !== undefined) { - const hashes = block.transactions.map((tx) => tx.tx.hash); - this.queue = this.queue.filter((tx) => !hashes.includes(tx.hash)); + const hashes = block.transactions.map((tx) => tx.tx.data.hash); + this.queue = this.queue.filter((tx) => !hashes.includes(tx.data.hash)); } } this.latestScannedBlock = nextHeight - 1; @@ -48,10 +47,10 @@ export class InMemoryTransactionStorage implements TransactionStorage { } public async pushUserTransaction( - tx: PendingTransactionJSONType + tx: PendingTransaction ): Promise { const notInQueue = - this.queue.find((tx2) => tx2.hash === tx.hash) === undefined; + this.queue.find((tx2) => tx2.data.hash === tx.data.hash) === undefined; if (notInQueue) { this.queue.push(tx); } @@ -76,14 +75,14 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async findTransaction(hash: string): Promise< | { - transaction: PendingTransactionJSONType; + transaction: PendingTransaction; block?: string; batch?: number; } | undefined > { const pending = await this.getPendingUserTransactions(); - const pendingResult = pending.find((tx) => tx.hash === hash); + const pendingResult = pending.find((tx) => tx.data.hash === hash); if (pendingResult !== undefined) { return { transaction: pendingResult, @@ -98,7 +97,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { if (block === undefined) { return undefined; } - const txResult = block.transactions.find((tx) => tx.tx.hash === hash); + const txResult = block.transactions.find((tx) => tx.tx.data.hash === hash); if (txResult !== undefined) { // eslint-disable-next-line no-await-in-loop const batch = await this.findBatch(block.hash); diff --git a/packages/sequencer/src/storage/repositories/MessageStorage.ts b/packages/sequencer/src/storage/repositories/MessageStorage.ts index f137b6c0c..343e831c8 100644 --- a/packages/sequencer/src/storage/repositories/MessageStorage.ts +++ b/packages/sequencer/src/storage/repositories/MessageStorage.ts @@ -1,4 +1,4 @@ -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; /** * Interface to store Messages previously fetched by a IncomingMessageadapter @@ -7,14 +7,14 @@ export interface MessageStorage { pushMessages: ( fromMessagesHash: string, toMessagesHash: string, - messages: PendingTransactionJSONType[] + messages: PendingTransaction[] ) => Promise; getNextMessagesBatch: (fromMessagesHash: string) => Promise< | { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; } | undefined >; @@ -26,7 +26,7 @@ export interface MessageStorage { { fromMessagesHash: string; toMessagesHash: string; - messages: PendingTransactionJSONType[]; + messages: PendingTransaction[]; }[] >; } diff --git a/packages/sequencer/src/storage/repositories/TransactionStorage.ts b/packages/sequencer/src/storage/repositories/TransactionStorage.ts index 7cf87f1d8..ef353ad08 100644 --- a/packages/sequencer/src/storage/repositories/TransactionStorage.ts +++ b/packages/sequencer/src/storage/repositories/TransactionStorage.ts @@ -1,9 +1,9 @@ -import { PendingTransactionJSONType } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; export interface TransactionStorage { - pushUserTransaction: (tx: PendingTransactionJSONType) => Promise; + pushUserTransaction: (tx: PendingTransaction) => Promise; - getPendingUserTransactions: () => Promise; + getPendingUserTransactions: () => Promise; removeTx: (txHashes: string[], type: "included" | "dropped") => Promise; @@ -16,7 +16,7 @@ export interface TransactionStorage { */ findTransaction: (hash: string) => Promise< | { - transaction: PendingTransactionJSONType; + transaction: PendingTransaction; block?: string; batch?: number; } diff --git a/packages/sequencer/test/integration/utils.ts b/packages/sequencer/test/integration/utils.ts index 877391d83..e81267a4e 100644 --- a/packages/sequencer/test/integration/utils.ts +++ b/packages/sequencer/test/integration/utils.ts @@ -7,7 +7,7 @@ import { } from "@proto-kit/module"; import { - PendingTransactionJSONType, + PendingTransaction, StateRecord, UnsignedTransaction, UntypedStateTransition, @@ -19,7 +19,7 @@ export function createTransaction(spec: { method: [string, string]; args: ArgumentTypes; nonce: number; -}): PendingTransactionJSONType { +}): PendingTransaction { const methodId = spec.runtime.dependencyContainer .resolve("MethodIdResolver") .getMethodId(spec.method[0], spec.method[1]); @@ -40,15 +40,14 @@ export function createTransaction(spec: { isMessage: false, }) .sign(spec.privateKey) - .toJSON(); } export function collectStateDiff( stateTransitions: UntypedStateTransition[] ): StateRecord { - return stateTransitions.reduce>( + return stateTransitions.reduce( (state, st) => { - state[st.path.toString()] = st.toValue.value; + state[st.path] = st.to.value; return state; }, {} diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 48f597699..c0564113d 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -55,7 +55,7 @@ import { VanillaTaskWorkerModules, Sequencer, InMemoryMinaSigner, - PendingTransactionJSONType, + PendingTransaction, CircuitAnalysisModule, } from "../../src"; import { BlockProofSerializer } from "../../src/protocol/production/tasks/serializers/BlockProofSerializer"; @@ -229,7 +229,7 @@ export const settlementTestFn = ( async function createBatch( withTransactions: boolean, customNonce: number = 0, - txs: PendingTransactionJSONType[] = [] + txs: PendingTransaction[] = [] ) { const mempool = appChain.sequencer.resolve("Mempool") as PrivateMempool; if (withTransactions) { From 1ee230b619802187d61d94120b4fc1a2743a65de Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:16:07 +0300 Subject: [PATCH 40/63] refactor: move FieldString to common/utils --- packages/common/src/utils.ts | 16 ++++++++++++++++ packages/sequencer/src/helpers/utils.ts | 16 +--------------- .../sequencer/src/mempool/PendingTransaction.ts | 2 +- .../sequencing/BlockProductionService.ts | 2 +- .../production/sequencing/BlockResultService.ts | 2 +- packages/sequencer/src/storage/model/Block.ts | 2 +- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index 0576aacb5..039bf348f 100644 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -295,3 +295,19 @@ export function assertDefined( throw new Error(msg ?? "Value is undefined"); } } + + +/** + * Type for serialized {@link Field}. + */ +export type FieldString = string; +/** + * + * @param value Value to be converted to {@link Field}. + * @returns + */ +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const FieldString = ( + value: number | string | bigint | Field +): FieldString => String(value); + diff --git a/packages/sequencer/src/helpers/utils.ts b/packages/sequencer/src/helpers/utils.ts index e57c3db1e..8ec70c72d 100644 --- a/packages/sequencer/src/helpers/utils.ts +++ b/packages/sequencer/src/helpers/utils.ts @@ -193,18 +193,4 @@ export class PairProofTaskSerializer input.map((element) => this.proofSerializer.toJSONProof(element)) ); } -} - -/** - * Type for serialized {@link Field}. - */ -export type FieldString = string; -/** - * - * @param value Value to be converted to {@link Field}. - * @returns - */ -// eslint-disable-next-line @typescript-eslint/no-redeclare -export const FieldString = ( - value: number | string | bigint | Field -): FieldString => String(value); +} \ No newline at end of file diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index c22f7572f..70aeb980d 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -13,7 +13,7 @@ import { SignedTransaction, UInt64Option, } from "@proto-kit/protocol"; -import { FieldString } from "../helpers/utils"; +import { FieldString } from "@proto-kit/common"; export type UnsignedTransactionBody = { methodId: Field; diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 6764edf99..7a9f526a6 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -28,7 +28,7 @@ import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; -import { FieldString } from "../../../helpers/utils"; +import { FieldString } from "@proto-kit/common"; import { BlockTrackers, diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index aa7b79552..aab18d5aa 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -33,7 +33,7 @@ import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; import { AsyncLinkedLeafStore } from "../../../state/async/AsyncLinkedLeafStore"; import { CachedLinkedLeafStore } from "../../../state/lmt/CachedLinkedLeafStore"; -import { FieldString } from "../../../helpers/utils"; +import { FieldString } from "@proto-kit/common"; import { executeWithExecutionContext } from "./TransactionExecutionService"; diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 57a0957cb..36c5f855b 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -15,7 +15,7 @@ import { import { UntypedStateTransition, } from "../../protocol/production/helpers/UntypedStateTransition"; -import { FieldString } from "../../helpers/utils"; +import { FieldString } from "@proto-kit/common"; export interface StateTransitionBatch { stateTransitions: UntypedStateTransition[]; From 170d86b6272bd9d0ccbef3b396a5b12b54767647 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:27:57 +0300 Subject: [PATCH 41/63] refactor: use toRuntimeTransaction for signature verification --- .../mempool/verification/TransactionValidator.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index ecc2730b2..25782e1e2 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -8,8 +8,7 @@ import { import { PendingTransaction, } from "../PendingTransaction"; -import { Field, Poseidon, PublicKey, Signature, UInt64 } from "o1js"; -import { SignedTransaction } from "packages/protocol/dist"; +import { Signature} from "o1js"; @injectable() export class TransactionValidator { @@ -52,17 +51,15 @@ export class TransactionValidator { } const signature = Signature.fromJSON(tx.data.signature) - const signatureData = SignedTransaction.getSignatureData({ - nonce: UInt64.from(tx.data.nonce), - methodId: Field(tx.data.methodId), - argsHash: Poseidon.hash(tx.data.argsFields.map((f) => Field(f))), - }); + const runtimeTx = tx.toRuntimeTransaction(); + const validSignature = signature.verify( - PublicKey.fromBase58(tx.data.sender), - signatureData + runtimeTx.sender.value, + [runtimeTx.methodId, ...runtimeTx.nonce.value.value.toFields(), runtimeTx.argsHash] ); + if (!validSignature.toBoolean()) { return [false, "Signature provided is not valid"]; } From 7dab7e52dd69dc5e54411b6084020038a8f7dc17 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:40:15 +0300 Subject: [PATCH 42/63] refactor: replace TransactionExecutionResultJson with TransactionExecutionResult --- .../src/services/prisma/PrismaBlockStorage.ts | 6 +++--- .../sequencing/BlockProductionService.ts | 4 ++-- .../production/sequencing/BlockResultService.ts | 4 ++-- .../sequencing/TransactionExecutionService.ts | 9 ++++----- .../tracing/TransactionTracingService.ts | 14 +++++++------- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index be0f0ddd7..26521d3ba 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -1,5 +1,5 @@ import { - TransactionExecutionResultJson, + TransactionExecutionResult, Block, BlockResult, BlockQueue, @@ -54,7 +54,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { return undefined; } const transactions = - dbResult.transactions.map((txresult) => + dbResult.transactions.map((txresult) => this.transactionResultMapper.mapIn([txresult, txresult.tx]) ); @@ -223,7 +223,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { return blocks.map((block, index) => { const transactions = - block.transactions.map((txresult) => { + block.transactions.map((txresult) => { return this.transactionResultMapper.mapIn([txresult, txresult.tx]); }); const decodedBlock = this.blockMapper.mapIn(block); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 7a9f526a6..d074a28f7 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -20,7 +20,7 @@ import { match } from "ts-pattern"; import { Block, BlockWithResult, - TransactionExecutionResultJson, + TransactionExecutionResult, } from "../../../storage/model/Block"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; @@ -39,7 +39,7 @@ import { function isIncludedTxs( x: TransactionExecutionResultStatus -): x is { status: "included"; result: TransactionExecutionResultJson } { +): x is { status: "included"; result: TransactionExecutionResult } { return x.status === "included"; } diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index aab18d5aa..fa6ce05bb 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -18,7 +18,7 @@ import { inject, injectable, Lifecycle, scoped } from "tsyringe"; import { Block, BlockResult, - TransactionExecutionResultJson, + TransactionExecutionResult, } from "../../../storage/model/Block"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; @@ -50,7 +50,7 @@ function collectOrderedStateDiff( } function createCombinedOrderedStateDiff( - transactions: TransactionExecutionResultJson[], + transactions: TransactionExecutionResult[], blockHookSTs: UntypedStateTransition[] ) { // Flatten diff list into a single diff by applying them over each other diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 0f83057d7..2609cf01d 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -42,8 +42,7 @@ import { import { CachedStateService } from "../../../state/state/CachedStateService"; import { StateTransitionBatch, - TransactionExecutionResultJson, - STBatchToJson, + TransactionExecutionResult, } from "../../../storage/model/Block"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { trace } from "../../../logging/trace"; @@ -205,7 +204,7 @@ function traceLogSTs(msg: string, stateTransitions: StateTransition[]) { export type TransactionExecutionResultStatus = | { - result: TransactionExecutionResultJson; + result: TransactionExecutionResult; status: "included"; } | { tx: PendingTransactionJSONType; status: "skipped" } @@ -419,7 +418,7 @@ export class TransactionExecutionService { state: BlockTrackers, newState: BlockTrackers ): Promise<{ - result: TransactionExecutionResultJson; + result: TransactionExecutionResult; shouldRemove: boolean; }> { // TODO Use RecordingStateService -> async asProver needed @@ -555,7 +554,7 @@ export class TransactionExecutionService { afterTxHookResult.statusMessage ?? runtimeResult.statusMessage, - stateTransitions: stateTransitions.map(STBatchToJson), + stateTransitions: stateTransitions, events: beforeHookEvents .concat(runtimeResultEvents, afterHookEvents) .map((e) => ({ diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 95c34ac57..4b01af92d 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -12,7 +12,7 @@ import { toStateTransitionsHash } from "@proto-kit/module"; import { injectable } from "tsyringe"; import { - TransactionExecutionResultJson, + TransactionExecutionResult, STBatchFromJson, } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; @@ -102,7 +102,7 @@ export class TransactionTracingService { private appendTransactionToState( previousState: BlockTracingState, - transaction: TransactionExecutionResultJson + transaction: TransactionExecutionResult ) { const tx = PendingTransaction.fromJSON(transaction.tx); // TODO Remove this call and instead reuse results from sequencing @@ -124,7 +124,7 @@ export class TransactionTracingService { } private createRuntimeProofParams( - tx: TransactionExecutionResultJson, + tx: TransactionExecutionResult, networkState: ProvableNetworkState ): RuntimeProofParametersJson { const stBatch = STBatchFromJson(tx.stateTransitions[1]); @@ -139,7 +139,7 @@ export class TransactionTracingService { private async traceTransaction( previousState: BlockTracingState, - transaction: TransactionExecutionResultJson + transaction: TransactionExecutionResult ) { const stBatches = transaction.stateTransitions.map(STBatchFromJson); @@ -167,7 +167,7 @@ export class TransactionTracingService { public async createSingleTransactionTrace( previousState: BlockTracingState, - transaction: TransactionExecutionResultJson + transaction: TransactionExecutionResult ): Promise<[BlockTracingState, TransactionTrace]> { const publicInput = this.getTransactionProofPublicInput(previousState); @@ -201,8 +201,8 @@ export class TransactionTracingService { public async createMultiTransactionTrace( previousState: BlockTracingState, - transaction1: TransactionExecutionResultJson, - transaction2: TransactionExecutionResultJson + transaction1: TransactionExecutionResult, + transaction2: TransactionExecutionResult ): Promise<[BlockTracingState, TransactionTrace]> { const publicInput = this.getTransactionProofPublicInput(previousState); From a5602a2f1ba357cd662edba8bafc0eb81dc2b4b7 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:42:37 +0300 Subject: [PATCH 43/63] fix: update missing PendingTransaction replacement --- .../production/sequencing/BlockProductionService.ts | 4 ++-- .../sequencing/TransactionExecutionService.ts | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index d074a28f7..5434deb1b 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -23,7 +23,7 @@ import { TransactionExecutionResult, } from "../../../storage/model/Block"; import { CachedStateService } from "../../../state/state/CachedStateService"; -import { PendingTransactionJSONType } from "../../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../../mempool/PendingTransaction"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { Tracer } from "../../../logging/Tracer"; @@ -99,7 +99,7 @@ export class BlockProductionService { */ public async createBlock( asyncStateService: AsyncStateService, - transactions: PendingTransactionJSONType[], + transactions: PendingTransaction[], lastBlockWithResult: BlockWithResult, allowEmptyBlocks: boolean ): Promise< diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 2609cf01d..37c1acd1d 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -37,7 +37,6 @@ import zip from "lodash/zip"; import { PendingTransaction, - PendingTransactionJSONType, } from "../../../mempool/PendingTransaction"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { @@ -82,7 +81,7 @@ function getAreProofsEnabledFromModule( } async function decodeTransaction( - tx: PendingTransactionJSONType, + tx: PendingTransaction, runtime: Runtime ): Promise<{ method: SomeRuntimeMethod; @@ -207,8 +206,8 @@ export type TransactionExecutionResultStatus = result: TransactionExecutionResult; status: "included"; } - | { tx: PendingTransactionJSONType; status: "skipped" } - | { tx: PendingTransactionJSONType; status: "shouldRemove" }; + | { tx: PendingTransaction; status: "skipped" } + | { tx: PendingTransaction; status: "shouldRemove" }; @injectable() @scoped(Lifecycle.ContainerScoped) @@ -317,7 +316,7 @@ export class TransactionExecutionService { public addTransactionToBlockProverState( state: BlockTrackers, - tx: PendingTransactionJSONType + tx: PendingTransaction ): BlockTrackers { const signedTransaction = PendingTransaction.fromJSON(tx).toProtocolTransaction(); @@ -332,7 +331,7 @@ export class TransactionExecutionService { // eslint-disable-next-line sonarjs/cognitive-complexity public async createExecutionTraces( asyncStateService: CachedStateService, - transactions: PendingTransactionJSONType[], + transactions: PendingTransaction[], networkState: ProvableNetworkState, state: BlockTrackers ): Promise<{ @@ -410,7 +409,7 @@ export class TransactionExecutionService { })) public async createExecutionTrace( asyncStateService: CachedStateService, - tx: PendingTransactionJSONType, + tx: PendingTransaction, { networkState, hash: networkStateHash, From 0d8db76c16eace53c18350be47dac09d5d7c72b7 Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:52:13 +0300 Subject: [PATCH 44/63] refactor: update toProvable in UntypedStateTransition --- .../protocol/production/helpers/UntypedOption.ts | 4 ++-- .../production/helpers/UntypedStateTransition.ts | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts index 6e2c8f796..c4f2b32fd 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts @@ -18,8 +18,8 @@ export class UntypedOption { return treeValue.toString(); } return "0"; - } - + } + public static fromOption(option: Option | Option) { return new UntypedOption( option.isSome.toBoolean(), diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index 5923c3eb5..d88901472 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -1,4 +1,4 @@ -import { Field } from "o1js"; +import { Bool, Field } from "o1js"; import { ProvableOption, ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; @@ -49,8 +49,15 @@ export class UntypedStateTransition { public toProvable(): ProvableStateTransition { return new ProvableStateTransition({ path: Field(this.path), - from: new ProvableOption(ProvableOption.fromFields(this.from.value.map(Field))), - to: new ProvableOption(ProvableOption.fromFields(this.to.value.map(Field))) + from: new ProvableOption({ + isSome: Bool(this.from.isSome), + value: Field(this.from.treeValue), + }), + to: new ProvableOption({ + isSome: Bool(this.to.isSome), + value: Field(this.to.treeValue), + }), }); } } + From 20081d791bee12c3291bb0e0b049db9e8166348a Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:54:33 +0300 Subject: [PATCH 45/63] refactor: replace UntypedStateTransitionJson with UntypedStateTransition --- .../services/prisma/mappers/BlockMapper.ts | 4 ++-- .../prisma/mappers/StateTransitionMapper.ts | 19 ++++++++++--------- .../sequencing/BlockResultService.ts | 5 +---- .../production/tracing/BlockTracingService.ts | 14 +++----------- .../tracing/StateTransitionTracingService.ts | 11 ++--------- 5 files changed, 18 insertions(+), 35 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index 228503120..c11e53d39 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,5 +1,5 @@ import { singleton } from "tsyringe"; -import { Block, UntypedStateTransitionJson } from "@proto-kit/sequencer"; +import { Block, UntypedStateTransition } from "@proto-kit/sequencer"; import { Prisma, Block as PrismaBlock } from "@prisma/client"; import { NetworkState } from "@proto-kit/protocol"; @@ -37,7 +37,7 @@ export class BlockMapper implements ObjectMapper { // This is cleaner to keep mapIn beforeBlockStateTransitions: - input.beforeBlockStateTransitions as unknown as UntypedStateTransitionJson[], + input.beforeBlockStateTransitions as unknown as UntypedStateTransition[], }; } diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index 2800427ff..84e894e97 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -1,7 +1,7 @@ import { singleton } from "tsyringe"; import { StateTransitionBatchJson, - UntypedStateTransitionJson, + UntypedStateTransition, } from "@proto-kit/sequencer"; import { Prisma } from "@prisma/client"; @@ -9,15 +9,16 @@ import { ObjectMapper } from "../../../ObjectMapper"; @singleton() export class StateTransitionMapper - implements ObjectMapper + implements ObjectMapper { - public mapIn(input: Prisma.JsonObject): UntypedStateTransitionJson { - // - return input as unknown as UntypedStateTransitionJson; + public mapIn(input: Prisma.JsonObject): UntypedStateTransition { + + return input as unknown as UntypedStateTransition; } - public mapOut(input: UntypedStateTransitionJson): Prisma.JsonObject { + public mapOut(input: UntypedStateTransition): Prisma.JsonObject { // Already JSON-compatible, just cast + input.toJSON(); return input as unknown as Prisma.JsonObject; } } @@ -25,13 +26,13 @@ export class StateTransitionMapper @singleton() export class StateTransitionArrayMapper implements - ObjectMapper + ObjectMapper { public constructor(private readonly stMapper: StateTransitionMapper) {} public mapIn( input: Prisma.JsonValue | undefined - ): UntypedStateTransitionJson[] { + ): UntypedStateTransition[] { if (input === undefined) return []; if (Array.isArray(input)) { @@ -42,7 +43,7 @@ export class StateTransitionArrayMapper return []; } - public mapOut(input: UntypedStateTransitionJson[]): Prisma.JsonValue { + public mapOut(input: UntypedStateTransition[]): Prisma.JsonValue { return input.map((st) => this.stMapper.mapOut(st)) as Prisma.JsonArray; } } diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index fa6ce05bb..a3946ffd5 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -24,7 +24,6 @@ import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore" import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; import { UntypedStateTransition, - UntypedStateTransitionJson, } from "../helpers/UntypedStateTransition"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; @@ -203,9 +202,7 @@ export class BlockResultService { }> { const combinedDiff = createCombinedOrderedStateDiff( block.transactions, - block.beforeBlockStateTransitions.map((st: UntypedStateTransitionJson) => - UntypedStateTransition.fromJSON(st) - ) + block.beforeBlockStateTransitions ); const inMemoryStore = await CachedLinkedLeafStore.new(merkleTreeStore); diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index b55b724ee..83e3dcf6a 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -18,7 +18,6 @@ import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; import { UntypedStateTransition, - UntypedStateTransitionJson, } from "../helpers/UntypedStateTransition"; import { @@ -102,9 +101,7 @@ export class BlockTracingService { }); const startingStateBeforeHook = collectStartingState( - block.block.beforeBlockStateTransitions.map( - (st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) - ) + block.block.beforeBlockStateTransitions ); const blockTrace = { @@ -121,10 +118,7 @@ export class BlockTracingService { state.pendingSTBatches.push({ batchHash: toStateTransitionsHash( - block.block.beforeBlockStateTransitions.map( - (st: UntypedStateTransitionJson) => - UntypedStateTransition.fromJSON(st) - ) + block.block.beforeBlockStateTransitions, ), applied: Bool(true), }); @@ -174,9 +168,7 @@ export class BlockTracingService { } const startingStateAfterHook = collectStartingState( - block.result.afterBlockStateTransitions.map( - (st: UntypedStateTransitionJson) => UntypedStateTransition.fromJSON(st) - ) + block.result.afterBlockStateTransitions ); state.networkState = new ProvableNetworkState( ProvableNetworkState.fromJSON(block.result.afterNetworkState) diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index a7517f7bd..1c5dc454c 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -20,7 +20,6 @@ import { distinctByString } from "../../../helpers/utils"; import { BlockWithResult } from "../../../storage/model/Block"; import { UntypedStateTransition, - UntypedStateTransitionJson, } from "../helpers/UntypedStateTransition"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { trace } from "../../../logging/trace"; @@ -50,10 +49,7 @@ export class StateTransitionTracingService { return blocks.reduce((previous, block) => { const batches = [ { - stateTransitions: block.block.beforeBlockStateTransitions.map( - (st: UntypedStateTransitionJson) => - UntypedStateTransition.fromJSON(st) - ), + stateTransitions: block.block.beforeBlockStateTransitions, applied: true, }, ...block.block.transactions.flatMap((tx) => @@ -75,10 +71,7 @@ export class StateTransitionTracingService { } return batchBeforeWitnessing.concat({ - stateTransitions: block.result.afterBlockStateTransitions.map( - (st: UntypedStateTransitionJson) => - UntypedStateTransition.fromJSON(st) - ), + stateTransitions: block.result.afterBlockStateTransitions, applied: true, witnessRoot: false, }); From 8a09ced939c3830d9340facce50a6e680dd86f7e Mon Sep 17 00:00:00 2001 From: saitunc Date: Sun, 18 Jan 2026 21:55:19 +0300 Subject: [PATCH 46/63] refactor: replace StateTransitionBatchJson with StateTransitionBatch --- .../src/services/prisma/mappers/StateTransitionMapper.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index 84e894e97..0956edc39 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -1,6 +1,6 @@ import { singleton } from "tsyringe"; import { - StateTransitionBatchJson, + StateTransitionBatch, UntypedStateTransition, } from "@proto-kit/sequencer"; import { Prisma } from "@prisma/client"; @@ -50,13 +50,13 @@ export class StateTransitionArrayMapper @singleton() export class StateTransitionBatchArrayMapper - implements ObjectMapper + implements ObjectMapper { public constructor( private readonly stArrayMapper: StateTransitionArrayMapper ) {} - public mapOut(input: StateTransitionBatchJson[]): Prisma.JsonValue { + public mapOut(input: StateTransitionBatch[]): Prisma.JsonValue { return input.map((st) => ({ stateTransitions: this.stArrayMapper.mapOut( st.stateTransitions @@ -65,7 +65,7 @@ export class StateTransitionBatchArrayMapper })); } - public mapIn(input: Prisma.JsonValue): StateTransitionBatchJson[] { + public mapIn(input: Prisma.JsonValue): StateTransitionBatch[] { if (input === undefined) return []; if (Array.isArray(input)) { From 8053677e7384b59a518aaf925cf317d2ee73c859 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 00:01:21 +0300 Subject: [PATCH 47/63] refactor(fix): fix use of PendingTransaction attributes --- .../src/services/prisma/PrismaBlockStorage.ts | 2 +- .../PrismaBlockProduction.test.ts | 30 ++++++++++++++----- .../sequencing/BlockProductionService.ts | 2 +- .../sequencing/BlockResultService.ts | 2 +- .../sequencing/TransactionExecutionService.ts | 26 ++++++++-------- .../tracing/TransactionTracingService.ts | 16 +++++----- .../integration/StorageIntegration.test.ts | 2 +- packages/stack/test/graphql/graphql.test.ts | 8 +++-- 8 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 26521d3ba..69ed9db1b 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -81,7 +81,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { public async pushBlock(block: Block): Promise { log.trace( "Pushing block to DB. Txs:", - block.transactions.map((x) => x.tx.hash) + block.transactions.map((x) => x.tx.data.hash) ); const transactions = block.transactions.map( diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index 52481d05a..04848a76b 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -3,7 +3,7 @@ import { afterAll, beforeAll, describe, expect } from "@jest/globals"; import { expectDefined, log } from "@proto-kit/common"; import { BalancesKey, TokenId } from "@proto-kit/library"; import { AppChainTransaction } from "@proto-kit/sdk"; -import { Block, Batch } from "@proto-kit/sequencer"; +import { Block, Batch, PendingTransaction } from "@proto-kit/sequencer"; import { PrivateKey, PublicKey } from "o1js"; import { container } from "tsyringe"; import { testBlockProduction } from "@proto-kit/sequencer/test/integration/BlockProduction-test"; @@ -96,8 +96,8 @@ describe("prisma integration", () => { // Check that transactions match expect(retrievedBlock.transactions).toHaveLength(1); - expect(retrievedBlock.transactions[0].tx.hash).toStrictEqual( - block.transactions[0].tx.hash + expect(retrievedBlock.transactions[0].tx.data.hash).toStrictEqual( + block.transactions[0].tx.data.hash ); expect(retrievedBlock.hash).toStrictEqual(block.hash); @@ -224,10 +224,16 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); + let txHash: string; + + if (transaction.transaction instanceof PendingTransaction) { + txHash = transaction.transaction.data.hash; + } else { + txHash = transaction.transaction!.hash().toString(); + } + expect(txs).toHaveLength(1); - expect(txs[0].hash).toStrictEqual( - transaction.transaction.hash().toString() - ); + expect(txs[0].data.hash).toStrictEqual(txHash); }); it("should resolve transaction from storage as pending", async () => { @@ -240,9 +246,17 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); + let txHash: string; + + if (transaction.transaction instanceof PendingTransaction) { + txHash = transaction.transaction.data.hash; + } else { + txHash = transaction.transaction!.hash().toString(); + } + expect(txs).toHaveLength(1); - expect(txs[0].hash).toStrictEqual( - transaction.transaction.hash().toString() + expect(txs[0].data.hash).toStrictEqual( + txHash ); }); }); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 5434deb1b..62dcc3fa1 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -198,7 +198,7 @@ export class BlockProductionService { const includedTxs = executionResults.map((x) => { const txHash = match(x) .with({ status: "included" }, ({ result }) => result.tx) - .otherwise(({ tx }) => tx).hash; + .otherwise(({ tx }) => tx).data.hash; return { hash: txHash, diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index a3946ffd5..b40361787 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -41,7 +41,7 @@ function collectOrderedStateDiff( stateTransitions: UntypedStateTransition[] ): StateRecord { return stateTransitions.reduce((state, st) => { - if (st.toValue.isSome.toBoolean()) { + if (st.to.isSome) { state[st.path.toString()] = st.toValue.value; } return state; diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 37c1acd1d..eb8afce49 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -89,13 +89,13 @@ async function decodeTransaction( module: RuntimeModule; }> { const methodDescriptors = runtime.methodIdResolver.getMethodNameFromId( - tx.methodId + tx.data.methodId ); - const method = runtime.getMethodById(tx.methodId); + const method = runtime.getMethodById(tx.data.methodId); if (methodDescriptors === undefined || method === undefined) { - throw errors.methodIdNotFound(tx.methodId); + throw errors.methodIdNotFound(tx.data.methodId); } const [moduleName, methodName] = methodDescriptors; @@ -106,8 +106,8 @@ async function decodeTransaction( methodName ); const args = await parameterDecoder.decode( - tx.argsFields.map(Field), - tx.auxiliaryData + tx.data.argsFields.map(Field), + tx.data.auxiliaryData ); return { @@ -319,11 +319,11 @@ export class TransactionExecutionService { tx: PendingTransaction ): BlockTrackers { const signedTransaction = - PendingTransaction.fromJSON(tx).toProtocolTransaction(); + tx.toProtocolTransaction(); // Add tx to commitments return addTransactionToBundle( state, - Bool(tx.isMessage), + Bool(tx.data.isMessage), signedTransaction.transaction ); } @@ -360,7 +360,7 @@ export class TransactionExecutionService { // If the hooks fail AND the tx is not a message (in which case we // have to still execute it), we skip this tx and don't add it to the block - if (!executionTrace.hooksStatus && !executionTrace.tx.isMessage) { + if (!executionTrace.hooksStatus && !executionTrace.tx.data.isMessage) { const actionMessage = shouldRemove ? "removing as to removeWhen hooks" : "skipping"; @@ -404,8 +404,8 @@ export class TransactionExecutionService { @trace("block.transaction", ([, tx, { networkState }]) => ({ height: networkState.block.height.toString(), - methodId: tx.methodId.toString(), - isMessage: tx.isMessage, + methodId: tx.data.methodId.toString(), + isMessage: tx.data.isMessage, })) public async createExecutionTrace( asyncStateService: CachedStateService, @@ -432,7 +432,7 @@ export class TransactionExecutionService { appChain.setProofsEnabled(false); const signedTransaction = - PendingTransaction.fromJSON(tx).toProtocolTransaction(); + tx.toProtocolTransaction(); const runtimeContextInputs = { transaction: signedTransaction.transaction, networkState, @@ -491,8 +491,8 @@ export class TransactionExecutionService { new MethodPublicOutput({ status: runtimeResult.status, networkStateHash: networkStateHash, - isMessage: Bool(tx.isMessage), - transactionHash: Field(tx.hash), + isMessage: Bool(tx.data.isMessage), + transactionHash: Field(tx.data.hash), eventsHash, stateTransitionsHash, }) diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 4b01af92d..9fd04b93c 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -6,7 +6,7 @@ import { ProvableNetworkState, TransactionProverTransactionArguments, } from "@proto-kit/protocol"; -import { Bool, Field } from "o1js"; +import { Bool, Field, Signature } from "o1js"; import { MAX_FIELD } from "@proto-kit/common"; import { toStateTransitionsHash } from "@proto-kit/module"; import { injectable } from "tsyringe"; @@ -74,12 +74,12 @@ export class TransactionTracingService { ): Promise { const verificationKeyAttestation = this.verificationKeyService.getAttestation( - transaction.methodId.toString() + transaction.data.methodId ); return { transaction: transaction.toRuntimeTransaction(), - signature: transaction.signature, + signature: Signature.fromJSON(transaction.data.signature), verificationKeyAttestation, }; } @@ -104,11 +104,11 @@ export class TransactionTracingService { previousState: BlockTracingState, transaction: TransactionExecutionResult ) { - const tx = PendingTransaction.fromJSON(transaction.tx); + const tx = transaction.tx; // TODO Remove this call and instead reuse results from sequencing const newState = addTransactionToBundle( previousState, - Bool(tx.isMessage), + Bool(tx.data.isMessage), tx.toRuntimeTransaction() ); @@ -181,7 +181,7 @@ export class TransactionTracingService { { executionData: { transaction: await this.getTransactionData( - PendingTransaction.fromJSON(transaction.tx) + transaction.tx ), networkState: previousState.networkState, }, @@ -222,10 +222,10 @@ export class TransactionTracingService { { executionData: { transaction1: await this.getTransactionData( - PendingTransaction.fromJSON(transaction1.tx) + transaction1.tx ), transaction2: await this.getTransactionData( - PendingTransaction.fromJSON(transaction2.tx) + transaction2.tx ), networkState: previousState.networkState, }, diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 215092e4f..3ef0728e7 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -205,7 +205,7 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await txStorage.getPendingUserTransactions(); expect(txs).toHaveLength(1); - expect(txs[0].hash).toStrictEqual(tx.hash); + expect(txs[0].data.hash).toStrictEqual(tx.data.hash); await sequencer.resolve("BlockTrigger").produceBlock(); diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index 5a60ef9bf..d22c9adf7 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -14,6 +14,8 @@ import { ManualBlockTrigger, Sequencer, InclusionStatus, + PendingTransaction, + UnsignedTransaction, } from "@proto-kit/sequencer"; import { ClientAppChain, @@ -184,7 +186,9 @@ describe("graphql client test", () => { await tx.sign(); await tx.send(); - const txHash = tx.transaction?.hash().toString()!; + const txHash = tx.transaction instanceof UnsignedTransaction + ? tx.transaction.hash().toString() + : tx.transaction!.data.hash; const waitPromise = appChain.query.explorer.fetchTxInclusion(txHash); @@ -227,7 +231,7 @@ describe("graphql client test", () => { const heightParsedTx = heightResult?.transactions!; - const blockTxHash = block?.transactions[0].tx.hash; + const blockTxHash = block?.transactions[0].tx.data.hash; const queryTxHash = heightParsedTx[0]?.tx?.hash; From f8bb8e2271db9229f1532985f97b5ef2f7ad5358 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 00:12:44 +0300 Subject: [PATCH 48/63] refactor: remove STBatchFromJson and fix UntypedStateTransition code --- .../sequencing/BlockProductionService.ts | 4 +--- .../production/sequencing/BlockResultService.ts | 4 ++-- .../tracing/TransactionTracingService.ts | 15 +++++++-------- .../helpers/UntypedStateTransition.test.ts | 12 ++++++------ 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 62dcc3fa1..dab82fd46 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -188,9 +188,7 @@ export class BlockProductionService { before: lastResult.afterNetworkState, during: ProvableNetworkState.toJSON(networkState), }, - beforeBlockStateTransitions: beforeBlockStateTransitions.map( - (st: UntypedStateTransition) => st.toJSON() - ), + beforeBlockStateTransitions: beforeBlockStateTransitions }; const hash = Block.hash(block).toString(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index b40361787..6ce9171e3 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -42,7 +42,7 @@ function collectOrderedStateDiff( ): StateRecord { return stateTransitions.reduce((state, st) => { if (st.to.isSome) { - state[st.path.toString()] = st.toValue.value; + state[st.path] = st.to.value; } return state; }, {}); @@ -251,7 +251,7 @@ export class BlockResultService { blockHashWitness: BlockHashMerkleTreeWitness.toJSON(blockHashWitness), afterBlockStateTransitions: stateTransitions.map((st) => - UntypedStateTransition.fromStateTransition(st).toJSON() + UntypedStateTransition.fromStateTransition(st) ), blockHash: FieldString(block.hash), }, diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 9fd04b93c..284d848d1 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -13,7 +13,6 @@ import { injectable } from "tsyringe"; import { TransactionExecutionResult, - STBatchFromJson, } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; import type { RuntimeProofParametersJson } from "../tasks/RuntimeProvingTask"; @@ -48,16 +47,16 @@ export function collectStartingState( // Filter distinct .filter( (st, index, array) => - array.findIndex((st2) => st2.path.toBigInt() === st.path.toBigInt()) === + array.findIndex((st2) => st2.path === st.path) === index ) // Filter out STs that have isSome: false as precondition, because this means // "state hasn't been set before" and has to correlate to a precondition on Field(0) // and for that the state has to be undefined - .filter((st) => st.fromValue.isSome.toBoolean()) + .filter((st) => st.from.isSome) .map((st) => [ - st.path.toString(), - st.fromValue.value.map((f: Field) => f.toString()), + st.path, + st.from.value, ]); return Object.fromEntries(stateEntries); @@ -112,7 +111,7 @@ export class TransactionTracingService { tx.toRuntimeTransaction() ); - const stBatches = transaction.stateTransitions.map(STBatchFromJson); + const stBatches = transaction.stateTransitions; stBatches.forEach((batch) => { newState.pendingSTBatches.push({ applied: Bool(batch.applied), @@ -127,7 +126,7 @@ export class TransactionTracingService { tx: TransactionExecutionResult, networkState: ProvableNetworkState ): RuntimeProofParametersJson { - const stBatch = STBatchFromJson(tx.stateTransitions[1]); + const stBatch = tx.stateTransitions[1]; const startingState = collectStartingState(stBatch.stateTransitions); return { @@ -141,7 +140,7 @@ export class TransactionTracingService { previousState: BlockTracingState, transaction: TransactionExecutionResult ) { - const stBatches = transaction.stateTransitions.map(STBatchFromJson); + const stBatches = transaction.stateTransitions; const beforeHookStartingState = collectStartingState( stBatches[0].stateTransitions.flat() diff --git a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts index 5fc4ae5d4..a7e432037 100644 --- a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts +++ b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts @@ -32,23 +32,23 @@ describe("stateTransition", () => { expect(untyped.path).toStrictEqual(st.path); - expect(untyped.fromValue.value).toStrictEqual( + expect(untyped.from.value).toStrictEqual( st.fromValue.valueType.toFields(st.fromValue.value) ); - expect(untyped.fromValue.isSome.toBoolean()).toStrictEqual( + expect(untyped.from.isSome).toStrictEqual( st.fromValue.isSome.toBoolean() ); - expect(untyped.fromValue.isForcedSome.toBoolean()).toStrictEqual( + expect(untyped.from.isForcedSome).toStrictEqual( st.fromValue.isForcedSome.toBoolean() ); - expect(untyped.toValue.value).toStrictEqual( + expect(untyped.to.value).toStrictEqual( st.toValue.valueType.toFields(st.toValue.value) ); - expect(untyped.toValue.isSome.toBoolean()).toStrictEqual( + expect(untyped.to.isSome).toStrictEqual( st.toValue.isSome.toBoolean() ); - expect(untyped.toValue.isForcedSome.toBoolean()).toStrictEqual( + expect(untyped.to.isForcedSome).toStrictEqual( st.toValue.isForcedSome.toBoolean() ); From 4ed3853bfab07d6ad963dfa315d53c7086663a7d Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 04:54:32 +0300 Subject: [PATCH 49/63] refactor: update RuntimeProofParameters and TaskStateRecord --- .../production/BatchProducerModule.ts | 2 +- .../sequencing/BlockResultService.ts | 2 +- .../protocol/production/tasks/NewBlockTask.ts | 23 ++++----------- .../production/tasks/RuntimeProvingTask.ts | 23 +++++++-------- .../tasks/TransactionProvingTask.ts | 14 ++++----- .../serializers/DecodedStateSerializer.ts | 3 +- .../NewBlockProvingParametersSerializer.ts | 6 ++-- .../RuntimeProofParametersSerializer.ts | 24 ++++++++++----- ...ansactionProvingTaskParameterSerializer.ts | 4 +-- .../types/TransactionProvingTypes.ts | 4 +-- .../production/tracing/BlockTracingService.ts | 29 ------------------- .../tracing/TransactionTracingService.ts | 12 ++++---- 12 files changed, 55 insertions(+), 91 deletions(-) diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 3fd090156..9875daa6a 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -22,7 +22,7 @@ import { BlockProofSerializer } from "./tasks/serializers/BlockProofSerializer"; import { BatchTracingService } from "./tracing/BatchTracingService"; import { BatchFlow } from "./flow/BatchFlow"; -export type StateRecord = Record; +export type StateRecord = Record; interface BatchMetadata { batch: SettleableBatch; diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 6ce9171e3..ebdce1bf1 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -174,7 +174,7 @@ export class BlockResultService { const tree = new LinkedMerkleTree(store.treeStore, store); const writes = Object.entries(stateDiff).map(([key, state]) => { - const treeValue = state !== undefined ? Poseidon.hash(state) : Field(0); + const treeValue = state !== undefined ? Poseidon.hash(state.map(Field)) : Field(0); return { path: BigInt(key), value: treeValue.toBigInt() }; }); tree.setLeaves(writes); diff --git a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts index eea3e14ff..e7d4b45fd 100644 --- a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts @@ -23,13 +23,10 @@ import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PairingDerivedInput } from "../flow/ReductionTaskFlow"; -import { - TaskStateRecordJson, - taskStateRecordFromJson, -} from "../tracing/BlockTracingService"; import { NewBlockProvingParametersSerializer } from "./serializers/NewBlockProvingParametersSerializer"; import { executeWithPrefilledStateService } from "./TransactionProvingTask"; +import { JSONEncodableState } from "./serializers/DecodedStateSerializer"; export interface NewBlockProverParameters { publicInput: BlockProverPublicInput; @@ -37,8 +34,8 @@ export interface NewBlockProverParameters { blockWitness: BlockHashMerkleTreeWitness; deferSTProof: Bool; afterBlockRootWitness: WitnessedRootWitness; - startingStateBeforeHook: TaskStateRecordJson; - startingStateAfterHook: TaskStateRecordJson; + startingStateBeforeHook: JSONEncodableState; + startingStateAfterHook: JSONEncodableState; } export type NewBlockProvingParameters = PairingDerivedInput< @@ -65,7 +62,7 @@ export class NewBlockTask @inject("Protocol") private readonly protocol: Protocol, private readonly executionContext: ProvableMethodExecutionContext, - private readonly compileRegistry: CompileRegistry + private readonly compileRegistry: CompileRegistry, ) { super(); this.stateTransitionProver = protocol.stateTransitionProver; @@ -116,23 +113,15 @@ export class NewBlockTask input2 ); - // Convert from JSON to provable types at the proving boundary - const startingStateBeforeHookProvable = taskStateRecordFromJson( - startingStateBeforeHook - ); - const startingStateAfterHookProvable = taskStateRecordFromJson( - startingStateAfterHook - ); - await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHookProvable, startingStateAfterHookProvable], + [startingStateBeforeHook , startingStateAfterHook], async () => {} ); return await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHookProvable, startingStateAfterHookProvable], + [startingStateBeforeHook , startingStateAfterHook], async () => await this.executionContext.current().result.prove() ); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 49f183819..10d7926f4 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -20,21 +20,18 @@ import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateSe import { PendingTransaction, } from "../../../mempool/PendingTransaction"; -import { - TaskStateRecord, -} from "../tracing/BlockTracingService"; import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; +import { DecodedStateSerializer, JSONEncodableState } from "./serializers/DecodedStateSerializer"; type RuntimeProof = Proof; export interface RuntimeProofParameters { tx: PendingTransaction; - networkState: ProvableNetworkState; - state: TaskStateRecord; + networkState: NetworkState; + state: JSONEncodableState; } - @injectable() @scoped(Lifecycle.ContainerScoped) export class RuntimeProvingTask @@ -67,15 +64,15 @@ export class RuntimeProvingTask ): Promise { // Convert from JSON to provable types at the proving boundary const tx = input.tx; - const networkState = input.networkState; - - const state = input.state; + const networkState = new ProvableNetworkState( + ProvableNetworkState.fromJSON(input.networkState) + ); - const method = this.runtime.getMethodById(tx.data.methodId.toString()); + const method = this.runtime.getMethodById(tx.data.methodId); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(tx.data.methodId.toString()); + .getMethodNameFromId(tx.data.methodId); if (methodDescriptors === undefined || method === undefined) { throw new Error(`MethodId not found ${tx.data.methodId}`); @@ -92,7 +89,9 @@ export class RuntimeProvingTask tx.data.auxiliaryData ); - const prefilledStateService = new PreFilledStateService(state); + const prefilledStateService = new PreFilledStateService( + DecodedStateSerializer.fromJSON(input.state) + ); this.runtime.stateServiceProvider.setCurrentStateService( prefilledStateService ); diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index 0784973c0..f5faf4334 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -18,20 +18,17 @@ import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskSerializer, Task } from "../../../worker/flow/Task"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; -import { - TaskStateRecord, - taskStateRecordFromJson, -} from "../tracing/BlockTracingService"; import { TransactionProvingTaskParameterSerializer } from "./serializers/TransactionProvingTaskParameterSerializer"; import { TransactionProvingTaskParameters, TransactionProvingType, } from "./serializers/types/TransactionProvingTypes"; +import { DecodedStateSerializer, JSONEncodableState, TaskStateRecord } from "./serializers/DecodedStateSerializer"; export async function executeWithPrefilledStateService( stateServiceProvider: StateServiceProvider, - startingStates: TaskStateRecord[], + startingStates: JSONEncodableState[], callback: () => Promise ): Promise { startingStates @@ -40,7 +37,7 @@ export async function executeWithPrefilledStateService( .forEach((startingState) => { stateServiceProvider.setCurrentStateService( new PreFilledStateService({ - ...startingState, + ...DecodedStateSerializer.fromJSON(startingState) }) ); }); @@ -96,9 +93,8 @@ export class TransactionProvingTask public async compute( input: TransactionProvingTaskParameters ): Promise { - const startingStateProvable = input.parameters.startingState.map( - taskStateRecordFromJson - ); + const startingStateProvable = input.parameters.startingState; + await executeWithPrefilledStateService( this.protocol.stateServiceProvider, startingStateProvable, diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/DecodedStateSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/DecodedStateSerializer.ts index 475a223be..14a178ff2 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/DecodedStateSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/DecodedStateSerializer.ts @@ -1,7 +1,6 @@ import { Field } from "o1js"; -import type { TaskStateRecord } from "../../tracing/BlockTracingService"; - +export type TaskStateRecord = Record; export type JSONEncodableState = Record; export class DecodedStateSerializer { diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts index 01f587593..cd8fadbb9 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts @@ -17,7 +17,7 @@ import type { NewBlockProverParameters } from "../NewBlockTask"; import { TaskSerializer } from "../../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../../helpers/utils"; import { PairingDerivedInput } from "../../flow/ReductionTaskFlow"; -import { TaskStateRecordJson } from "../../tracing/BlockTracingService"; +import { JSONEncodableState } from "./DecodedStateSerializer"; interface JsonType { input1: string; @@ -26,8 +26,8 @@ interface JsonType { publicInput: ReturnType; networkState: ReturnType; blockWitness: ReturnType; - startingStateBeforeHook: TaskStateRecordJson; - startingStateAfterHook: TaskStateRecordJson; + startingStateBeforeHook: JSONEncodableState; + startingStateAfterHook: JSONEncodableState; deferSTProof: boolean; afterBlockRootWitness: ReturnType; }; diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts index 73fee13c6..957aaf8bc 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts @@ -1,19 +1,29 @@ import { TaskSerializer } from "../../../../worker/flow/Task"; -import type { RuntimeProofParametersJson } from "../RuntimeProvingTask"; +import type { RuntimeProofParameters } from "../RuntimeProvingTask"; +import { PendingTransaction } from "../../../../mempool/PendingTransaction"; /** * Serializer for RuntimeProofParametersJson. * Since RuntimeProofParametersJson is already JSON-compatible, this is trivial. */ export class RuntimeProofParametersSerializer - implements TaskSerializer + implements TaskSerializer { - public toJSON(parameters: RuntimeProofParametersJson): string { - return JSON.stringify(parameters); + public toJSON(parameters: RuntimeProofParameters): string { + return JSON.stringify({ + tx: parameters.tx.toJSON(), + networkState: parameters.networkState, + state: parameters.state, + }); } - public fromJSON(json: string): RuntimeProofParametersJson { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return JSON.parse(json) as RuntimeProofParametersJson; + public fromJSON(json: string): RuntimeProofParameters { + const parsed = JSON.parse(json); + return { + tx: PendingTransaction.fromJSON(parsed.tx), + networkState: parsed.networkState, + state: parsed.state, + }; } } + diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts index 7cf7c45e1..b4ad5476b 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts @@ -10,13 +10,13 @@ import { JsonProof, Signature } from "o1js"; import { TaskSerializer } from "../../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../../helpers/utils"; -import { TaskStateRecordJson } from "../../tracing/BlockTracingService"; import { TransactionProvingTaskParameters, TransactionProvingType, } from "./types/TransactionProvingTypes"; import { RuntimeVerificationKeyAttestationSerializer } from "./RuntimeVerificationKeyAttestationSerializer"; +import { JSONEncodableState } from "./DecodedStateSerializer"; export type TransactionProverTransactionArgumentsJSON = { transaction: ReturnType; @@ -40,7 +40,7 @@ export type MultiExecutionDataJSON = { export type TransactionProverTaskParametersJSON< ExecutionData extends SingleExecutionDataJSON | MultiExecutionDataJSON, > = { - startingState: TaskStateRecordJson[]; + startingState: JSONEncodableState[]; publicInput: ReturnType; executionData: ExecutionData; }; diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts index ac4c72375..490564a20 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/types/TransactionProvingTypes.ts @@ -6,7 +6,7 @@ import { } from "@proto-kit/protocol"; import { Proof } from "o1js"; -import type { TaskStateRecordJson } from "../../../tracing/BlockTracingService"; +import { JSONEncodableState } from "../DecodedStateSerializer"; export type RuntimeProof = Proof; @@ -22,7 +22,7 @@ export interface TransactionProverTaskParameters< > { publicInput: BlockProverPublicInput; executionData: ExecutionData; - startingState: TaskStateRecordJson[]; + startingState: JSONEncodableState[]; } export type TransactionProvingTaskParameters = diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index 83e3dcf6a..d58ccc9db 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -16,9 +16,6 @@ import { BlockWithResult } from "../../../storage/model/Block"; import type { NewBlockProverParameters } from "../tasks/NewBlockTask"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; -import { - UntypedStateTransition, -} from "../helpers/UntypedStateTransition"; import { collectStartingState, @@ -26,32 +23,6 @@ import { TransactionTracingService, } from "./TransactionTracingService"; -export type TaskStateRecord = Record; - -export type TaskStateRecordJson = Record; - -export function taskStateRecordToJson( - record: TaskStateRecord -): TaskStateRecordJson { - return Object.fromEntries( - Object.entries(record).map(([key, fields]) => [ - key, - fields.map((f) => f.toString()), - ]) - ); -} - -export function taskStateRecordFromJson( - json: TaskStateRecordJson -): TaskStateRecord { - return Object.fromEntries( - Object.entries(json).map(([key, strings]) => [ - key, - strings.map((s) => Field(s)), - ]) - ); -} - export type BlockTracingState = Pick< BlockProverState, | "witnessedRoots" diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 284d848d1..4ad74f767 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -15,7 +15,7 @@ import { TransactionExecutionResult, } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; -import type { RuntimeProofParametersJson } from "../tasks/RuntimeProvingTask"; +import type { RuntimeProofParameters } from "../tasks/RuntimeProvingTask"; import { TransactionProverTaskParameters, TransactionProvingType, @@ -25,24 +25,24 @@ import { VerificationKeyService } from "../../runtime/RuntimeVerificationKeyServ import type { BlockTracingState, - TaskStateRecordJson, } from "./BlockTracingService"; +import { JSONEncodableState } from "../tasks/serializers/DecodedStateSerializer"; export type TransactionTrace = | { type: TransactionProvingType.SINGLE; transaction: TransactionProverTaskParameters; - runtime: [RuntimeProofParametersJson]; + runtime: [RuntimeProofParameters]; } | { type: TransactionProvingType.MULTI; transaction: TransactionProverTaskParameters; - runtime: [RuntimeProofParametersJson, RuntimeProofParametersJson]; + runtime: [RuntimeProofParameters, RuntimeProofParameters]; }; export function collectStartingState( stateTransitions: UntypedStateTransition[] -): TaskStateRecordJson { +): JSONEncodableState { const stateEntries = stateTransitions // Filter distinct .filter( @@ -125,7 +125,7 @@ export class TransactionTracingService { private createRuntimeProofParams( tx: TransactionExecutionResult, networkState: ProvableNetworkState - ): RuntimeProofParametersJson { + ): RuntimeProofParameters { const stBatch = tx.stateTransitions[1]; const startingState = collectStartingState(stBatch.stateTransitions); From a959f99cdfb60fd5f3131787148d59d2d4978f58 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 04:59:33 +0300 Subject: [PATCH 50/63] refactor(fix): fix missing changes on refactored non-provable code --- packages/indexer/src/IndexerNotifier.ts | 2 +- packages/indexer/test/IndexerNotifier.test.ts | 5 +- .../processor/test/HandlersExecutor.test.ts | 6 +- .../sdk/src/query/InMemoryBlockExplorer.ts | 7 +- .../workers/workers-proven.test.ts | 2 +- packages/sequencer/test/Mempool.test.ts | 6 +- .../test/integration/Mempool.test.ts | 96 +++++++++---------- .../StateTransitionTracingService.test.ts | 6 +- .../test/settlement/Settlement-only.ts | 2 +- 9 files changed, 68 insertions(+), 64 deletions(-) diff --git a/packages/indexer/src/IndexerNotifier.ts b/packages/indexer/src/IndexerNotifier.ts index 87d92f578..651249b7b 100644 --- a/packages/indexer/src/IndexerNotifier.ts +++ b/packages/indexer/src/IndexerNotifier.ts @@ -67,7 +67,7 @@ export class IndexerNotifier extends SequencerModule> { this.indexPendingTxTask.name ); // This part seems weird - const payload = await txInputSerializer.toJSON(tx.toJSON()); + const payload = await txInputSerializer.toJSON(tx); const sequencerId = this.sequencerIdProvider.getSequencerId(); const task: TaskPayload = { diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index f75bdeca9..7b90b572f 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -22,6 +22,7 @@ import { } from "@proto-kit/sdk"; import { LocalTaskQueue, + PendingTransaction, Sequencer, TaskPayload, VanillaTaskWorkerModules, @@ -130,7 +131,7 @@ async function sendTransactions( { nonce: i } ); - console.log("tx nonce", tx.transaction?.nonce.toBigInt()); + console.log("tx nonce", (tx.transaction as PendingTransaction).data.nonce); await tx.sign(); await tx.send(); @@ -141,7 +142,7 @@ async function sendTransactions( const txs = await mempool.getTxs(); console.log( "txs", - txs.map((tx) => tx.nonce) + txs.map((tx) => tx.data.nonce) ); return await appChain.produceBlock(); diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index 88438fad2..953e3643d 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -42,7 +42,7 @@ describe("HandlersModule", () => { ) => { // iterate over all transactions for (const tx of block.transactions) { - const methodId = tx.tx.methodId.toString(); + const methodId = tx.tx.data.methodId; const methodDescriptor = appChain.runtime.methodIdResolver.getMethodNameFromId(methodId); @@ -66,8 +66,8 @@ describe("HandlersModule", () => { // @ts-expect-error const [, from, to, amount]: [TokenId, PublicKey, PublicKey, Balance] = await parameterDecoder.decode( - tx.tx.argsFields.map(Field), - tx.tx.auxiliaryData + tx.tx.data.argsFields.map(Field), + tx.tx.data.auxiliaryData ); const currentFromBalance = await client.balance.findFirst({ diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index 51b695c61..bd5b86874 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -59,8 +59,11 @@ export class InMemoryBlockExplorer if (block === undefined) { return undefined; } - - const clientTransactions: ClientTransaction[] = block.transactions; + const clientTransactions: ClientTransaction[] = block.transactions.map((txResult) => ({ + tx: txResult.tx.toJSON(), + status: txResult.status, + statusMessage: txResult.statusMessage, + })); return { ...block, diff --git a/packages/sequencer/test-integration/workers/workers-proven.test.ts b/packages/sequencer/test-integration/workers/workers-proven.test.ts index f914473e4..de9de936e 100644 --- a/packages/sequencer/test-integration/workers/workers-proven.test.ts +++ b/packages/sequencer/test-integration/workers/workers-proven.test.ts @@ -120,7 +120,7 @@ describe("worker-proven", () => { expectDefined(block); expect(block.transactions).toHaveLength(1); - expect(block.transactions[0].status.toBoolean()).toBe(true); + expect(block.transactions[0].status).toBe(true); expectDefined(batch); diff --git a/packages/sequencer/test/Mempool.test.ts b/packages/sequencer/test/Mempool.test.ts index d80a00f0f..32260bb00 100644 --- a/packages/sequencer/test/Mempool.test.ts +++ b/packages/sequencer/test/Mempool.test.ts @@ -20,12 +20,12 @@ describe("memPool", () => { }); const data = unsigned.getSignatureData(); - const hash = unsigned.hash(); + const hash = unsigned.hash().toString(); const signed = unsigned.sign(pk); - expect(data).toStrictEqual(signed.getSignatureData()); - expect(hash).toStrictEqual(signed.hash()); + expect(data).toStrictEqual(signed.toProtocolTransaction().getSignatureData()); + expect(hash).toStrictEqual(signed.data.hash); }); }); diff --git a/packages/sequencer/test/integration/Mempool.test.ts b/packages/sequencer/test/integration/Mempool.test.ts index 2054b7f86..6f48233b2 100644 --- a/packages/sequencer/test/integration/Mempool.test.ts +++ b/packages/sequencer/test/integration/Mempool.test.ts @@ -134,18 +134,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce).toStrictEqual("0"); - expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].nonce).toStrictEqual("0"); - expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].nonce).toStrictEqual("0"); - expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].nonce).toStrictEqual("1"); - expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].nonce).toStrictEqual("1"); - expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].nonce).toStrictEqual("1"); - expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].data.nonce).toStrictEqual("0"); + expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].data.nonce).toStrictEqual("0"); + expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].data.nonce).toStrictEqual("0"); + expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].data.nonce).toStrictEqual("1"); + expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].data.nonce).toStrictEqual("1"); + expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].data.nonce).toStrictEqual("1"); + expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - medium", async () => { @@ -163,18 +163,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce).toStrictEqual("0"); - expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].nonce).toStrictEqual("0"); - expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].nonce).toStrictEqual("1"); - expect(txs[2].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[3].nonce).toStrictEqual("1"); - expect(txs[3].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[4].nonce).toStrictEqual("0"); - expect(txs[4].sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[5].nonce).toStrictEqual("1"); - expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].data.nonce).toStrictEqual("0"); + expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].data.nonce).toStrictEqual("0"); + expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].data.nonce).toStrictEqual("1"); + expect(txs[2].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[3].data.nonce).toStrictEqual("1"); + expect(txs[3].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[4].data.nonce).toStrictEqual("0"); + expect(txs[4].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[5].data.nonce).toStrictEqual("1"); + expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - harder", async () => { @@ -190,18 +190,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce).toStrictEqual("0"); - expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].nonce).toStrictEqual("0"); - expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].nonce).toStrictEqual("0"); - expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].nonce).toStrictEqual("1"); - expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].nonce).toStrictEqual("1"); - expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].nonce).toStrictEqual("1"); - expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].data.nonce).toStrictEqual("0"); + expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].data.nonce).toStrictEqual("0"); + expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].data.nonce).toStrictEqual("0"); + expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].data.nonce).toStrictEqual("1"); + expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].data.nonce).toStrictEqual("1"); + expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].data.nonce).toStrictEqual("1"); + expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - hardest", async () => { @@ -219,18 +219,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].nonce).toStrictEqual("0"); - expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].nonce).toStrictEqual("0"); - expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].nonce).toStrictEqual("0"); - expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].nonce).toStrictEqual("1"); - expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].nonce).toStrictEqual("1"); - expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].nonce).toStrictEqual("1"); - expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].data.nonce).toStrictEqual("0"); + expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].data.nonce).toStrictEqual("0"); + expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].data.nonce).toStrictEqual("0"); + expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].data.nonce).toStrictEqual("1"); + expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].data.nonce).toStrictEqual("1"); + expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].data.nonce).toStrictEqual("1"); + expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); }); } ); diff --git a/packages/sequencer/test/production/tracing/StateTransitionTracingService.test.ts b/packages/sequencer/test/production/tracing/StateTransitionTracingService.test.ts index 6c877194c..b26505cfd 100644 --- a/packages/sequencer/test/production/tracing/StateTransitionTracingService.test.ts +++ b/packages/sequencer/test/production/tracing/StateTransitionTracingService.test.ts @@ -61,10 +61,10 @@ async function applyBatchesToTree( const tree = new LinkedMerkleTree(cached.treeStore, cached); await mapSequential(sts, async (st) => { - await cached.preloadKey(st.path.toBigInt()); + await cached.preloadKey(BigInt(st.path)); - if (st.to.isSome.toBoolean()) { - tree.setLeaf(st.path.toBigInt(), st.to.treeValue.toBigInt()); + if (st.to.isSome) { + tree.setLeaf(BigInt(st.path), BigInt(st.to.treeValue)); } }); diff --git a/packages/sequencer/test/settlement/Settlement-only.ts b/packages/sequencer/test/settlement/Settlement-only.ts index 7339f7906..02f63432f 100644 --- a/packages/sequencer/test/settlement/Settlement-only.ts +++ b/packages/sequencer/test/settlement/Settlement-only.ts @@ -173,7 +173,7 @@ export const settlementOnlyTestFn = ( await mempool.add(tx); } await mapSequential(txs, async (tx) => { - await mempool.add(tx.toJSON()); + await mempool.add(tx); }); const result = await trigger.produceBlockAndBatch(); From 0c38966a975dfd887e3a883d16005e6af9e8c786 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 18:06:13 +0300 Subject: [PATCH 51/63] refactor: add helper methods to UntypedOption and UntypedStateTransition --- .../production/helpers/UntypedOption.ts | 39 +++++++++++-------- .../helpers/UntypedStateTransition.ts | 25 ++++-------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts index c4f2b32fd..ddc37416a 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts @@ -1,9 +1,6 @@ import { Bool, Field, Poseidon } from "o1js"; -import { Option, OptionBase } from "@proto-kit/protocol"; +import { Option, ProvableOption } from "@proto-kit/protocol"; -/** - * Option facilitating in-circuit values that may or may not exist. - */ export class UntypedOption { public constructor( public isSome: boolean, @@ -11,15 +8,13 @@ export class UntypedOption { public isForcedSome: boolean ) {} - public get treeValue() { - const treeValue = Poseidon.hash(this.encodeValueToFields()); - - if(this.isSome && !this.isForcedSome){ - return treeValue.toString(); + public get treeValue(): string { + if (this.isSome && !this.isForcedSome) { + return Poseidon.hash(this.encodeValueToFields()).toString(); } return "0"; } - + public static fromOption(option: Option | Option) { return new UntypedOption( option.isSome.toBoolean(), @@ -40,19 +35,31 @@ export class UntypedOption { return new UntypedOption(isSome, value, isForcedSome); } - public toJSON(){ + public toJSON() { return { - isSome: this.isSome, - value: this.value, - isForcedSome: this.isForcedSome + isSome: this.isSome, + value: this.value, + isForcedSome: this.isForcedSome, }; } public clone() { - return new UntypedOption(this.isSome, this.value, this.isForcedSome); + return new UntypedOption(this.isSome, [...this.value], this.isForcedSome); } + public forceSome() { + this.isForcedSome = !this.isSome; + this.isSome = true; + } + public encodeValueToFields(): Field[] { - return this.value.map((fieldString) => Field(fieldString)) + return this.value.map((fieldString) => Field(fieldString)); + } + + public toProvable(): ProvableOption { + return new ProvableOption({ + isSome: Bool(this.isSome), + value: Field(this.treeValue), + }); } } \ No newline at end of file diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index d88901472..49f520da6 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -1,12 +1,7 @@ -import { Bool, Field } from "o1js"; -import { ProvableOption, ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; - +import { Field } from "o1js"; +import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; import { UntypedOption } from "./UntypedOption"; -/** - * Generic state transition that constraints the current method circuit - * to external state, by providing a state anchor. - */ export class UntypedStateTransition { public static fromStateTransition(st: StateTransition) { return new UntypedStateTransition( @@ -47,17 +42,13 @@ export class UntypedStateTransition { } public toProvable(): ProvableStateTransition { + const from = this.from.clone(); + from.forceSome(); + return new ProvableStateTransition({ path: Field(this.path), - from: new ProvableOption({ - isSome: Bool(this.from.isSome), - value: Field(this.from.treeValue), - }), - to: new ProvableOption({ - isSome: Bool(this.to.isSome), - value: Field(this.to.treeValue), - }), + from: from.toProvable(), + to: this.to.toProvable(), }); } -} - +} \ No newline at end of file From 019591f214225f3e60b59c3c5490848b56d3e49f Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 19:43:07 +0300 Subject: [PATCH 52/63] refactor: flatten PendingTransaction like UnsignedTransaction --- .../src/mempool/PendingTransaction.ts | 72 +++++++++++-------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index 70aeb980d..7ea72a3f7 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -134,9 +134,16 @@ export interface PendingTransactionJSONType { } export class PendingTransaction { - public static fromJSON( - object: PendingTransactionJSONType - ): PendingTransaction { + public readonly hash: string; + public readonly methodId: string; + public readonly nonce: string; + public readonly sender: string; + public readonly argsFields: string[]; + public readonly auxiliaryData: string[]; + public readonly signature: { r: string; s: string }; + public readonly isMessage: boolean; + + public static fromJSON(object: PendingTransactionJSONType): PendingTransaction { return new PendingTransaction({ hash: object.hash, methodId: object.methodId, @@ -149,46 +156,53 @@ export class PendingTransaction { }); } - public constructor( - public data: { - hash: FieldString; - methodId: FieldString; - nonce: string; - sender: string; - argsFields: FieldString[]; - auxiliaryData: string[]; - signature: { r: string; s: string }; - isMessage: boolean; - } - ) {} + public constructor(data: { + hash: string; + methodId: string; + nonce: string; + sender: string; + argsFields: string[]; + auxiliaryData: string[]; + signature: { r: string; s: string }; + isMessage: boolean; + }) { + this.hash = data.hash; + this.methodId = data.methodId; + this.nonce = data.nonce; + this.sender = data.sender; + this.argsFields = data.argsFields; + this.auxiliaryData = data.auxiliaryData; + this.signature = data.signature; + this.isMessage = data.isMessage; + } public toJSON(): PendingTransactionJSONType { return { - hash: this.data.hash, - methodId: this.data.methodId, - nonce: this.data.nonce, - sender: this.data.sender, - argsFields: this.data.argsFields.slice(), - auxiliaryData: this.data.auxiliaryData.slice(), - signature: { r: this.data.signature.r, s: this.data.signature.s }, - isMessage: this.data.isMessage, + hash: this.hash, + methodId: this.methodId, + nonce: this.nonce, + sender: this.sender, + argsFields: this.argsFields.slice(), + auxiliaryData: this.auxiliaryData.slice(), + signature: { r: this.signature.r, s: this.signature.s }, + isMessage: this.isMessage, }; } public toRuntimeTransaction(): RuntimeTransaction { - const isSome = Bool(!this.data.isMessage); + const isSome = Bool(!this.isMessage); return new RuntimeTransaction({ - methodId: Field(this.data.methodId), - argsHash: Poseidon.hash(this.data.argsFields.map((f) => Field(f))), - nonce: new UInt64Option({ value: UInt64.from(this.data.nonce), isSome }), - sender: new PublicKeyOption({ value: PublicKey.fromBase58(this.data.sender), isSome }), + methodId: Field(this.methodId), + argsHash: Poseidon.hash(this.argsFields.map((f) => Field(f))), + nonce: new UInt64Option({ value: UInt64.from(this.nonce), isSome }), + sender: new PublicKeyOption({ value: PublicKey.fromBase58(this.sender), isSome }), }); } public toProtocolTransaction(): SignedTransaction { return new SignedTransaction({ transaction: this.toRuntimeTransaction(), - signature: Signature.fromJSON(this.data.signature), + signature: Signature.fromJSON(this.signature), }); } } \ No newline at end of file From 9fd7a92b868dc1d25121ef2edf1806f36d3de8b4 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 19:47:27 +0300 Subject: [PATCH 53/63] refactor: update code using PendingTransaction --- .../src/graphql/modules/MempoolResolver.ts | 6 +- packages/indexer/test/IndexerNotifier.test.ts | 4 +- .../src/hooks/RuntimeFeeAnalyzerService.ts | 8 +- .../library/src/hooks/TransactionFeeHook.ts | 6 +- .../src/services/prisma/PrismaBlockStorage.ts | 2 +- .../prisma/mappers/TransactionMapper.ts | 18 ++-- .../PrismaBlockProduction.test.ts | 12 +-- .../processor/test/HandlersExecutor.test.ts | 6 +- .../src/transaction/AppChainTransaction.ts | 1 - .../sdk/test/fees-multi-zkprograms.test.ts | 13 +-- packages/sdk/test/fees.test.ts | 3 +- .../src/mempool/private/PrivateMempool.ts | 22 ++--- .../verification/TransactionValidator.ts | 6 +- .../sequencing/BlockProducerModule.ts | 8 +- .../sequencing/BlockProductionService.ts | 2 +- .../sequencing/TransactionExecutionService.ts | 22 ++--- .../production/tasks/RuntimeProvingTask.ts | 10 +- .../tracing/StateTransitionTracingService.ts | 9 +- .../tracing/TransactionTracingService.ts | 6 +- .../inmemory/InMemoryTransactionStorage.ts | 12 +-- packages/sequencer/test/Mempool.test.ts | 2 +- .../test/integration/Mempool.test.ts | 96 +++++++++---------- .../integration/StorageIntegration.test.ts | 8 +- .../production/helpers/UntypedOption.test.ts | 7 +- .../helpers/UntypedStateTransition.test.ts | 7 +- packages/stack/test/graphql/graphql.test.ts | 4 +- 26 files changed, 150 insertions(+), 150 deletions(-) diff --git a/packages/api/src/graphql/modules/MempoolResolver.ts b/packages/api/src/graphql/modules/MempoolResolver.ts index d26c85541..0d97b618a 100644 --- a/packages/api/src/graphql/modules/MempoolResolver.ts +++ b/packages/api/src/graphql/modules/MempoolResolver.ts @@ -49,7 +49,7 @@ export class TransactionObject { isMessage, } = pt.toJSON(); return new TransactionObject( - pt.data.hash, + pt.hash, methodId, sender, nonce, @@ -128,7 +128,7 @@ export class MempoolResolver extends GraphqlModule { const decoded = PendingTransaction.fromJSON(tx); await this.mempool.add(decoded); - return decoded.data.hash; + return decoded.hash; } // TODO Add retrieval of pending messages somewhere as well @@ -162,6 +162,6 @@ export class MempoolResolver extends GraphqlModule { }) public async transactions() { const txs = await this.transactionStorage.getPendingUserTransactions(); - return txs.map((x) => x.data.hash); + return txs.map((x) => x.hash); } } diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 7b90b572f..3939bb73a 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -131,7 +131,7 @@ async function sendTransactions( { nonce: i } ); - console.log("tx nonce", (tx.transaction as PendingTransaction).data.nonce); + console.log("tx nonce", (tx.transaction as PendingTransaction).nonce); await tx.sign(); await tx.send(); @@ -142,7 +142,7 @@ async function sendTransactions( const txs = await mempool.getTxs(); console.log( "txs", - txs.map((tx) => tx.data.nonce) + txs.map((tx) => tx.nonce) ); return await appChain.produceBlock(); diff --git a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts index 47245baa1..351b273fc 100644 --- a/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts +++ b/packages/library/src/hooks/RuntimeFeeAnalyzerService.ts @@ -166,8 +166,8 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule { const feeConfig = Provable.witness(MethodFeeConfigData, () => this.feeAnalyzer.getFeeConfig( - executionData.transaction.methodId.toBigInt() + executionData.transaction.methodId.toString() ) ); const witness = Provable.witness( RuntimeFeeAnalyzerService.getWitnessType(), () => this.feeAnalyzer.getWitness( - executionData.transaction.methodId.toBigInt() + executionData.transaction.methodId.toString() ) ); @@ -167,7 +167,7 @@ export class TransactionFeeHook extends ProvableTransactionHook { const feeConfig = this.feeAnalyzer.getFeeConfig( - args.transaction.methodId.toBigInt() + args.transaction.methodId.toString() ); const fee = this.getFee(feeConfig); diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 69ed9db1b..26521d3ba 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -81,7 +81,7 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { public async pushBlock(block: Block): Promise { log.trace( "Pushing block to DB. Txs:", - block.transactions.map((x) => x.tx.data.hash) + block.transactions.map((x) => x.tx.hash) ); const transactions = block.transactions.map( diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index b59bdf396..e3d435809 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -36,15 +36,15 @@ export class TransactionMapper public mapOut(input: PendingTransaction): DBTransaction { return { - hash: input.data.hash, - methodId: input.data.methodId, - nonce: input.data.nonce, - sender: input.data.sender, - argsFields: input.data.argsFields, - auxiliaryData: input.data.auxiliaryData, - isMessage: input.data.isMessage, - signature_r: input.data.signature.r, - signature_s: input.data.signature.s, + hash: input.hash, + methodId: input.methodId, + nonce: input.nonce, + sender: input.sender, + argsFields: input.argsFields, + auxiliaryData: input.auxiliaryData, + isMessage: input.isMessage, + signature_r: input.signature.r, + signature_s: input.signature.s, }; } } diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index 04848a76b..10ce56ac6 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -96,8 +96,8 @@ describe("prisma integration", () => { // Check that transactions match expect(retrievedBlock.transactions).toHaveLength(1); - expect(retrievedBlock.transactions[0].tx.data.hash).toStrictEqual( - block.transactions[0].tx.data.hash + expect(retrievedBlock.transactions[0].tx.hash).toStrictEqual( + block.transactions[0].tx.hash ); expect(retrievedBlock.hash).toStrictEqual(block.hash); @@ -227,13 +227,13 @@ describe("prisma integration", () => { let txHash: string; if (transaction.transaction instanceof PendingTransaction) { - txHash = transaction.transaction.data.hash; + txHash = transaction.transaction.hash; } else { txHash = transaction.transaction!.hash().toString(); } expect(txs).toHaveLength(1); - expect(txs[0].data.hash).toStrictEqual(txHash); + expect(txs[0].hash).toStrictEqual(txHash); }); it("should resolve transaction from storage as pending", async () => { @@ -249,13 +249,13 @@ describe("prisma integration", () => { let txHash: string; if (transaction.transaction instanceof PendingTransaction) { - txHash = transaction.transaction.data.hash; + txHash = transaction.transaction.hash; } else { txHash = transaction.transaction!.hash().toString(); } expect(txs).toHaveLength(1); - expect(txs[0].data.hash).toStrictEqual( + expect(txs[0].hash).toStrictEqual( txHash ); }); diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index 953e3643d..7f396bb92 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -42,7 +42,7 @@ describe("HandlersModule", () => { ) => { // iterate over all transactions for (const tx of block.transactions) { - const methodId = tx.tx.data.methodId; + const methodId = tx.tx.methodId; const methodDescriptor = appChain.runtime.methodIdResolver.getMethodNameFromId(methodId); @@ -66,8 +66,8 @@ describe("HandlersModule", () => { // @ts-expect-error const [, from, to, amount]: [TokenId, PublicKey, PublicKey, Balance] = await parameterDecoder.decode( - tx.tx.data.argsFields.map(Field), - tx.tx.data.auxiliaryData + tx.tx.argsFields.map(Field), + tx.tx.auxiliaryData ); const currentFromBalance = await client.balance.findFirst({ diff --git a/packages/sdk/src/transaction/AppChainTransaction.ts b/packages/sdk/src/transaction/AppChainTransaction.ts index ab6ea9ab5..496772e17 100644 --- a/packages/sdk/src/transaction/AppChainTransaction.ts +++ b/packages/sdk/src/transaction/AppChainTransaction.ts @@ -47,7 +47,6 @@ export class AppChainTransaction { public async send() { this.hasPendingTransaction(this.transaction); - // Wait for next commit await this.transactionSender.send(this.transaction); } } diff --git a/packages/sdk/test/fees-multi-zkprograms.test.ts b/packages/sdk/test/fees-multi-zkprograms.test.ts index 53d4389f9..e32911e15 100644 --- a/packages/sdk/test/fees-multi-zkprograms.test.ts +++ b/packages/sdk/test/fees-multi-zkprograms.test.ts @@ -6,7 +6,7 @@ import { expectDefined, noop } from "@proto-kit/common"; import { inject } from "tsyringe"; import { Balance, Balances, BalancesKey, TokenId } from "@proto-kit/library"; -import { TestingAppChain } from "../src"; +import { TestingAppChain } from "../src"; // This test is designed to check what happens when we have multiple zkPrograms. // Currently, the hardcoded maximum for methods per zkProgram is 8 (see Runtime.ts). @@ -226,8 +226,9 @@ describe("check fee analyzer", () => { ); await tx2.sign(); - await tx2.send(); - const methodId2 = tx2.transaction?.methodId.toBigInt(); + await tx2.send(); + + const methodId2 = tx2.transaction?.methodId.toString() expectDefined(methodId2); const transactionFeeConfig2 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId2); @@ -244,7 +245,7 @@ describe("check fee analyzer", () => { await tx3.sign(); await tx3.send(); - const methodId3 = tx3.transaction?.methodId.toBigInt(); + const methodId3 = tx3.transaction?.methodId.toString() expectDefined(methodId3); const transactionFeeConfig3 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId3); @@ -262,7 +263,7 @@ describe("check fee analyzer", () => { await tx4.sign(); await tx4.send(); - const methodId4 = tx4.transaction?.methodId.toBigInt(); + const methodId4 = tx4.transaction?.methodId.toString() expectDefined(methodId4); const transactionFeeConfig4 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId4); @@ -280,7 +281,7 @@ describe("check fee analyzer", () => { await tx5.sign(); await tx5.send(); - const methodId5 = tx5.transaction?.methodId.toBigInt(); + const methodId5 = tx5.transaction?.methodId.toString() expectDefined(methodId5); const transactionFeeConfig5 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId5); diff --git a/packages/sdk/test/fees.test.ts b/packages/sdk/test/fees.test.ts index 9adaa126d..83c8e78ac 100644 --- a/packages/sdk/test/fees.test.ts +++ b/packages/sdk/test/fees.test.ts @@ -135,7 +135,8 @@ describe("fees", () => { await pit.burn(burnAmount); }); - const methodId = tx.transaction?.methodId.toBigInt(); + + const methodId = tx.transaction?.methodId.toString(); expectDefined(methodId); const transactionFeeConfig = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId); diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index ca6179d17..f962e69eb 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -85,21 +85,21 @@ export class PrivateMempool "mempool-transaction-added", tx ); - log.trace(`Transaction added to mempool: ${tx.data.hash}`); + log.trace(`Transaction added to mempool: ${tx.hash}`); } else { - log.error(`Transaction ${tx.data.hash} rejected: already exists in mempool`); + log.error(`Transaction ${tx.hash} rejected: already exists in mempool`); } return success; } log.error( - `Validation of tx ${tx.data.hash} failed:`, + `Validation of tx ${tx.hash} failed:`, `${error ?? "unknown error"}` ); throw new Error( - `Validation of tx ${tx.data.hash} failed: ${error ?? "unknown error"}` + `Validation of tx ${tx.hash} failed: ${error ?? "unknown error"}` ); } @@ -225,13 +225,13 @@ export class PrivateMempool executionContext.current().result; if (status.toBoolean()) { - log.trace(`Accepted tx ${tx.data.hash}`); + log.trace(`Accepted tx ${tx.hash}`); sortedTransactions.push(tx); // eslint-disable-next-line no-await-in-loop await txStateService.applyStateTransitions(stateTransitions); // eslint-disable-next-line no-await-in-loop await txStateService.mergeIntoParent(); - delete skippedTransactions[tx.data.hash]; + delete skippedTransactions[tx.hash]; if (Object.entries(skippedTransactions).length > 0) { // eslint-disable-next-line @typescript-eslint/no-loop-func stateTransitions.forEach((st) => { @@ -253,17 +253,17 @@ export class PrivateMempool }); if (removeTxWhen) { // eslint-disable-next-line no-await-in-loop - await this.transactionStorage.removeTx([tx.data.hash], "dropped"); + await this.transactionStorage.removeTx([tx.hash], "dropped"); log.trace( - `Deleting tx ${tx.data.hash} from mempool because removeTransactionWhen condition is satisfied` + `Deleting tx ${tx.hash} from mempool because removeTransactionWhen condition is satisfied` ); // eslint-disable-next-line no-continue continue; } - log.trace(`Skipped tx ${tx.data.hash} because ${statusMessage}`); - if (!(tx.data.hash in skippedTransactions)) { - skippedTransactions[tx.data.hash] = { + log.trace(`Skipped tx ${tx.hash} because ${statusMessage}`); + if (!(tx.hash in skippedTransactions)) { + skippedTransactions[tx.hash] = { transaction: tx, paths: stateTransitions .map((x) => x.path) diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index 25782e1e2..1f69ee2c4 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -23,11 +23,11 @@ export class TransactionValidator { // module name validation happens inside getMethodNameFromId // and also in the next step const methodPath = this.runtime.methodIdResolver.getMethodNameFromId( - tx.data.methodId + tx.methodId ); if (methodPath === undefined) { - return `Method with id ${tx.data.methodId} does not exist`; + return `Method with id ${tx.methodId} does not exist`; } // Check if parameters are decodable @@ -50,7 +50,7 @@ export class TransactionValidator { return [false, methodError]; } - const signature = Signature.fromJSON(tx.data.signature) + const signature = Signature.fromJSON(tx.signature) const runtimeTx = tx.toRuntimeTransaction(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 000f2bbb6..e94af7733 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -74,7 +74,7 @@ export class BlockProducerModule extends SequencerModule { private prettyPrintBlockContents(block: Block) { block.transactions.forEach((tx, i) => { const methodName = this.methodIdResolver.getMethodNameFromId( - tx.tx.data.methodId + tx.tx.methodId ); if (!methodName) return; @@ -86,15 +86,15 @@ export class BlockProducerModule extends SequencerModule { log.info("---------------------------------------"); log.info(`Transaction #${i}`); - log.info("Sender:", tx.tx.data.sender, "Nonce:", tx.tx.data.nonce); + log.info("Sender:", tx.tx.sender, "Nonce:", tx.tx.nonce); log.info(`Method: ${methodName?.join(".")}`); log.info(); if (log.getLevel() <= log.levels.INFO) { Provable.log( "Arguments:", paramEncoder.decode( - tx.tx.data.argsFields.map((s) => Field(s)), - tx.tx.data.auxiliaryData + tx.tx.argsFields.map((s) => Field(s)), + tx.tx.auxiliaryData ) ); } diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index dab82fd46..430ba0c8c 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -196,7 +196,7 @@ export class BlockProductionService { const includedTxs = executionResults.map((x) => { const txHash = match(x) .with({ status: "included" }, ({ result }) => result.tx) - .otherwise(({ tx }) => tx).data.hash; + .otherwise(({ tx }) => tx).hash; return { hash: txHash, diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index eb8afce49..d302bb028 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -89,13 +89,13 @@ async function decodeTransaction( module: RuntimeModule; }> { const methodDescriptors = runtime.methodIdResolver.getMethodNameFromId( - tx.data.methodId + tx.methodId ); - const method = runtime.getMethodById(tx.data.methodId); + const method = runtime.getMethodById(tx.methodId); if (methodDescriptors === undefined || method === undefined) { - throw errors.methodIdNotFound(tx.data.methodId); + throw errors.methodIdNotFound(tx.methodId); } const [moduleName, methodName] = methodDescriptors; @@ -106,8 +106,8 @@ async function decodeTransaction( methodName ); const args = await parameterDecoder.decode( - tx.data.argsFields.map(Field), - tx.data.auxiliaryData + tx.argsFields.map(Field), + tx.auxiliaryData ); return { @@ -323,7 +323,7 @@ export class TransactionExecutionService { // Add tx to commitments return addTransactionToBundle( state, - Bool(tx.data.isMessage), + Bool(tx.isMessage), signedTransaction.transaction ); } @@ -360,7 +360,7 @@ export class TransactionExecutionService { // If the hooks fail AND the tx is not a message (in which case we // have to still execute it), we skip this tx and don't add it to the block - if (!executionTrace.hooksStatus && !executionTrace.tx.data.isMessage) { + if (!executionTrace.hooksStatus && !executionTrace.tx.isMessage) { const actionMessage = shouldRemove ? "removing as to removeWhen hooks" : "skipping"; @@ -404,8 +404,8 @@ export class TransactionExecutionService { @trace("block.transaction", ([, tx, { networkState }]) => ({ height: networkState.block.height.toString(), - methodId: tx.data.methodId.toString(), - isMessage: tx.data.isMessage, + methodId: tx.methodId.toString(), + isMessage: tx.isMessage, })) public async createExecutionTrace( asyncStateService: CachedStateService, @@ -491,8 +491,8 @@ export class TransactionExecutionService { new MethodPublicOutput({ status: runtimeResult.status, networkStateHash: networkStateHash, - isMessage: Bool(tx.data.isMessage), - transactionHash: Field(tx.data.hash), + isMessage: Bool(tx.isMessage), + transactionHash: Field(tx.hash), eventsHash, stateTransitionsHash, }) diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 10d7926f4..81dca8ff9 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -68,14 +68,14 @@ export class RuntimeProvingTask ProvableNetworkState.fromJSON(input.networkState) ); - const method = this.runtime.getMethodById(tx.data.methodId); + const method = this.runtime.getMethodById(tx.methodId); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(tx.data.methodId); + .getMethodNameFromId(tx.methodId); if (methodDescriptors === undefined || method === undefined) { - throw new Error(`MethodId not found ${tx.data.methodId}`); + throw new Error(`MethodId not found ${tx.methodId}`); } const [moduleName, methodName] = methodDescriptors; @@ -85,8 +85,8 @@ export class RuntimeProvingTask methodName ); const decodedArguments = await parameterEncoder.decode( - tx.data.argsFields.map(Field), - tx.data.auxiliaryData + tx.argsFields.map(Field), + tx.auxiliaryData ); const prefilledStateService = new PreFilledStateService( diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index 1c5dc454c..b5df930b2 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -1,4 +1,4 @@ -import { Bool, Field } from "o1js"; +import { Bool, Field, Poseidon } from "o1js"; import { LinkedMerkleTree, LinkedMerkleTreeWitness, @@ -9,6 +9,7 @@ import { AppliedBatchHashList, AppliedStateTransitionBatchState, DefaultProvableHashList, + ProvableOption, ProvableStateTransition, StateTransitionProvableBatch, StateTransitionProverPublicInput, @@ -55,7 +56,7 @@ export class StateTransitionTracingService { ...block.block.transactions.flatMap((tx) => tx.stateTransitions.map((batch) => ({ stateTransitions: batch.stateTransitions.map((st) => - UntypedStateTransition.fromJSON(st) + st ), applied: batch.applied, })) @@ -84,13 +85,13 @@ export class StateTransitionTracingService { stateTransitions: TracingStateTransitionBatch[] ) { const batches = StateTransitionProvableBatch.fromBatches( - stateTransitions.map( + stateTransitions.map( ({ stateTransitions: batchStateTransitions, applied, witnessRoot, }) => ({ - stateTransitions: batchStateTransitions.map((transition) => + stateTransitions: batchStateTransitions.map((transition) => transition.toProvable() ), applied: Bool(applied), diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 4ad74f767..275eacf7c 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -73,12 +73,12 @@ export class TransactionTracingService { ): Promise { const verificationKeyAttestation = this.verificationKeyService.getAttestation( - transaction.data.methodId + transaction.methodId ); return { transaction: transaction.toRuntimeTransaction(), - signature: Signature.fromJSON(transaction.data.signature), + signature: Signature.fromJSON(transaction.signature), verificationKeyAttestation, }; } @@ -107,7 +107,7 @@ export class TransactionTracingService { // TODO Remove this call and instead reuse results from sequencing const newState = addTransactionToBundle( previousState, - Bool(tx.data.isMessage), + Bool(tx.isMessage), tx.toRuntimeTransaction() ); diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index 54dbb867b..ed78a7661 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -21,7 +21,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { public async removeTx(hashes: string[]) { const hashSet = new Set(hashes); this.queue = this.queue.filter((tx) => { - return !hashSet.has(tx.data.hash); + return !hashSet.has(tx.hash); }); } @@ -37,8 +37,8 @@ export class InMemoryTransactionStorage implements TransactionStorage { // eslint-disable-next-line no-await-in-loop const block = await this.blockStorage.getBlockAt(height); if (block !== undefined) { - const hashes = block.transactions.map((tx) => tx.tx.data.hash); - this.queue = this.queue.filter((tx) => !hashes.includes(tx.data.hash)); + const hashes = block.transactions.map((tx) => tx.tx.hash); + this.queue = this.queue.filter((tx) => !hashes.includes(tx.hash)); } } this.latestScannedBlock = nextHeight - 1; @@ -50,7 +50,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { tx: PendingTransaction ): Promise { const notInQueue = - this.queue.find((tx2) => tx2.data.hash === tx.data.hash) === undefined; + this.queue.find((tx2) => tx2.hash === tx.hash) === undefined; if (notInQueue) { this.queue.push(tx); } @@ -82,7 +82,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { | undefined > { const pending = await this.getPendingUserTransactions(); - const pendingResult = pending.find((tx) => tx.data.hash === hash); + const pendingResult = pending.find((tx) => tx.hash === hash); if (pendingResult !== undefined) { return { transaction: pendingResult, @@ -97,7 +97,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { if (block === undefined) { return undefined; } - const txResult = block.transactions.find((tx) => tx.tx.data.hash === hash); + const txResult = block.transactions.find((tx) => tx.tx.hash === hash); if (txResult !== undefined) { // eslint-disable-next-line no-await-in-loop const batch = await this.findBatch(block.hash); diff --git a/packages/sequencer/test/Mempool.test.ts b/packages/sequencer/test/Mempool.test.ts index 32260bb00..a2eb6a339 100644 --- a/packages/sequencer/test/Mempool.test.ts +++ b/packages/sequencer/test/Mempool.test.ts @@ -25,7 +25,7 @@ describe("memPool", () => { const signed = unsigned.sign(pk); expect(data).toStrictEqual(signed.toProtocolTransaction().getSignatureData()); - expect(hash).toStrictEqual(signed.data.hash); + expect(hash).toStrictEqual(signed.hash); }); }); diff --git a/packages/sequencer/test/integration/Mempool.test.ts b/packages/sequencer/test/integration/Mempool.test.ts index 6f48233b2..2054b7f86 100644 --- a/packages/sequencer/test/integration/Mempool.test.ts +++ b/packages/sequencer/test/integration/Mempool.test.ts @@ -134,18 +134,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].data.nonce).toStrictEqual("0"); - expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].data.nonce).toStrictEqual("0"); - expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].data.nonce).toStrictEqual("0"); - expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].data.nonce).toStrictEqual("1"); - expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].data.nonce).toStrictEqual("1"); - expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].data.nonce).toStrictEqual("1"); - expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - medium", async () => { @@ -163,18 +163,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].data.nonce).toStrictEqual("0"); - expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].data.nonce).toStrictEqual("0"); - expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].data.nonce).toStrictEqual("1"); - expect(txs[2].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[3].data.nonce).toStrictEqual("1"); - expect(txs[3].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[4].data.nonce).toStrictEqual("0"); - expect(txs[4].data.sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[5].data.nonce).toStrictEqual("1"); - expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("1"); + expect(txs[2].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("0"); + expect(txs[4].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - harder", async () => { @@ -190,18 +190,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].data.nonce).toStrictEqual("0"); - expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].data.nonce).toStrictEqual("0"); - expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].data.nonce).toStrictEqual("0"); - expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].data.nonce).toStrictEqual("1"); - expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].data.nonce).toStrictEqual("1"); - expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].data.nonce).toStrictEqual("1"); - expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); it("transactions are returned in right order - hardest", async () => { @@ -219,18 +219,18 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await mempool.getTxs(); expect(txs).toHaveLength(6); - expect(txs[0].data.nonce).toStrictEqual("0"); - expect(txs[0].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[1].data.nonce).toStrictEqual("0"); - expect(txs[1].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[2].data.nonce).toStrictEqual("0"); - expect(txs[2].data.sender).toStrictEqual(user3PublicKey.toBase58()); - expect(txs[3].data.nonce).toStrictEqual("1"); - expect(txs[3].data.sender).toStrictEqual(user1PublicKey.toBase58()); - expect(txs[4].data.nonce).toStrictEqual("1"); - expect(txs[4].data.sender).toStrictEqual(user2PublicKey.toBase58()); - expect(txs[5].data.nonce).toStrictEqual("1"); - expect(txs[5].data.sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[0].nonce).toStrictEqual("0"); + expect(txs[0].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[1].nonce).toStrictEqual("0"); + expect(txs[1].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[2].nonce).toStrictEqual("0"); + expect(txs[2].sender).toStrictEqual(user3PublicKey.toBase58()); + expect(txs[3].nonce).toStrictEqual("1"); + expect(txs[3].sender).toStrictEqual(user1PublicKey.toBase58()); + expect(txs[4].nonce).toStrictEqual("1"); + expect(txs[4].sender).toStrictEqual(user2PublicKey.toBase58()); + expect(txs[5].nonce).toStrictEqual("1"); + expect(txs[5].sender).toStrictEqual(user3PublicKey.toBase58()); }); } ); diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 3ef0728e7..c8f951cb0 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -151,11 +151,7 @@ describe.each([["InMemory", InMemoryDatabase]])( expect(block2.hash).toStrictEqual(generatedBlock.hash); const input = block.transactions.flatMap((tx) => tx.stateTransitions.flatMap((batch) => - batch.stateTransitions.map((st) => - UntypedStateTransition.fromJSON(st) - ) - ) - ); + batch.stateTransitions)); const stateDiff = collectStateDiff(input); const state = await unprovenState.getMany( @@ -205,7 +201,7 @@ describe.each([["InMemory", InMemoryDatabase]])( const txs = await txStorage.getPendingUserTransactions(); expect(txs).toHaveLength(1); - expect(txs[0].data.hash).toStrictEqual(tx.data.hash); + expect(txs[0].hash).toStrictEqual(tx.hash); await sequencer.resolve("BlockTrigger").produceBlock(); diff --git a/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts b/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts index e14d343e7..45afe54d7 100644 --- a/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts +++ b/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts @@ -20,12 +20,12 @@ describe("option <-> untypedoption", () => { const untyped = UntypedOption.fromOption(option); - expect(untyped.isSome.toBoolean()).toStrictEqual(option.isSome.toBoolean()); - expect(untyped.isForcedSome.toBoolean()).toStrictEqual( + expect(untyped.isSome).toStrictEqual(option.isSome.toBoolean()); + expect(untyped.isForcedSome).toStrictEqual( option.isForcedSome.toBoolean() ); expect(untyped.value).toStrictEqual( - option.valueType.toFields(option.value) + option.valueType.toFields(option.value).map(f => f.toString()) ); const provable1 = option.toProvable(); @@ -34,3 +34,4 @@ describe("option <-> untypedoption", () => { expect(provable1).toStrictEqual(provable2); }); }); + diff --git a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts index a7e432037..77d76224a 100644 --- a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts +++ b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts @@ -30,10 +30,10 @@ describe("stateTransition", () => { const untyped = UntypedStateTransition.fromStateTransition(st); - expect(untyped.path).toStrictEqual(st.path); + expect(untyped.path).toStrictEqual(st.path.toString()); expect(untyped.from.value).toStrictEqual( - st.fromValue.valueType.toFields(st.fromValue.value) + st.fromValue.valueType.toFields(st.fromValue.value).map((f) => f.toString()) ); expect(untyped.from.isSome).toStrictEqual( st.fromValue.isSome.toBoolean() @@ -43,7 +43,7 @@ describe("stateTransition", () => { ); expect(untyped.to.value).toStrictEqual( - st.toValue.valueType.toFields(st.toValue.value) + st.toValue.valueType.toFields(st.toValue.value).map((f) => f.toString()) ); expect(untyped.to.isSome).toStrictEqual( st.toValue.isSome.toBoolean() @@ -53,6 +53,7 @@ describe("stateTransition", () => { ); const provable1 = st.toProvable(); + const provable2 = untyped.toProvable(); expect(provable1).toStrictEqual(provable2); diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index d22c9adf7..bc865c54a 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -188,7 +188,7 @@ describe("graphql client test", () => { const txHash = tx.transaction instanceof UnsignedTransaction ? tx.transaction.hash().toString() - : tx.transaction!.data.hash; + : tx.transaction!.hash; const waitPromise = appChain.query.explorer.fetchTxInclusion(txHash); @@ -231,7 +231,7 @@ describe("graphql client test", () => { const heightParsedTx = heightResult?.transactions!; - const blockTxHash = block?.transactions[0].tx.data.hash; + const blockTxHash = block?.transactions[0].tx.hash; const queryTxHash = heightParsedTx[0]?.tx?.hash; From cbecb5a6103bbfa0226c408b17f4b6d180b8a5cd Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 20:43:19 +0300 Subject: [PATCH 54/63] refactor: make decode to take string array as input --- packages/module/src/method/MethodParameterEncoder.ts | 10 ++++------ .../module/test/method/MethodParameterEncoder.test.ts | 11 ++++++----- packages/processor/test/HandlersExecutor.test.ts | 2 +- .../production/sequencing/BlockProducerModule.ts | 2 +- .../sequencing/TransactionExecutionService.ts | 2 +- .../protocol/production/tasks/RuntimeProvingTask.ts | 2 +- .../settlement/messages/MinaIncomingMessageAdapter.ts | 4 ++-- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/module/src/method/MethodParameterEncoder.ts b/packages/module/src/method/MethodParameterEncoder.ts index 691e0d6b2..d57360bc8 100644 --- a/packages/module/src/method/MethodParameterEncoder.ts +++ b/packages/module/src/method/MethodParameterEncoder.ts @@ -128,7 +128,7 @@ export class MethodParameterEncoder { public constructor(private readonly types: ArgTypeArray) {} - public decode(fields: Field[], auxiliary: string[]): Promise { + public decode(fields: string[], auxiliary: string[]): Promise { if (fields.length < this.fieldSize()) { throw errors.fieldLengthNotMatching(this.fieldSize(), fields.length); } @@ -156,11 +156,9 @@ export class MethodParameterEncoder { type.publicInputType )!; const input = structFields - .slice(0, inputFieldSize) - .map((x) => x.toString()); + .slice(0, inputFieldSize); const output = structFields - .slice(inputFieldSize) - .map((x) => x.toString()); + .slice(inputFieldSize); // fromJSON has incompatible signature for Proof and DynamicProof if (isProofType(type)) { @@ -180,7 +178,7 @@ export class MethodParameterEncoder { } return (type as FlexibleProvable).fromFields( - structFields, + structFields.map(Field), [] ) as any; }) diff --git a/packages/module/test/method/MethodParameterEncoder.test.ts b/packages/module/test/method/MethodParameterEncoder.test.ts index 9f4bb5c05..6b42dee4e 100644 --- a/packages/module/test/method/MethodParameterEncoder.test.ts +++ b/packages/module/test/method/MethodParameterEncoder.test.ts @@ -50,7 +50,8 @@ describe("MethodParameterEncoder", () => { expect(fields[0].toString()).toBe("2"); expect(fields[1].toString()).toStrictEqual(Bool(true).toField().toString()); - const decoded = await encoder.decode(fields, auxiliary); + const fieldString = fields.map(field => field.toString()); + const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); const decoded1 = decoded[0] as unknown as NonMethods; expect(decoded1.a.toString()).toStrictEqual("2"); @@ -70,8 +71,8 @@ describe("MethodParameterEncoder", () => { expect(fields.map((x) => x.toString())).toStrictEqual( pk.toFields().map((x) => x.toString()) ); - - const decoded = await encoder.decode(fields, auxiliary); + const fieldString = fields.map(field => field.toString()); + const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); const decoded1 = decoded[0] as unknown as PublicKey; @@ -105,8 +106,8 @@ describe("MethodParameterEncoder", () => { x.toString() ) ); - - const decoded = await encoder.decode(fields, auxiliary); + const fieldString = fields.map(field => field.toString()); + const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); const decoded1 = decoded[0] as unknown as Proof; diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index 7f396bb92..2474cf12f 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -66,7 +66,7 @@ describe("HandlersModule", () => { // @ts-expect-error const [, from, to, amount]: [TokenId, PublicKey, PublicKey, Balance] = await parameterDecoder.decode( - tx.tx.argsFields.map(Field), + tx.tx.argsFields, tx.tx.auxiliaryData ); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index e94af7733..913b59c10 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -93,7 +93,7 @@ export class BlockProducerModule extends SequencerModule { Provable.log( "Arguments:", paramEncoder.decode( - tx.tx.argsFields.map((s) => Field(s)), + tx.tx.argsFields, tx.tx.auxiliaryData ) ); diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index d302bb028..2dfaef1e1 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -106,7 +106,7 @@ async function decodeTransaction( methodName ); const args = await parameterDecoder.decode( - tx.argsFields.map(Field), + tx.argsFields, tx.auxiliaryData ); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 81dca8ff9..94e2c7b12 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -85,7 +85,7 @@ export class RuntimeProvingTask methodName ); const decodedArguments = await parameterEncoder.decode( - tx.argsFields.map(Field), + tx.argsFields, tx.auxiliaryData ); diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 150bc64c4..8620226ab 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -68,7 +68,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { private async mapActionToTransactions( tx: RuntimeTransaction, - fieldArgs: Field[] + fieldArgs: string[] ): Promise { const { methodId } = tx; @@ -180,7 +180,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { if (correspondingEvent === undefined) { throw new Error("Couldn't find events corresponding to action"); } - const args = correspondingEvent.event.data.map((x) => Field(x)); + const args = correspondingEvent.event.data; return await this.mapActionToTransactions(tx, args); }); From 44e9ea63e35571c648b6cbb87c2e25cfb78c08b6 Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 20:45:01 +0300 Subject: [PATCH 55/63] refactor: remove unnecessary lines and fix mappings --- .../persistance/src/services/prisma/mappers/BlockMapper.ts | 5 +++-- .../src/services/prisma/mappers/StateTransitionMapper.ts | 4 +--- packages/sequencer/src/mempool/PendingTransaction.ts | 2 +- packages/sequencer/src/storage/model/Block.ts | 2 -- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index c11e53d39..d16634810 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -35,9 +35,10 @@ export class BlockMapper implements ObjectMapper { previousBlockHash: input.parentHash !== null ? input.parentHash : undefined, - // This is cleaner to keep mapIn beforeBlockStateTransitions: - input.beforeBlockStateTransitions as unknown as UntypedStateTransition[], + this.stArrayMapper.mapIn( + input.beforeBlockStateTransitions + ), }; } diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index 0956edc39..75628ade5 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -17,9 +17,7 @@ export class StateTransitionMapper } public mapOut(input: UntypedStateTransition): Prisma.JsonObject { - // Already JSON-compatible, just cast - input.toJSON(); - return input as unknown as Prisma.JsonObject; + return input.toJSON(); } } diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index 7ea72a3f7..5c8e69f53 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -119,7 +119,7 @@ export class UnsignedTransaction implements UnsignedTransactionBody { } } -export interface PendingTransactionJSONType { +interface PendingTransactionJSONType { hash: string; methodId: string; nonce: string; diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 36c5f855b..1831b4581 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -35,8 +35,6 @@ export interface TransactionExecutionResult { }[]; } -// TODO Why is Block using Fields, but BlockResult bigints? Align that towards the best option - export interface Block { hash: FieldString; previousBlockHash: FieldString | undefined; From 4f776a760b3d54bf4e5208da91683d78fdeb1a0a Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 21:31:25 +0300 Subject: [PATCH 56/63] style: run lint fix --- .../api/src/graphql/modules/BlockResolver.ts | 2 +- packages/common/src/utils.ts | 2 - .../indexer/src/tasks/IndexPendingTxTask.ts | 4 +- .../src/method/MethodParameterEncoder.ts | 6 +- .../method/MethodParameterEncoder.test.ts | 6 +- .../src/services/prisma/PrismaBlockStorage.ts | 14 +- .../services/prisma/PrismaMessageStorage.ts | 5 +- .../prisma/PrismaTransactionStorage.ts | 8 +- .../services/prisma/mappers/BlockMapper.ts | 5 +- .../prisma/mappers/StateTransitionMapper.ts | 5 +- .../prisma/mappers/TransactionMapper.ts | 2 +- .../PrismaBlockProduction.test.ts | 12 +- .../processor/test/HandlersExecutor.test.ts | 4 +- .../protocol/src/hooks/BlockHeightHook.ts | 8 +- .../src/hooks/LastStateRootBlockHook.ts | 4 +- .../src/graphql/GraphqlTransactionSender.ts | 5 +- .../query/BlockStorageNetworkStateModule.ts | 4 +- .../sdk/src/query/InMemoryBlockExplorer.ts | 12 +- .../sdk/test/fees-multi-zkprograms.test.ts | 14 +- packages/sdk/test/fees.test.ts | 1 - packages/sequencer/src/helpers/utils.ts | 2 +- packages/sequencer/src/mempool/Mempool.ts | 4 +- .../src/mempool/PendingTransaction.ts | 193 +++++++++--------- .../src/mempool/private/PrivateMempool.ts | 12 +- .../verification/TransactionValidator.ts | 23 +-- .../production/BatchProducerModule.ts | 2 +- .../production/helpers/UntypedOption.ts | 10 +- .../helpers/UntypedStateTransition.ts | 3 +- .../sequencing/BlockProducerModule.ts | 7 +- .../sequencing/BlockProductionService.ts | 14 +- .../sequencing/BlockResultService.ts | 14 +- .../sequencing/TransactionExecutionService.ts | 15 +- .../protocol/production/tasks/NewBlockTask.ts | 6 +- .../production/tasks/RuntimeProvingTask.ts | 17 +- .../tasks/TransactionProvingTask.ts | 7 +- .../NewBlockProvingParametersSerializer.ts | 2 + .../RuntimeProofParametersSerializer.ts | 5 - ...ansactionProvingTaskParameterSerializer.ts | 4 +- .../production/tracing/BlockTracingService.ts | 2 +- .../tracing/StateTransitionTracingService.ts | 15 +- .../tracing/TransactionTracingService.ts | 36 +--- .../bridging/BridgingSettlementInteraction.ts | 8 +- .../vanilla/VanillaSettlementInteraction.ts | 8 +- .../messages/IncomingMessageAdapter.ts | 2 +- .../messages/MinaIncomingMessageAdapter.ts | 5 +- .../inmemory/InMemoryTransactionStorage.ts | 8 +- packages/sequencer/src/storage/model/Block.ts | 17 +- packages/sequencer/test/Mempool.test.ts | 4 +- .../integration/StorageIntegration.test.ts | 5 +- packages/sequencer/test/integration/utils.ts | 14 +- .../production/helpers/UntypedOption.test.ts | 7 +- .../helpers/UntypedStateTransition.test.ts | 12 +- packages/stack/test/graphql/graphql.test.ts | 8 +- 53 files changed, 278 insertions(+), 336 deletions(-) diff --git a/packages/api/src/graphql/modules/BlockResolver.ts b/packages/api/src/graphql/modules/BlockResolver.ts index 0379478ff..5313b0d39 100644 --- a/packages/api/src/graphql/modules/BlockResolver.ts +++ b/packages/api/src/graphql/modules/BlockResolver.ts @@ -1,5 +1,5 @@ import { inject } from "tsyringe"; -import { Block, BlockStorage, PendingTransaction } from "@proto-kit/sequencer"; +import { Block, BlockStorage } from "@proto-kit/sequencer"; import { Arg, Field, ObjectType, Query } from "type-graphql"; import { GraphqlModule, graphqlModule } from "../GraphqlModule"; diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index 039bf348f..0cca60cee 100644 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -296,7 +296,6 @@ export function assertDefined( } } - /** * Type for serialized {@link Field}. */ @@ -310,4 +309,3 @@ export type FieldString = string; export const FieldString = ( value: number | string | bigint | Field ): FieldString => String(value); - diff --git a/packages/indexer/src/tasks/IndexPendingTxTask.ts b/packages/indexer/src/tasks/IndexPendingTxTask.ts index eddabbaa5..db468660d 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTask.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTask.ts @@ -28,9 +28,7 @@ export class IndexPendingTxTask // eslint-disable-next-line @typescript-eslint/no-empty-function public async prepare(): Promise {} - public async compute( - input: PendingTransaction - ): Promise { + public async compute(input: PendingTransaction): Promise { try { await this.transactionStorage.pushUserTransaction(input); return ""; diff --git a/packages/module/src/method/MethodParameterEncoder.ts b/packages/module/src/method/MethodParameterEncoder.ts index d57360bc8..83fa21c23 100644 --- a/packages/module/src/method/MethodParameterEncoder.ts +++ b/packages/module/src/method/MethodParameterEncoder.ts @@ -155,10 +155,8 @@ export class MethodParameterEncoder { const inputFieldSize = MethodParameterEncoder.fieldSize( type.publicInputType )!; - const input = structFields - .slice(0, inputFieldSize); - const output = structFields - .slice(inputFieldSize); + const input = structFields.slice(0, inputFieldSize); + const output = structFields.slice(inputFieldSize); // fromJSON has incompatible signature for Proof and DynamicProof if (isProofType(type)) { diff --git a/packages/module/test/method/MethodParameterEncoder.test.ts b/packages/module/test/method/MethodParameterEncoder.test.ts index 6b42dee4e..45c4f74b0 100644 --- a/packages/module/test/method/MethodParameterEncoder.test.ts +++ b/packages/module/test/method/MethodParameterEncoder.test.ts @@ -50,7 +50,7 @@ describe("MethodParameterEncoder", () => { expect(fields[0].toString()).toBe("2"); expect(fields[1].toString()).toStrictEqual(Bool(true).toField().toString()); - const fieldString = fields.map(field => field.toString()); + const fieldString = fields.map((field) => field.toString()); const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); const decoded1 = decoded[0] as unknown as NonMethods; @@ -71,7 +71,7 @@ describe("MethodParameterEncoder", () => { expect(fields.map((x) => x.toString())).toStrictEqual( pk.toFields().map((x) => x.toString()) ); - const fieldString = fields.map(field => field.toString()); + const fieldString = fields.map((field) => field.toString()); const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); @@ -106,7 +106,7 @@ describe("MethodParameterEncoder", () => { x.toString() ) ); - const fieldString = fields.map(field => field.toString()); + const fieldString = fields.map((field) => field.toString()); const decoded = await encoder.decode(fieldString, auxiliary); expect(decoded).toHaveLength(1); diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 26521d3ba..74f8ea5b7 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -53,10 +53,9 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { if (dbResult === null) { return undefined; } - const transactions = - dbResult.transactions.map((txresult) => - this.transactionResultMapper.mapIn([txresult, txresult.tx]) - ); + const transactions = dbResult.transactions.map( + (txresult) => this.transactionResultMapper.mapIn([txresult, txresult.tx]) + ); return { block: { @@ -222,10 +221,11 @@ export class PrismaBlockStorage implements BlockQueue, BlockStorage { }); return blocks.map((block, index) => { - const transactions = - block.transactions.map((txresult) => { + const transactions = block.transactions.map( + (txresult) => { return this.transactionResultMapper.mapIn([txresult, txresult.tx]); - }); + } + ); const decodedBlock = this.blockMapper.mapIn(block); decodedBlock.transactions = transactions; diff --git a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts index d93b79769..c1b113bb7 100644 --- a/packages/persistance/src/services/prisma/PrismaMessageStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaMessageStorage.ts @@ -1,7 +1,4 @@ -import { - MessageStorage, - PendingTransaction, -} from "@proto-kit/sequencer"; +import { MessageStorage, PendingTransaction } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; import type { PrismaConnection } from "../../PrismaDatabaseConnection"; diff --git a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts index 10a5b47e0..d4544a7c4 100644 --- a/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaTransactionStorage.ts @@ -19,9 +19,7 @@ export class PrismaTransactionStorage implements TransactionStorage { ) {} @trace("db.txs.get") - public async getPendingUserTransactions(): Promise< - PendingTransaction[] - > { + public async getPendingUserTransactions(): Promise { const { prismaClient } = this.connection; const txs = await prismaClient.transaction.findMany({ @@ -53,9 +51,7 @@ export class PrismaTransactionStorage implements TransactionStorage { } } - public async pushUserTransaction( - tx: PendingTransaction - ): Promise { + public async pushUserTransaction(tx: PendingTransaction): Promise { const { prismaClient } = this.connection; const result = await prismaClient.transaction.createMany({ diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index d16634810..df5f9d68e 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -1,5 +1,5 @@ import { singleton } from "tsyringe"; -import { Block, UntypedStateTransition } from "@proto-kit/sequencer"; +import { Block } from "@proto-kit/sequencer"; import { Prisma, Block as PrismaBlock } from "@prisma/client"; import { NetworkState } from "@proto-kit/protocol"; @@ -35,8 +35,7 @@ export class BlockMapper implements ObjectMapper { previousBlockHash: input.parentHash !== null ? input.parentHash : undefined, - beforeBlockStateTransitions: - this.stArrayMapper.mapIn( + beforeBlockStateTransitions: this.stArrayMapper.mapIn( input.beforeBlockStateTransitions ), }; diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index 75628ade5..fad5d7fc6 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -12,7 +12,6 @@ export class StateTransitionMapper implements ObjectMapper { public mapIn(input: Prisma.JsonObject): UntypedStateTransition { - return input as unknown as UntypedStateTransition; } @@ -28,9 +27,7 @@ export class StateTransitionArrayMapper { public constructor(private readonly stMapper: StateTransitionMapper) {} - public mapIn( - input: Prisma.JsonValue | undefined - ): UntypedStateTransition[] { + public mapIn(input: Prisma.JsonValue | undefined): UntypedStateTransition[] { if (input === undefined) return []; if (Array.isArray(input)) { diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index e3d435809..1d43f0995 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -18,7 +18,7 @@ import { EventArrayMapper } from "./EventMapper"; export class TransactionMapper implements ObjectMapper { - public mapIn(input: DBTransaction): PendingTransaction { + public mapIn(input: DBTransaction): PendingTransaction { return new PendingTransaction({ hash: input.hash, methodId: input.methodId, diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index 10ce56ac6..75c93c678 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -224,8 +224,8 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); - let txHash: string; - + let txHash: string; + if (transaction.transaction instanceof PendingTransaction) { txHash = transaction.transaction.hash; } else { @@ -246,8 +246,8 @@ describe("prisma integration", () => { expectDefined(transaction.transaction); - let txHash: string; - + let txHash: string; + if (transaction.transaction instanceof PendingTransaction) { txHash = transaction.transaction.hash; } else { @@ -255,9 +255,7 @@ describe("prisma integration", () => { } expect(txs).toHaveLength(1); - expect(txs[0].hash).toStrictEqual( - txHash - ); + expect(txs[0].hash).toStrictEqual(txHash); }); }); }); diff --git a/packages/processor/test/HandlersExecutor.test.ts b/packages/processor/test/HandlersExecutor.test.ts index 2474cf12f..25f1ab8e9 100644 --- a/packages/processor/test/HandlersExecutor.test.ts +++ b/packages/processor/test/HandlersExecutor.test.ts @@ -6,7 +6,7 @@ import { import { TestingAppChain } from "@proto-kit/sdk"; import { Balance, Balances, TokenId } from "@proto-kit/library"; import { MethodParameterEncoder } from "@proto-kit/module"; -import { Field, PrivateKey, PublicKey } from "o1js"; +import { PrivateKey, PublicKey } from "o1js"; import { mockDeep } from "jest-mock-extended"; import { container } from "tsyringe"; @@ -42,7 +42,7 @@ describe("HandlersModule", () => { ) => { // iterate over all transactions for (const tx of block.transactions) { - const methodId = tx.tx.methodId; + const { methodId } = tx.tx; const methodDescriptor = appChain.runtime.methodIdResolver.getMethodNameFromId(methodId); diff --git a/packages/protocol/src/hooks/BlockHeightHook.ts b/packages/protocol/src/hooks/BlockHeightHook.ts index e46d89221..08541eac9 100644 --- a/packages/protocol/src/hooks/BlockHeightHook.ts +++ b/packages/protocol/src/hooks/BlockHeightHook.ts @@ -2,7 +2,9 @@ import { ProvableNetworkState } from "../model/network/NetworkState"; import { ProvableBlockHook } from "../protocol/ProvableBlockHook"; export class BlockHeightHook extends ProvableBlockHook> { - public async afterBlock(networkState: ProvableNetworkState): Promise { + public async afterBlock( + networkState: ProvableNetworkState + ): Promise { return new ProvableNetworkState({ block: { height: networkState.block.height.add(1), @@ -11,7 +13,9 @@ export class BlockHeightHook extends ProvableBlockHook> { }); } - public async beforeBlock(networkState: ProvableNetworkState): Promise { + public async beforeBlock( + networkState: ProvableNetworkState + ): Promise { return networkState; } } diff --git a/packages/protocol/src/hooks/LastStateRootBlockHook.ts b/packages/protocol/src/hooks/LastStateRootBlockHook.ts index cc06f60ac..577d6c996 100644 --- a/packages/protocol/src/hooks/LastStateRootBlockHook.ts +++ b/packages/protocol/src/hooks/LastStateRootBlockHook.ts @@ -19,7 +19,9 @@ export class LastStateRootBlockHook extends ProvableBlockHook< }); } - public async beforeBlock(networkState: ProvableNetworkState): Promise { + public async beforeBlock( + networkState: ProvableNetworkState + ): Promise { return networkState; } } diff --git a/packages/sdk/src/graphql/GraphqlTransactionSender.ts b/packages/sdk/src/graphql/GraphqlTransactionSender.ts index dfbcefb87..c22a5ed4e 100644 --- a/packages/sdk/src/graphql/GraphqlTransactionSender.ts +++ b/packages/sdk/src/graphql/GraphqlTransactionSender.ts @@ -1,8 +1,5 @@ import { inject, injectable } from "tsyringe"; -import { - AppChainModule, - PendingTransaction, -} from "@proto-kit/sequencer"; +import { AppChainModule, PendingTransaction } from "@proto-kit/sequencer"; import { gql } from "@urql/core"; import { TransactionSender } from "../transaction/InMemoryTransactionSender"; diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index 66b746a3e..713e5a6a5 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -37,9 +37,7 @@ export class BlockStorageNetworkStateModule ); } - public async getUnprovenNetworkState(): Promise< - NetworkState | undefined - > { + public async getUnprovenNetworkState(): Promise { const latestBlock = await this.unprovenStorage.getLatestBlock(); return latestBlock?.block.networkState.during; } diff --git a/packages/sdk/src/query/InMemoryBlockExplorer.ts b/packages/sdk/src/query/InMemoryBlockExplorer.ts index bd5b86874..ae92707ee 100644 --- a/packages/sdk/src/query/InMemoryBlockExplorer.ts +++ b/packages/sdk/src/query/InMemoryBlockExplorer.ts @@ -59,11 +59,13 @@ export class InMemoryBlockExplorer if (block === undefined) { return undefined; } - const clientTransactions: ClientTransaction[] = block.transactions.map((txResult) => ({ - tx: txResult.tx.toJSON(), - status: txResult.status, - statusMessage: txResult.statusMessage, - })); + const clientTransactions: ClientTransaction[] = block.transactions.map( + (txResult) => ({ + tx: txResult.tx.toJSON(), + status: txResult.status, + statusMessage: txResult.statusMessage, + }) + ); return { ...block, diff --git a/packages/sdk/test/fees-multi-zkprograms.test.ts b/packages/sdk/test/fees-multi-zkprograms.test.ts index e32911e15..9be9884db 100644 --- a/packages/sdk/test/fees-multi-zkprograms.test.ts +++ b/packages/sdk/test/fees-multi-zkprograms.test.ts @@ -6,7 +6,7 @@ import { expectDefined, noop } from "@proto-kit/common"; import { inject } from "tsyringe"; import { Balance, Balances, BalancesKey, TokenId } from "@proto-kit/library"; -import { TestingAppChain } from "../src"; +import { TestingAppChain } from "../src"; // This test is designed to check what happens when we have multiple zkPrograms. // Currently, the hardcoded maximum for methods per zkProgram is 8 (see Runtime.ts). @@ -226,9 +226,9 @@ describe("check fee analyzer", () => { ); await tx2.sign(); - await tx2.send(); - - const methodId2 = tx2.transaction?.methodId.toString() + await tx2.send(); + + const methodId2 = tx2.transaction?.methodId.toString(); expectDefined(methodId2); const transactionFeeConfig2 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId2); @@ -245,7 +245,7 @@ describe("check fee analyzer", () => { await tx3.sign(); await tx3.send(); - const methodId3 = tx3.transaction?.methodId.toString() + const methodId3 = tx3.transaction?.methodId.toString(); expectDefined(methodId3); const transactionFeeConfig3 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId3); @@ -263,7 +263,7 @@ describe("check fee analyzer", () => { await tx4.sign(); await tx4.send(); - const methodId4 = tx4.transaction?.methodId.toString() + const methodId4 = tx4.transaction?.methodId.toString(); expectDefined(methodId4); const transactionFeeConfig4 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId4); @@ -281,7 +281,7 @@ describe("check fee analyzer", () => { await tx5.sign(); await tx5.send(); - const methodId5 = tx5.transaction?.methodId.toString() + const methodId5 = tx5.transaction?.methodId.toString(); expectDefined(methodId5); const transactionFeeConfig5 = transactionFeeModule.feeAnalyzer.getFeeConfig(methodId5); diff --git a/packages/sdk/test/fees.test.ts b/packages/sdk/test/fees.test.ts index 83c8e78ac..168abbc56 100644 --- a/packages/sdk/test/fees.test.ts +++ b/packages/sdk/test/fees.test.ts @@ -135,7 +135,6 @@ describe("fees", () => { await pit.burn(burnAmount); }); - const methodId = tx.transaction?.methodId.toString(); expectDefined(methodId); const transactionFeeConfig = diff --git a/packages/sequencer/src/helpers/utils.ts b/packages/sequencer/src/helpers/utils.ts index 8ec70c72d..686613d52 100644 --- a/packages/sequencer/src/helpers/utils.ts +++ b/packages/sequencer/src/helpers/utils.ts @@ -193,4 +193,4 @@ export class PairProofTaskSerializer input.map((element) => this.proofSerializer.toJSONProof(element)) ); } -} \ No newline at end of file +} diff --git a/packages/sequencer/src/mempool/Mempool.ts b/packages/sequencer/src/mempool/Mempool.ts index 12b005043..97401a973 100644 --- a/packages/sequencer/src/mempool/Mempool.ts +++ b/packages/sequencer/src/mempool/Mempool.ts @@ -1,8 +1,6 @@ import { EventEmittingComponent } from "@proto-kit/common"; -import type { - PendingTransaction, -} from "./PendingTransaction"; +import type { PendingTransaction } from "./PendingTransaction"; export type MempoolEvents = { "mempool-transaction-added": [PendingTransaction]; diff --git a/packages/sequencer/src/mempool/PendingTransaction.ts b/packages/sequencer/src/mempool/PendingTransaction.ts index 5c8e69f53..36aa511e1 100644 --- a/packages/sequencer/src/mempool/PendingTransaction.ts +++ b/packages/sequencer/src/mempool/PendingTransaction.ts @@ -13,7 +13,6 @@ import { SignedTransaction, UInt64Option, } from "@proto-kit/protocol"; -import { FieldString } from "@proto-kit/common"; export type UnsignedTransactionBody = { methodId: Field; @@ -28,6 +27,106 @@ export type UnsignedTransactionBody = { isMessage: boolean; }; +interface PendingTransactionJSONType { + hash: string; + methodId: string; + nonce: string; + sender: string; + argsFields: string[]; + auxiliaryData: string[]; + signature: { + r: string; + s: string; + }; + isMessage: boolean; +} + +export class PendingTransaction { + public readonly hash: string; + + public readonly methodId: string; + + public readonly nonce: string; + + public readonly sender: string; + + public readonly argsFields: string[]; + + public readonly auxiliaryData: string[]; + + public readonly signature: { r: string; s: string }; + + public readonly isMessage: boolean; + + public static fromJSON( + object: PendingTransactionJSONType + ): PendingTransaction { + return new PendingTransaction({ + hash: object.hash, + methodId: object.methodId, + nonce: object.nonce, + sender: object.sender, + argsFields: object.argsFields.slice(), + auxiliaryData: object.auxiliaryData.slice(), + signature: { r: object.signature.r, s: object.signature.s }, + isMessage: object.isMessage, + }); + } + + public constructor(data: { + hash: string; + methodId: string; + nonce: string; + sender: string; + argsFields: string[]; + auxiliaryData: string[]; + signature: { r: string; s: string }; + isMessage: boolean; + }) { + this.hash = data.hash; + this.methodId = data.methodId; + this.nonce = data.nonce; + this.sender = data.sender; + this.argsFields = data.argsFields; + this.auxiliaryData = data.auxiliaryData; + this.signature = data.signature; + this.isMessage = data.isMessage; + } + + public toJSON(): PendingTransactionJSONType { + return { + hash: this.hash, + methodId: this.methodId, + nonce: this.nonce, + sender: this.sender, + argsFields: this.argsFields.slice(), + auxiliaryData: this.auxiliaryData.slice(), + signature: { r: this.signature.r, s: this.signature.s }, + isMessage: this.isMessage, + }; + } + + public toRuntimeTransaction(): RuntimeTransaction { + const isSome = Bool(!this.isMessage); + return new RuntimeTransaction({ + methodId: Field(this.methodId), + argsHash: Poseidon.hash(this.argsFields.map((f) => Field(f))), + nonce: new UInt64Option({ value: UInt64.from(this.nonce), isSome }), + sender: new PublicKeyOption({ + value: PublicKey.fromBase58(this.sender), + isSome, + }), + }); + } + + public toProtocolTransaction(): SignedTransaction { + return new SignedTransaction({ + transaction: this.toRuntimeTransaction(), + signature: Signature.fromJSON(this.signature), + }); + } +} + export class UnsignedTransaction implements UnsignedTransactionBody { public readonly methodId: Field; @@ -105,7 +204,7 @@ export class UnsignedTransaction implements UnsignedTransactionBody { }); } - public signed(signature: Signature): PendingTransaction { + public signed(signature: Signature) { return new PendingTransaction({ hash: this.hash().toString(), methodId: this.methodId.toString(), @@ -116,93 +215,5 @@ export class UnsignedTransaction implements UnsignedTransactionBody { auxiliaryData: this.auxiliaryData, isMessage: this.isMessage, }); -} -} - -interface PendingTransactionJSONType { - hash: string; - methodId: string; - nonce: string; - sender: string; - argsFields: string[]; - auxiliaryData: string[]; - signature: { - r: string; - s: string; - }; - isMessage: boolean; -} - -export class PendingTransaction { - public readonly hash: string; - public readonly methodId: string; - public readonly nonce: string; - public readonly sender: string; - public readonly argsFields: string[]; - public readonly auxiliaryData: string[]; - public readonly signature: { r: string; s: string }; - public readonly isMessage: boolean; - - public static fromJSON(object: PendingTransactionJSONType): PendingTransaction { - return new PendingTransaction({ - hash: object.hash, - methodId: object.methodId, - nonce: object.nonce, - sender: object.sender, - argsFields: object.argsFields.slice(), - auxiliaryData: object.auxiliaryData.slice(), - signature: { r: object.signature.r, s: object.signature.s }, - isMessage: object.isMessage, - }); - } - - public constructor(data: { - hash: string; - methodId: string; - nonce: string; - sender: string; - argsFields: string[]; - auxiliaryData: string[]; - signature: { r: string; s: string }; - isMessage: boolean; - }) { - this.hash = data.hash; - this.methodId = data.methodId; - this.nonce = data.nonce; - this.sender = data.sender; - this.argsFields = data.argsFields; - this.auxiliaryData = data.auxiliaryData; - this.signature = data.signature; - this.isMessage = data.isMessage; - } - - public toJSON(): PendingTransactionJSONType { - return { - hash: this.hash, - methodId: this.methodId, - nonce: this.nonce, - sender: this.sender, - argsFields: this.argsFields.slice(), - auxiliaryData: this.auxiliaryData.slice(), - signature: { r: this.signature.r, s: this.signature.s }, - isMessage: this.isMessage, - }; - } - - public toRuntimeTransaction(): RuntimeTransaction { - const isSome = Bool(!this.isMessage); - return new RuntimeTransaction({ - methodId: Field(this.methodId), - argsHash: Poseidon.hash(this.argsFields.map((f) => Field(f))), - nonce: new UInt64Option({ value: UInt64.from(this.nonce), isSome }), - sender: new PublicKeyOption({ value: PublicKey.fromBase58(this.sender), isSome }), - }); } - - public toProtocolTransaction(): SignedTransaction { - return new SignedTransaction({ - transaction: this.toRuntimeTransaction(), - signature: Signature.fromJSON(this.signature), - }); - } -} \ No newline at end of file +} diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index f962e69eb..4ba910b13 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -20,9 +20,7 @@ import { import { Field } from "o1js"; import type { Mempool, MempoolEvents } from "../Mempool"; -import { - PendingTransaction, -} from "../PendingTransaction"; +import { PendingTransaction } from "../PendingTransaction"; import { sequencerModule, SequencerModule, @@ -81,10 +79,7 @@ export class PrivateMempool if (txValid) { const success = await this.transactionStorage.pushUserTransaction(tx); if (success) { - this.events.emit( - "mempool-transaction-added", - tx - ); + this.events.emit("mempool-transaction-added", tx); log.trace(`Transaction added to mempool: ${tx.hash}`); } else { log.error(`Transaction ${tx.hash} rejected: already exists in mempool`); @@ -130,7 +125,8 @@ export class PrivateMempool const stagedNetworkState = await this.getStagedNetworkState(); const networkState = - stagedNetworkState || ProvableNetworkState.toJSON(ProvableNetworkState.empty()); + stagedNetworkState || + ProvableNetworkState.toJSON(ProvableNetworkState.empty()); const validationEnabled = this.config.validationEnabled ?? false; const sortedTxs = validationEnabled diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index 1f69ee2c4..aae6fde51 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -4,11 +4,9 @@ import { Runtime, RuntimeModulesRecord, } from "@proto-kit/module"; +import { Signature } from "o1js"; -import { - PendingTransaction, -} from "../PendingTransaction"; -import { Signature} from "o1js"; +import { PendingTransaction } from "../PendingTransaction"; @injectable() export class TransactionValidator { @@ -41,24 +39,21 @@ export class TransactionValidator { return undefined; } - public validateTx( - tx: PendingTransaction - ): [boolean, string | undefined] { + public validateTx(tx: PendingTransaction): [boolean, string | undefined] { const methodError = this.validateMethod(tx); if (methodError !== undefined) { return [false, methodError]; } - const signature = Signature.fromJSON(tx.signature) + const signature = Signature.fromJSON(tx.signature); const runtimeTx = tx.toRuntimeTransaction(); - - const validSignature = signature.verify( - runtimeTx.sender.value, - [runtimeTx.methodId, ...runtimeTx.nonce.value.value.toFields(), runtimeTx.argsHash] - ); - + const validSignature = signature.verify(runtimeTx.sender.value, [ + runtimeTx.methodId, + ...runtimeTx.nonce.value.value.toFields(), + runtimeTx.argsHash, + ]); if (!validSignature.toBoolean()) { return [false, "Signature provided is not valid"]; diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 9875daa6a..021c779b1 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -4,7 +4,7 @@ import { BlockProverPublicOutput, NetworkState, } from "@proto-kit/protocol"; -import { Field, Proof } from "o1js"; +import { Proof } from "o1js"; import { log, noop } from "@proto-kit/common"; import { diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts index ddc37416a..b40f087ea 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedOption.ts @@ -47,10 +47,10 @@ export class UntypedOption { return new UntypedOption(this.isSome, [...this.value], this.isForcedSome); } - public forceSome() { - this.isForcedSome = !this.isSome; - this.isSome = true; - } + public forceSome() { + this.isForcedSome = !this.isSome; + this.isSome = true; + } public encodeValueToFields(): Field[] { return this.value.map((fieldString) => Field(fieldString)); @@ -62,4 +62,4 @@ export class UntypedOption { value: Field(this.treeValue), }); } -} \ No newline at end of file +} diff --git a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts index 49f520da6..a5d9c9c0b 100644 --- a/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts +++ b/packages/sequencer/src/protocol/production/helpers/UntypedStateTransition.ts @@ -1,5 +1,6 @@ import { Field } from "o1js"; import { ProvableStateTransition, StateTransition } from "@proto-kit/protocol"; + import { UntypedOption } from "./UntypedOption"; export class UntypedStateTransition { @@ -51,4 +52,4 @@ export class UntypedStateTransition { to: this.to.toProvable(), }); } -} \ No newline at end of file +} diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 913b59c10..ffa600922 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -6,7 +6,7 @@ import { Runtime, RuntimeModulesRecord, } from "@proto-kit/module"; -import { Field, Provable } from "o1js"; +import { Provable } from "o1js"; import { Mempool } from "../../../mempool/Mempool"; import { @@ -92,10 +92,7 @@ export class BlockProducerModule extends SequencerModule { if (log.getLevel() <= log.levels.INFO) { Provable.log( "Arguments:", - paramEncoder.decode( - tx.tx.argsFields, - tx.tx.auxiliaryData - ) + paramEncoder.decode(tx.tx.argsFields, tx.tx.auxiliaryData) ); } log.info( diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts index 430ba0c8c..e585b8f27 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProductionService.ts @@ -14,7 +14,7 @@ import { TransactionHashList, } from "@proto-kit/protocol"; import { Field } from "o1js"; -import { log } from "@proto-kit/common"; +import { log, FieldString } from "@proto-kit/common"; import { match } from "ts-pattern"; import { @@ -28,7 +28,6 @@ import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { Tracer } from "../../../logging/Tracer"; import { trace } from "../../../logging/trace"; -import { FieldString } from "@proto-kit/common"; import { BlockTrackers, @@ -132,7 +131,9 @@ export class BlockProductionService { // Get used networkState by executing beforeBlock() hooks const beforeHookResult = await this.executeBeforeBlockHook( toProvableHookBlockState(blockState), - new ProvableNetworkState(ProvableNetworkState.fromJSON(lastResult.afterNetworkState)), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(lastResult.afterNetworkState) + ), stateService ); @@ -174,10 +175,7 @@ export class BlockProductionService { toEternalTransactionsHash: FieldString( newBlockState.eternalTransactionsList.commitment ), - height: - (lastBlock.hash) !== "0" - ? lastBlock.height + 1 - : 0, + height: lastBlock.hash !== "0" ? lastBlock.height + 1 : 0, fromBlockHashRoot: FieldString(lastResult.blockHashRoot), fromMessagesHash: lastBlock.toMessagesHash, fromStateRoot: FieldString(lastResult.stateRoot), @@ -188,7 +186,7 @@ export class BlockProductionService { before: lastResult.afterNetworkState, during: ProvableNetworkState.toJSON(networkState), }, - beforeBlockStateTransitions: beforeBlockStateTransitions + beforeBlockStateTransitions: beforeBlockStateTransitions, }; const hash = Block.hash(block).toString(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index ebdce1bf1..2ba26bce5 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -1,5 +1,5 @@ import { Bool, Field, Poseidon } from "o1js"; -import { LinkedMerkleTree } from "@proto-kit/common"; +import { LinkedMerkleTree, FieldString } from "@proto-kit/common"; import { AfterBlockHookArguments, BlockHashMerkleTree, @@ -22,9 +22,7 @@ import { } from "../../../storage/model/Block"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; -import { - UntypedStateTransition, -} from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { AsyncStateService } from "../../../state/async/AsyncStateService"; import type { StateRecord } from "../BatchProducerModule"; @@ -32,7 +30,6 @@ import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; import { AsyncLinkedLeafStore } from "../../../state/async/AsyncLinkedLeafStore"; import { CachedLinkedLeafStore } from "../../../state/lmt/CachedLinkedLeafStore"; -import { FieldString } from "@proto-kit/common"; import { executeWithExecutionContext } from "./TransactionExecutionService"; @@ -174,7 +171,8 @@ export class BlockResultService { const tree = new LinkedMerkleTree(store.treeStore, store); const writes = Object.entries(stateDiff).map(([key, state]) => { - const treeValue = state !== undefined ? Poseidon.hash(state.map(Field)) : Field(0); + const treeValue = + state !== undefined ? Poseidon.hash(state.map(Field)) : Field(0); return { path: BigInt(key), value: treeValue.toBigInt() }; }); tree.setLeaves(writes); @@ -225,7 +223,9 @@ export class BlockResultService { transactionsHash: Field(block.transactionsHash), eternalTransactionsHash: Field(block.toEternalTransactionsHash), }, - new ProvableNetworkState(ProvableNetworkState.fromJSON(block.networkState.during)), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(block.networkState.during) + ), stateService ); diff --git a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts index 2dfaef1e1..b213c8f36 100644 --- a/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/TransactionExecutionService.ts @@ -35,9 +35,7 @@ import { // eslint-disable-next-line import/no-extraneous-dependencies import zip from "lodash/zip"; -import { - PendingTransaction, -} from "../../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../../mempool/PendingTransaction"; import { CachedStateService } from "../../../state/state/CachedStateService"; import { StateTransitionBatch, @@ -105,10 +103,7 @@ async function decodeTransaction( module, methodName ); - const args = await parameterDecoder.decode( - tx.argsFields, - tx.auxiliaryData - ); + const args = await parameterDecoder.decode(tx.argsFields, tx.auxiliaryData); return { method, @@ -318,8 +313,7 @@ export class TransactionExecutionService { state: BlockTrackers, tx: PendingTransaction ): BlockTrackers { - const signedTransaction = - tx.toProtocolTransaction(); + const signedTransaction = tx.toProtocolTransaction(); // Add tx to commitments return addTransactionToBundle( state, @@ -431,8 +425,7 @@ export class TransactionExecutionService { const previousProofsEnabled = appChain.areProofsEnabled; appChain.setProofsEnabled(false); - const signedTransaction = - tx.toProtocolTransaction(); + const signedTransaction = tx.toProtocolTransaction(); const runtimeContextInputs = { transaction: signedTransaction.transaction, networkState, diff --git a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts index e7d4b45fd..ab5696211 100644 --- a/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/NewBlockTask.ts @@ -62,7 +62,7 @@ export class NewBlockTask @inject("Protocol") private readonly protocol: Protocol, private readonly executionContext: ProvableMethodExecutionContext, - private readonly compileRegistry: CompileRegistry, + private readonly compileRegistry: CompileRegistry ) { super(); this.stateTransitionProver = protocol.stateTransitionProver; @@ -115,13 +115,13 @@ export class NewBlockTask await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHook , startingStateAfterHook], + [startingStateBeforeHook, startingStateAfterHook], async () => {} ); return await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - [startingStateBeforeHook , startingStateAfterHook], + [startingStateBeforeHook, startingStateAfterHook], async () => await this.executionContext.current().result.prove() ); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 94e2c7b12..a731847b3 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -10,19 +10,20 @@ import { NetworkState, RuntimeMethodExecutionContext, } from "@proto-kit/protocol"; -import { Field, Proof } from "o1js"; +import { Proof } from "o1js"; import { CompileRegistry } from "@proto-kit/common"; import { Task, TaskSerializer } from "../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; -import { - PendingTransaction, -} from "../../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../../mempool/PendingTransaction"; import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; -import { DecodedStateSerializer, JSONEncodableState } from "./serializers/DecodedStateSerializer"; +import { + DecodedStateSerializer, + JSONEncodableState, +} from "./serializers/DecodedStateSerializer"; type RuntimeProof = Proof; @@ -59,11 +60,9 @@ export class RuntimeProvingTask return new ProofTaskSerializer(this.runtimeZkProgrammable[0].Proof); } - public async compute( - input: RuntimeProofParameters - ): Promise { + public async compute(input: RuntimeProofParameters): Promise { // Convert from JSON to provable types at the proving boundary - const tx = input.tx; + const { tx } = input; const networkState = new ProvableNetworkState( ProvableNetworkState.fromJSON(input.networkState) ); diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index f5faf4334..0a75b601c 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -24,7 +24,10 @@ import { TransactionProvingTaskParameters, TransactionProvingType, } from "./serializers/types/TransactionProvingTypes"; -import { DecodedStateSerializer, JSONEncodableState, TaskStateRecord } from "./serializers/DecodedStateSerializer"; +import { + DecodedStateSerializer, + JSONEncodableState, +} from "./serializers/DecodedStateSerializer"; export async function executeWithPrefilledStateService( stateServiceProvider: StateServiceProvider, @@ -37,7 +40,7 @@ export async function executeWithPrefilledStateService( .forEach((startingState) => { stateServiceProvider.setCurrentStateService( new PreFilledStateService({ - ...DecodedStateSerializer.fromJSON(startingState) + ...DecodedStateSerializer.fromJSON(startingState), }) ); }); diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts index cd8fadbb9..4a14c6ecb 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/NewBlockProvingParametersSerializer.ts @@ -17,6 +17,7 @@ import type { NewBlockProverParameters } from "../NewBlockTask"; import { TaskSerializer } from "../../../../worker/flow/Task"; import { ProofTaskSerializer } from "../../../../helpers/utils"; import { PairingDerivedInput } from "../../flow/ReductionTaskFlow"; + import { JSONEncodableState } from "./DecodedStateSerializer"; interface JsonType { @@ -70,6 +71,7 @@ export class NewBlockProvingParametersSerializer startingStateBeforeHook: input.params.startingStateBeforeHook, startingStateAfterHook: input.params.startingStateAfterHook, + deferSTProof: input.params.deferSTProof.toBoolean(), afterBlockRootWitness: WitnessedRootWitness.toJSON( diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts index 957aaf8bc..af7bdf8fc 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts @@ -2,10 +2,6 @@ import { TaskSerializer } from "../../../../worker/flow/Task"; import type { RuntimeProofParameters } from "../RuntimeProvingTask"; import { PendingTransaction } from "../../../../mempool/PendingTransaction"; -/** - * Serializer for RuntimeProofParametersJson. - * Since RuntimeProofParametersJson is already JSON-compatible, this is trivial. - */ export class RuntimeProofParametersSerializer implements TaskSerializer { @@ -26,4 +22,3 @@ export class RuntimeProofParametersSerializer }; } } - diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts index b4ad5476b..a03d7f403 100644 --- a/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts +++ b/packages/sequencer/src/protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer.ts @@ -182,7 +182,9 @@ export class TransactionProvingTaskParameterSerializer parameters.executionData.transaction ), networkState: new ProvableNetworkState( - ProvableNetworkState.fromJSON(parameters.executionData.networkState) + ProvableNetworkState.fromJSON( + parameters.executionData.networkState + ) ), }, }, diff --git a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts index d58ccc9db..eb20e6597 100644 --- a/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/BlockTracingService.ts @@ -89,7 +89,7 @@ export class BlockTracingService { state.pendingSTBatches.push({ batchHash: toStateTransitionsHash( - block.block.beforeBlockStateTransitions, + block.block.beforeBlockStateTransitions ), applied: Bool(true), }); diff --git a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts index b5df930b2..d4afc72c4 100644 --- a/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/StateTransitionTracingService.ts @@ -1,4 +1,4 @@ -import { Bool, Field, Poseidon } from "o1js"; +import { Bool, Field } from "o1js"; import { LinkedMerkleTree, LinkedMerkleTreeWitness, @@ -9,7 +9,6 @@ import { AppliedBatchHashList, AppliedStateTransitionBatchState, DefaultProvableHashList, - ProvableOption, ProvableStateTransition, StateTransitionProvableBatch, StateTransitionProverPublicInput, @@ -19,9 +18,7 @@ import { import { distinctByString } from "../../../helpers/utils"; import { BlockWithResult } from "../../../storage/model/Block"; -import { - UntypedStateTransition, -} from "../helpers/UntypedStateTransition"; +import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { StateTransitionProofParameters } from "../tasks/StateTransitionTask"; import { trace } from "../../../logging/trace"; import { Tracer } from "../../../logging/Tracer"; @@ -55,9 +52,7 @@ export class StateTransitionTracingService { }, ...block.block.transactions.flatMap((tx) => tx.stateTransitions.map((batch) => ({ - stateTransitions: batch.stateTransitions.map((st) => - st - ), + stateTransitions: batch.stateTransitions.map((st) => st), applied: batch.applied, })) ), @@ -85,13 +80,13 @@ export class StateTransitionTracingService { stateTransitions: TracingStateTransitionBatch[] ) { const batches = StateTransitionProvableBatch.fromBatches( - stateTransitions.map( + stateTransitions.map( ({ stateTransitions: batchStateTransitions, applied, witnessRoot, }) => ({ - stateTransitions: batchStateTransitions.map((transition) => + stateTransitions: batchStateTransitions.map((transition) => transition.toProvable() ), applied: Bool(applied), diff --git a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts index 275eacf7c..1901a0a6d 100644 --- a/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts +++ b/packages/sequencer/src/protocol/production/tracing/TransactionTracingService.ts @@ -11,9 +11,7 @@ import { MAX_FIELD } from "@proto-kit/common"; import { toStateTransitionsHash } from "@proto-kit/module"; import { injectable } from "tsyringe"; -import { - TransactionExecutionResult, -} from "../../../storage/model/Block"; +import { TransactionExecutionResult } from "../../../storage/model/Block"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; import type { RuntimeProofParameters } from "../tasks/RuntimeProvingTask"; import { @@ -22,12 +20,10 @@ import { } from "../tasks/serializers/types/TransactionProvingTypes"; import { UntypedStateTransition } from "../helpers/UntypedStateTransition"; import { VerificationKeyService } from "../../runtime/RuntimeVerificationKeyService"; - -import type { - BlockTracingState, -} from "./BlockTracingService"; import { JSONEncodableState } from "../tasks/serializers/DecodedStateSerializer"; +import type { BlockTracingState } from "./BlockTracingService"; + export type TransactionTrace = | { type: TransactionProvingType.SINGLE; @@ -47,17 +43,13 @@ export function collectStartingState( // Filter distinct .filter( (st, index, array) => - array.findIndex((st2) => st2.path === st.path) === - index + array.findIndex((st2) => st2.path === st.path) === index ) // Filter out STs that have isSome: false as precondition, because this means // "state hasn't been set before" and has to correlate to a precondition on Field(0) // and for that the state has to be undefined .filter((st) => st.from.isSome) - .map((st) => [ - st.path, - st.from.value, - ]); + .map((st) => [st.path, st.from.value]); return Object.fromEntries(stateEntries); } @@ -72,9 +64,7 @@ export class TransactionTracingService { transaction: PendingTransaction ): Promise { const verificationKeyAttestation = - this.verificationKeyService.getAttestation( - transaction.methodId - ); + this.verificationKeyService.getAttestation(transaction.methodId); return { transaction: transaction.toRuntimeTransaction(), @@ -103,7 +93,7 @@ export class TransactionTracingService { previousState: BlockTracingState, transaction: TransactionExecutionResult ) { - const tx = transaction.tx; + const { tx } = transaction; // TODO Remove this call and instead reuse results from sequencing const newState = addTransactionToBundle( previousState, @@ -179,9 +169,7 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction: await this.getTransactionData( - transaction.tx - ), + transaction: await this.getTransactionData(transaction.tx), networkState: previousState.networkState, }, startingState, @@ -220,12 +208,8 @@ export class TransactionTracingService { const transactionTrace: TransactionProverTaskParameters = { executionData: { - transaction1: await this.getTransactionData( - transaction1.tx - ), - transaction2: await this.getTransactionData( - transaction2.tx - ), + transaction1: await this.getTransactionData(transaction1.tx), + transaction2: await this.getTransactionData(transaction2.tx), networkState: previousState.networkState, }, startingState: [...startingState1, ...startingState2], diff --git a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts index 764f80dfe..0205d1bff 100644 --- a/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/bridging/BridgingSettlementInteraction.ts @@ -102,8 +102,12 @@ export class BridgingSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.fromNetworkState)), - new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.toNetworkState)), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch.fromNetworkState) + ), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch.toNetworkState) + ), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts index 38b1ad1a0..fc3782af6 100644 --- a/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/vanilla/VanillaSettlementInteraction.ts @@ -94,8 +94,12 @@ export class VanillaSettlementInteraction implements SettleInteraction { dynamicBlockProof, signature, feepayer, - new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.fromNetworkState)), - new ProvableNetworkState(ProvableNetworkState.fromJSON(batch.toNetworkState)), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch.fromNetworkState) + ), + new ProvableNetworkState( + ProvableNetworkState.fromJSON(batch.toNetworkState) + ), latestSequenceStateHash ); } diff --git a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts index 363ff410b..dffae431b 100644 --- a/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts @@ -1,6 +1,6 @@ import { PublicKey } from "o1js"; -import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; /** * An interface provided by the BaseLayer via DependencyFactory, diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 8620226ab..ae184bc4f 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -24,9 +24,7 @@ import { SettlementContractModule, } from "@proto-kit/protocol"; -import { - PendingTransaction, -} from "../../mempool/PendingTransaction"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; import { IncomingMessageAdapter } from "./IncomingMessageAdapter"; @@ -97,7 +95,6 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { Poseidon.hash(fields), ]).toString(); - return new PendingTransaction({ hash, methodId: methodId.toString(), diff --git a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts index ed78a7661..44d91d41a 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryTransactionStorage.ts @@ -25,9 +25,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { }); } - public async getPendingUserTransactions(): Promise< - PendingTransaction[] - > { + public async getPendingUserTransactions(): Promise { const nextHeight = await this.blockStorage.getCurrentBlockHeight(); for ( let height = this.latestScannedBlock + 1; @@ -46,9 +44,7 @@ export class InMemoryTransactionStorage implements TransactionStorage { return this.queue.slice(); } - public async pushUserTransaction( - tx: PendingTransaction - ): Promise { + public async pushUserTransaction(tx: PendingTransaction): Promise { const notInQueue = this.queue.find((tx2) => tx2.hash === tx.hash) === undefined; if (notInQueue) { diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 1831b4581..b47b69991 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -1,4 +1,4 @@ -import { Bool, Field, Poseidon } from "o1js"; +import { Field, Poseidon } from "o1js"; import { ACTIONS_EMPTY_HASH, BlockHashMerkleTree, @@ -7,15 +7,10 @@ import { ProvableNetworkState, NetworkState, } from "@proto-kit/protocol"; -import { LinkedMerkleTree } from "@proto-kit/common"; +import { LinkedMerkleTree, FieldString } from "@proto-kit/common"; -import { - PendingTransaction, -} from "../../mempool/PendingTransaction"; -import { - UntypedStateTransition, -} from "../../protocol/production/helpers/UntypedStateTransition"; -import { FieldString } from "@proto-kit/common"; +import { PendingTransaction } from "../../mempool/PendingTransaction"; +import { UntypedStateTransition } from "../../protocol/production/helpers/UntypedStateTransition"; export interface StateTransitionBatch { stateTransitions: UntypedStateTransition[]; @@ -121,7 +116,9 @@ export const BlockWithResult = { previousBlockHash: undefined, }, result: { - afterNetworkState: ProvableNetworkState.toJSON(ProvableNetworkState.empty()), + afterNetworkState: ProvableNetworkState.toJSON( + ProvableNetworkState.empty() + ), stateRoot: FieldString(LinkedMerkleTree.EMPTY_ROOT), blockHashRoot: FieldString(BlockHashMerkleTree.EMPTY_ROOT), afterBlockStateTransitions: [], diff --git a/packages/sequencer/test/Mempool.test.ts b/packages/sequencer/test/Mempool.test.ts index a2eb6a339..373625cc4 100644 --- a/packages/sequencer/test/Mempool.test.ts +++ b/packages/sequencer/test/Mempool.test.ts @@ -24,7 +24,9 @@ describe("memPool", () => { const signed = unsigned.sign(pk); - expect(data).toStrictEqual(signed.toProtocolTransaction().getSignatureData()); + expect(data).toStrictEqual( + signed.toProtocolTransaction().getSignatureData() + ); expect(hash).toStrictEqual(signed.hash); }); }); diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index c8f951cb0..a52f259ee 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -17,7 +17,6 @@ import { BlockStorage, VanillaTaskWorkerModules, AppChain, - UntypedStateTransition, } from "../../src"; import { DefaultTestingSequencerModules, @@ -150,8 +149,8 @@ describe.each([["InMemory", InMemoryDatabase]])( expectDefined(block2); expect(block2.hash).toStrictEqual(generatedBlock.hash); const input = block.transactions.flatMap((tx) => - tx.stateTransitions.flatMap((batch) => - batch.stateTransitions)); + tx.stateTransitions.flatMap((batch) => batch.stateTransitions) + ); const stateDiff = collectStateDiff(input); const state = await unprovenState.getMany( diff --git a/packages/sequencer/test/integration/utils.ts b/packages/sequencer/test/integration/utils.ts index e81267a4e..4cdfc4a24 100644 --- a/packages/sequencer/test/integration/utils.ts +++ b/packages/sequencer/test/integration/utils.ts @@ -38,18 +38,14 @@ export function createTransaction(spec: { sender: spec.privateKey.toPublicKey(), nonce: UInt64.from(spec.nonce), isMessage: false, - }) - .sign(spec.privateKey) + }).sign(spec.privateKey); } export function collectStateDiff( stateTransitions: UntypedStateTransition[] ): StateRecord { - return stateTransitions.reduce( - (state, st) => { - state[st.path] = st.to.value; - return state; - }, - {} - ); + return stateTransitions.reduce((state, st) => { + state[st.path] = st.to.value; + return state; + }, {}); } diff --git a/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts b/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts index 45afe54d7..200c543cd 100644 --- a/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts +++ b/packages/sequencer/test/protocol/production/helpers/UntypedOption.test.ts @@ -21,11 +21,9 @@ describe("option <-> untypedoption", () => { const untyped = UntypedOption.fromOption(option); expect(untyped.isSome).toStrictEqual(option.isSome.toBoolean()); - expect(untyped.isForcedSome).toStrictEqual( - option.isForcedSome.toBoolean() - ); + expect(untyped.isForcedSome).toStrictEqual(option.isForcedSome.toBoolean()); expect(untyped.value).toStrictEqual( - option.valueType.toFields(option.value).map(f => f.toString()) + option.valueType.toFields(option.value).map((f) => f.toString()) ); const provable1 = option.toProvable(); @@ -34,4 +32,3 @@ describe("option <-> untypedoption", () => { expect(provable1).toStrictEqual(provable2); }); }); - diff --git a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts index 77d76224a..9ebfe119b 100644 --- a/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts +++ b/packages/sequencer/test/protocol/production/helpers/UntypedStateTransition.test.ts @@ -33,11 +33,11 @@ describe("stateTransition", () => { expect(untyped.path).toStrictEqual(st.path.toString()); expect(untyped.from.value).toStrictEqual( - st.fromValue.valueType.toFields(st.fromValue.value).map((f) => f.toString()) - ); - expect(untyped.from.isSome).toStrictEqual( - st.fromValue.isSome.toBoolean() + st.fromValue.valueType + .toFields(st.fromValue.value) + .map((f) => f.toString()) ); + expect(untyped.from.isSome).toStrictEqual(st.fromValue.isSome.toBoolean()); expect(untyped.from.isForcedSome).toStrictEqual( st.fromValue.isForcedSome.toBoolean() ); @@ -45,9 +45,7 @@ describe("stateTransition", () => { expect(untyped.to.value).toStrictEqual( st.toValue.valueType.toFields(st.toValue.value).map((f) => f.toString()) ); - expect(untyped.to.isSome).toStrictEqual( - st.toValue.isSome.toBoolean() - ); + expect(untyped.to.isSome).toStrictEqual(st.toValue.isSome.toBoolean()); expect(untyped.to.isForcedSome).toStrictEqual( st.toValue.isForcedSome.toBoolean() ); diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index bc865c54a..641cc905c 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -14,7 +14,6 @@ import { ManualBlockTrigger, Sequencer, InclusionStatus, - PendingTransaction, UnsignedTransaction, } from "@proto-kit/sequencer"; import { @@ -186,9 +185,10 @@ describe("graphql client test", () => { await tx.sign(); await tx.send(); - const txHash = tx.transaction instanceof UnsignedTransaction - ? tx.transaction.hash().toString() - : tx.transaction!.hash; + const txHash = + tx.transaction instanceof UnsignedTransaction + ? tx.transaction.hash().toString() + : tx.transaction!.hash; const waitPromise = appChain.query.explorer.fetchTxInclusion(txHash); From cb059f470edaf8dfc8b324fc0b163508fe20d04c Mon Sep 17 00:00:00 2001 From: saitunc Date: Mon, 19 Jan 2026 23:30:46 +0300 Subject: [PATCH 57/63] fix(test): fix test code to pass --- packages/module/test/method/MethodParameterEncoder.test.ts | 1 + packages/module/test/runtimeMethod.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/module/test/method/MethodParameterEncoder.test.ts b/packages/module/test/method/MethodParameterEncoder.test.ts index 45c4f74b0..65a8ab938 100644 --- a/packages/module/test/method/MethodParameterEncoder.test.ts +++ b/packages/module/test/method/MethodParameterEncoder.test.ts @@ -1,3 +1,4 @@ +import "reflect-metadata"; import { Struct, Field, diff --git a/packages/module/test/runtimeMethod.test.ts b/packages/module/test/runtimeMethod.test.ts index 37da9dab5..d569095ee 100644 --- a/packages/module/test/runtimeMethod.test.ts +++ b/packages/module/test/runtimeMethod.test.ts @@ -91,10 +91,10 @@ describe("runtimeMethod", () => { expect.assertions(1 + parameters.length); const module = runtime.resolve("Balances"); - + const parametersArray = parameters.flatMap((x) => x.toFields().map(f => f.toString())); const decoder = MethodParameterEncoder.fromMethod(module, "getBalance"); const recodedParameters = await decoder.decode( - parameters.flatMap((x) => x.toFields()), + parametersArray, [] ); From 81c0df7646c2d51d00d4fb53568a45c46065bbd6 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 00:12:16 +0300 Subject: [PATCH 58/63] refactor: use JSONTaskSerializer for RuntimeProofParameters --- packages/sequencer/src/index.ts | 1 - .../production/tasks/RuntimeProvingTask.ts | 8 +++---- .../RuntimeProofParametersSerializer.ts | 24 ------------------- 3 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index a0fee0179..bce411ef9 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -39,7 +39,6 @@ export * from "./protocol/production/tasks/serializers/ArtifactionRecordSerializ export * from "./protocol/production/tasks/serializers/BlockProofSerializer"; export * from "./protocol/production/tasks/serializers/DecodedStateSerializer"; export * from "./protocol/production/tasks/serializers/NewBlockProvingParametersSerializer"; -export * from "./protocol/production/tasks/serializers/RuntimeProofParametersSerializer"; export * from "./protocol/production/tasks/serializers/RuntimeVerificationKeyAttestationSerializer"; export * from "./protocol/production/tasks/serializers/StateTransitionParametersSerializer"; export * from "./protocol/production/tasks/serializers/TransactionProvingTaskParameterSerializer"; diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index a731847b3..70eca754b 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -19,16 +19,16 @@ import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; -import { RuntimeProofParametersSerializer } from "./serializers/RuntimeProofParametersSerializer"; import { DecodedStateSerializer, JSONEncodableState, } from "./serializers/DecodedStateSerializer"; +import { JSONTaskSerializer } from "../../../worker/flow/JSONTaskSerializer"; type RuntimeProof = Proof; export interface RuntimeProofParameters { - tx: PendingTransaction; + tx: ReturnType; networkState: NetworkState; state: JSONEncodableState; } @@ -53,7 +53,7 @@ export class RuntimeProvingTask } public inputSerializer(): TaskSerializer { - return new RuntimeProofParametersSerializer(); + return JSONTaskSerializer.fromType(); } public resultSerializer(): TaskSerializer { @@ -96,7 +96,7 @@ export class RuntimeProvingTask ); // Set network state and transaction for the runtimemodule to access - const { transaction, signature } = tx.toProtocolTransaction(); + const { transaction, signature } = PendingTransaction.fromJSON(tx).toProtocolTransaction(); const contextInputs = { networkState, transaction, diff --git a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts b/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts deleted file mode 100644 index af7bdf8fc..000000000 --- a/packages/sequencer/src/protocol/production/tasks/serializers/RuntimeProofParametersSerializer.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { TaskSerializer } from "../../../../worker/flow/Task"; -import type { RuntimeProofParameters } from "../RuntimeProvingTask"; -import { PendingTransaction } from "../../../../mempool/PendingTransaction"; - -export class RuntimeProofParametersSerializer - implements TaskSerializer -{ - public toJSON(parameters: RuntimeProofParameters): string { - return JSON.stringify({ - tx: parameters.tx.toJSON(), - networkState: parameters.networkState, - state: parameters.state, - }); - } - - public fromJSON(json: string): RuntimeProofParameters { - const parsed = JSON.parse(json); - return { - tx: PendingTransaction.fromJSON(parsed.tx), - networkState: parsed.networkState, - state: parsed.state, - }; - } -} From 92ee61bd0b7114b8c975e90b546d1cf455071b00 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 00:18:57 +0300 Subject: [PATCH 59/63] style: run lint fix --- packages/module/test/runtimeMethod.test.ts | 9 ++++----- .../src/protocol/production/tasks/RuntimeProvingTask.ts | 5 +++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/module/test/runtimeMethod.test.ts b/packages/module/test/runtimeMethod.test.ts index d569095ee..e83471168 100644 --- a/packages/module/test/runtimeMethod.test.ts +++ b/packages/module/test/runtimeMethod.test.ts @@ -91,12 +91,11 @@ describe("runtimeMethod", () => { expect.assertions(1 + parameters.length); const module = runtime.resolve("Balances"); - const parametersArray = parameters.flatMap((x) => x.toFields().map(f => f.toString())); - const decoder = MethodParameterEncoder.fromMethod(module, "getBalance"); - const recodedParameters = await decoder.decode( - parametersArray, - [] + const parametersArray = parameters.flatMap((x) => + x.toFields().map((f) => f.toString()) ); + const decoder = MethodParameterEncoder.fromMethod(module, "getBalance"); + const recodedParameters = await decoder.decode(parametersArray, []); expect(parameters).toHaveLength(recodedParameters.length); diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 70eca754b..a2af30cb9 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -18,12 +18,12 @@ import { ProofTaskSerializer } from "../../../helpers/utils"; import { TaskWorkerModule } from "../../../worker/worker/TaskWorkerModule"; import { PreFilledStateService } from "../../../state/prefilled/PreFilledStateService"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; +import { JSONTaskSerializer } from "../../../worker/flow/JSONTaskSerializer"; import { DecodedStateSerializer, JSONEncodableState, } from "./serializers/DecodedStateSerializer"; -import { JSONTaskSerializer } from "../../../worker/flow/JSONTaskSerializer"; type RuntimeProof = Proof; @@ -96,7 +96,8 @@ export class RuntimeProvingTask ); // Set network state and transaction for the runtimemodule to access - const { transaction, signature } = PendingTransaction.fromJSON(tx).toProtocolTransaction(); + const { transaction, signature } = + PendingTransaction.fromJSON(tx).toProtocolTransaction(); const contextInputs = { networkState, transaction, From 9ef4aea86d390656d81603f2b6daacd9122beb9f Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 11:54:17 +0300 Subject: [PATCH 60/63] refactor: minor line changes --- .../prisma/mappers/TransactionMapper.ts | 10 ++-------- .../src/mempool/private/PrivateMempool.ts | 15 +++------------ .../verification/TransactionValidator.ts | 2 +- .../production/tasks/RuntimeProvingTask.ts | 19 +++++++------------ .../messages/MinaIncomingMessageAdapter.ts | 3 +-- 5 files changed, 14 insertions(+), 35 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index 1d43f0995..3e1265d91 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -20,17 +20,11 @@ export class TransactionMapper { public mapIn(input: DBTransaction): PendingTransaction { return new PendingTransaction({ - hash: input.hash, - methodId: input.methodId, - nonce: input.nonce, - sender: input.sender, - argsFields: input.argsFields, - auxiliaryData: input.auxiliaryData, - isMessage: input.isMessage, + ...input, signature: { r: input.signature_r, s: input.signature_s, - }, + } }); } diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 4ba910b13..91101de47 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -177,18 +177,9 @@ export class PrivateMempool blockHashRoot: Field( previousBlock?.result.blockHashRoot ?? BlockHashMerkleTree.EMPTY_ROOT ), - eternalTransactionsHash: - previousBlock?.block.toEternalTransactionsHash !== undefined - ? Field(previousBlock?.block.toEternalTransactionsHash) - : Field(0), - transactionsHash: - previousBlock?.block.transactionsHash !== undefined - ? Field(previousBlock?.block.transactionsHash) - : Field(0), - incomingMessagesHash: - previousBlock?.block.toMessagesHash !== undefined - ? Field(previousBlock?.block.toMessagesHash) - : Field(0), + eternalTransactionsHash: Field(previousBlock?.block.toEternalTransactionsHash ?? 0), + transactionsHash: Field(previousBlock?.block.transactionsHash ?? 0), + incomingMessagesHash: Field(previousBlock?.block.toMessagesHash ?? 0), }; const provableNetworkState = new ProvableNetworkState( diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index aae6fde51..0e0ddeb1f 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -6,7 +6,7 @@ import { } from "@proto-kit/module"; import { Signature } from "o1js"; -import { PendingTransaction } from "../PendingTransaction"; +import { PendingTransaction, UnsignedTransaction } from "../PendingTransaction"; @injectable() export class TransactionValidator { diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index a2af30cb9..4a10aeb01 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -61,20 +61,15 @@ export class RuntimeProvingTask } public async compute(input: RuntimeProofParameters): Promise { - // Convert from JSON to provable types at the proving boundary - const { tx } = input; - const networkState = new ProvableNetworkState( - ProvableNetworkState.fromJSON(input.networkState) - ); - const method = this.runtime.getMethodById(tx.methodId); + const method = this.runtime.getMethodById(input.tx.methodId); const methodDescriptors = this.runtime.dependencyContainer .resolve("MethodIdResolver") - .getMethodNameFromId(tx.methodId); + .getMethodNameFromId(input.tx.methodId); if (methodDescriptors === undefined || method === undefined) { - throw new Error(`MethodId not found ${tx.methodId}`); + throw new Error(`MethodId not found ${input.tx.methodId}`); } const [moduleName, methodName] = methodDescriptors; @@ -84,8 +79,8 @@ export class RuntimeProvingTask methodName ); const decodedArguments = await parameterEncoder.decode( - tx.argsFields, - tx.auxiliaryData + input.tx.argsFields, + input.tx.auxiliaryData ); const prefilledStateService = new PreFilledStateService( @@ -97,9 +92,9 @@ export class RuntimeProvingTask // Set network state and transaction for the runtimemodule to access const { transaction, signature } = - PendingTransaction.fromJSON(tx).toProtocolTransaction(); + PendingTransaction.fromJSON(input.tx).toProtocolTransaction(); const contextInputs = { - networkState, + networkState: new ProvableNetworkState( ProvableNetworkState.fromJSON( input.networkState ) ), transaction, signature, }; diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index ae184bc4f..1344ea85d 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -87,7 +87,6 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { const args = await methodEncoder.decode(fieldArgs, []); const { fields, auxiliary } = methodEncoder.encode(args); - const signature = Signature.create(PrivateKey.random(), [Field(0)]); const hash = Poseidon.hash([ methodId, ...EMPTY_PUBLICKEY.toFields(), @@ -100,7 +99,7 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { methodId: methodId.toString(), sender: EMPTY_PUBLICKEY.toBase58(), nonce: UInt64.zero.toString(), - signature: { r: signature.r.toJSON(), s: signature.s.toJSON() }, + signature: Signature.create(PrivateKey.random(), [Field(0)]).toJSON(), argsFields: fields.map((f) => f.toString()), auxiliaryData: auxiliary, isMessage: true, From 39505c884fca1f541f05bc1e82d7fbfb9c3cf234 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 15:09:31 +0300 Subject: [PATCH 61/63] refactor: remove block and pendingTx serializers --- packages/indexer/src/tasks/IndexBlockTask.ts | 5 ++--- .../indexer/src/tasks/IndexPendingTxTask.ts | 6 ++--- .../src/tasks/IndexPendingTxTaskParameters.ts | 22 ------------------- packages/indexer/test/IndexerNotifier.test.ts | 9 ++++---- 4 files changed, 9 insertions(+), 33 deletions(-) delete mode 100644 packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts diff --git a/packages/indexer/src/tasks/IndexBlockTask.ts b/packages/indexer/src/tasks/IndexBlockTask.ts index 3bc46a2c4..05d939afa 100644 --- a/packages/indexer/src/tasks/IndexBlockTask.ts +++ b/packages/indexer/src/tasks/IndexBlockTask.ts @@ -1,5 +1,6 @@ import { BlockQueue, + JSONTaskSerializer, Task, TaskSerializer, TaskWorkerModule, @@ -9,7 +10,6 @@ import { inject, injectable } from "tsyringe"; import { IndexBlockTaskParameters, - IndexBlockTaskParametersSerializer, } from "./IndexBlockTaskParameters"; @injectable() @@ -20,7 +20,6 @@ export class IndexBlockTask public name = "index-block"; public constructor( - public taskSerializer: IndexBlockTaskParametersSerializer, @inject("BlockQueue") public blockStorage: BlockQueue ) { @@ -45,7 +44,7 @@ export class IndexBlockTask } public inputSerializer(): TaskSerializer { - return this.taskSerializer; + return JSONTaskSerializer.fromType(); } public resultSerializer(): TaskSerializer { diff --git a/packages/indexer/src/tasks/IndexPendingTxTask.ts b/packages/indexer/src/tasks/IndexPendingTxTask.ts index db468660d..5022ddf17 100644 --- a/packages/indexer/src/tasks/IndexPendingTxTask.ts +++ b/packages/indexer/src/tasks/IndexPendingTxTask.ts @@ -1,4 +1,5 @@ import { + JSONTaskSerializer, PendingTransaction, Task, TaskSerializer, @@ -8,8 +9,6 @@ import { import { log } from "@proto-kit/common"; import { inject, injectable } from "tsyringe"; -import { IndexPendingTxTaskParametersSerializer } from "./IndexPendingTxTaskParameters"; - @injectable() export class IndexPendingTxTask extends TaskWorkerModule @@ -18,7 +17,6 @@ export class IndexPendingTxTask public name = "index-pending-tx"; public constructor( - public taskSerializer: IndexPendingTxTaskParametersSerializer, @inject("TransactionStorage") public transactionStorage: TransactionStorage ) { @@ -39,7 +37,7 @@ export class IndexPendingTxTask } public inputSerializer(): TaskSerializer { - return this.taskSerializer; + return JSONTaskSerializer.fromType(); } public resultSerializer(): TaskSerializer { diff --git a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts b/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts deleted file mode 100644 index 5c60be517..000000000 --- a/packages/indexer/src/tasks/IndexPendingTxTaskParameters.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PendingTransaction } from "@proto-kit/sequencer"; -import { TransactionMapper } from "@proto-kit/persistance"; -import { injectable } from "tsyringe"; - -@injectable() -export class IndexPendingTxTaskParametersSerializer { - public constructor(public transactionMapper: TransactionMapper) {} - - public toJSON(parameters: PendingTransaction): string { - return JSON.stringify({ - tx: this.transactionMapper.mapOut(parameters), - }); - } - - public fromJSON(json: string): PendingTransaction { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const parsed = JSON.parse(json) as { - tx: ReturnType; - }; - return this.transactionMapper.mapIn(parsed.tx); - } -} diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 3939bb73a..361a83f10 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -21,6 +21,7 @@ import { TestingAppChain, } from "@proto-kit/sdk"; import { + JSONTaskSerializer, LocalTaskQueue, PendingTransaction, Sequencer, @@ -28,7 +29,7 @@ import { VanillaTaskWorkerModules, } from "@proto-kit/sequencer"; -import { IndexerNotifier, IndexBlockTaskParametersSerializer } from "../src"; +import { IndexerNotifier, IndexBlockTaskParameters } from "../src"; class TestBalances extends Balances { @runtimeMethod() @@ -180,9 +181,9 @@ describe.skip("IndexerNotifier", () => { }, 20000); it("should create a task for every unproven block produced", async () => { - const { block } = container - .resolve(IndexBlockTaskParametersSerializer) - .fromJSON(addTaskSpy.mock.lastCall?.[0].payload!); + const serializer = JSONTaskSerializer.fromType(); + + const { block } = await serializer.fromJSON(addTaskSpy.mock.lastCall?.[0].payload!); expect(block.height).toBe(0); expect(block.transactions.length).toBe(2); From 3f72d187b01e7132b852fb79912a37d284cf8064 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 15:13:07 +0300 Subject: [PATCH 62/63] style: run lint fix --- packages/indexer/src/tasks/IndexBlockTask.ts | 4 +--- packages/indexer/test/IndexerNotifier.test.ts | 4 +++- .../src/services/prisma/mappers/BlockMapper.ts | 2 +- .../src/services/prisma/mappers/TransactionMapper.ts | 2 +- .../sequencer/src/mempool/private/PrivateMempool.ts | 4 +++- .../src/mempool/verification/TransactionValidator.ts | 2 +- .../protocol/production/tasks/RuntimeProvingTask.ts | 10 ++++++---- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/indexer/src/tasks/IndexBlockTask.ts b/packages/indexer/src/tasks/IndexBlockTask.ts index 05d939afa..956ec5840 100644 --- a/packages/indexer/src/tasks/IndexBlockTask.ts +++ b/packages/indexer/src/tasks/IndexBlockTask.ts @@ -8,9 +8,7 @@ import { import { log } from "@proto-kit/common"; import { inject, injectable } from "tsyringe"; -import { - IndexBlockTaskParameters, -} from "./IndexBlockTaskParameters"; +import { IndexBlockTaskParameters } from "./IndexBlockTaskParameters"; @injectable() export class IndexBlockTask diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 361a83f10..914ebb3c3 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -183,7 +183,9 @@ describe.skip("IndexerNotifier", () => { it("should create a task for every unproven block produced", async () => { const serializer = JSONTaskSerializer.fromType(); - const { block } = await serializer.fromJSON(addTaskSpy.mock.lastCall?.[0].payload!); + const { block } = await serializer.fromJSON( + addTaskSpy.mock.lastCall?.[0].payload! + ); expect(block.height).toBe(0); expect(block.transactions.length).toBe(2); diff --git a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts index df5f9d68e..3ebe0f4dc 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockMapper.ts @@ -43,7 +43,7 @@ export class BlockMapper implements ObjectMapper { public mapOut(input: Block): PrismaBlock { return { - height: Number(input.height), + height: input.height, beforeNetworkState: input.networkState.before, duringNetworkState: input.networkState.during, fromEternalTransactionsHash: input.fromEternalTransactionsHash, diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index 3e1265d91..4d3b9c782 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -24,7 +24,7 @@ export class TransactionMapper signature: { r: input.signature_r, s: input.signature_s, - } + }, }); } diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 91101de47..d4de6f09b 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -177,7 +177,9 @@ export class PrivateMempool blockHashRoot: Field( previousBlock?.result.blockHashRoot ?? BlockHashMerkleTree.EMPTY_ROOT ), - eternalTransactionsHash: Field(previousBlock?.block.toEternalTransactionsHash ?? 0), + eternalTransactionsHash: Field( + previousBlock?.block.toEternalTransactionsHash ?? 0 + ), transactionsHash: Field(previousBlock?.block.transactionsHash ?? 0), incomingMessagesHash: Field(previousBlock?.block.toMessagesHash ?? 0), }; diff --git a/packages/sequencer/src/mempool/verification/TransactionValidator.ts b/packages/sequencer/src/mempool/verification/TransactionValidator.ts index 0e0ddeb1f..aae6fde51 100644 --- a/packages/sequencer/src/mempool/verification/TransactionValidator.ts +++ b/packages/sequencer/src/mempool/verification/TransactionValidator.ts @@ -6,7 +6,7 @@ import { } from "@proto-kit/module"; import { Signature } from "o1js"; -import { PendingTransaction, UnsignedTransaction } from "../PendingTransaction"; +import { PendingTransaction } from "../PendingTransaction"; @injectable() export class TransactionValidator { diff --git a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts index 4a10aeb01..a444bbc58 100644 --- a/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/RuntimeProvingTask.ts @@ -61,7 +61,6 @@ export class RuntimeProvingTask } public async compute(input: RuntimeProofParameters): Promise { - const method = this.runtime.getMethodById(input.tx.methodId); const methodDescriptors = this.runtime.dependencyContainer @@ -91,10 +90,13 @@ export class RuntimeProvingTask ); // Set network state and transaction for the runtimemodule to access - const { transaction, signature } = - PendingTransaction.fromJSON(input.tx).toProtocolTransaction(); + const { transaction, signature } = PendingTransaction.fromJSON( + input.tx + ).toProtocolTransaction(); const contextInputs = { - networkState: new ProvableNetworkState( ProvableNetworkState.fromJSON( input.networkState ) ), + networkState: new ProvableNetworkState( + ProvableNetworkState.fromJSON(input.networkState) + ), transaction, signature, }; From e3789b831566ed17d99e9e713a37590163b05a87 Mon Sep 17 00:00:00 2001 From: saitunc Date: Tue, 20 Jan 2026 17:35:17 +0300 Subject: [PATCH 63/63] refactor(fix): fix mistaken conversions and fix lint errors --- .../src/services/prisma/mappers/BlockResultMapper.ts | 6 +++--- .../src/services/prisma/mappers/StateTransitionMapper.ts | 3 ++- .../src/services/prisma/mappers/TransactionMapper.ts | 9 ++++++++- .../protocol/production/tasks/TransactionProvingTask.ts | 6 ++---- .../settlement/messages/MinaIncomingMessageAdapter.ts | 4 +++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts index 64f351576..3881e5e3d 100644 --- a/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/BlockResultMapper.ts @@ -27,9 +27,9 @@ export class BlockResultMapper blockHashWitness: input.blockHashWitness as BlockHashMerkleTreeWitnessJson, - afterBlockStateTransitions: this.stArrayMapper - .mapIn(input.afterBlockStateTransitions) - .map((st) => st), + afterBlockStateTransitions: this.stArrayMapper.mapIn( + input.afterBlockStateTransitions + ), blockHash: input.blockHash, witnessedRoots: [input.witnessedRoots[0]], diff --git a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts index fad5d7fc6..ed35da7b3 100644 --- a/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/StateTransitionMapper.ts @@ -12,7 +12,8 @@ export class StateTransitionMapper implements ObjectMapper { public mapIn(input: Prisma.JsonObject): UntypedStateTransition { - return input as unknown as UntypedStateTransition; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + return UntypedStateTransition.fromJSON(input as any); } public mapOut(input: UntypedStateTransition): Prisma.JsonObject { diff --git a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts index 4d3b9c782..fdcfd2445 100644 --- a/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts +++ b/packages/persistance/src/services/prisma/mappers/TransactionMapper.ts @@ -20,7 +20,14 @@ export class TransactionMapper { public mapIn(input: DBTransaction): PendingTransaction { return new PendingTransaction({ - ...input, + hash: input.hash, + methodId: input.methodId, + nonce: input.nonce, + sender: input.sender, + argsFields: input.argsFields, + auxiliaryData: input.auxiliaryData, + isMessage: input.isMessage, + signature: { r: input.signature_r, s: input.signature_s, diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index 0a75b601c..783a22010 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -96,11 +96,9 @@ export class TransactionProvingTask public async compute( input: TransactionProvingTaskParameters ): Promise { - const startingStateProvable = input.parameters.startingState; - await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - startingStateProvable, + input.parameters.startingState, async () => { const { type, parameters } = input; @@ -125,7 +123,7 @@ export class TransactionProvingTask return await executeWithPrefilledStateService( this.protocol.stateServiceProvider, - startingStateProvable, + input.parameters.startingState, async () => await this.executionContext.current().result.prove() ); diff --git a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts index 1344ea85d..a8460e689 100644 --- a/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts +++ b/packages/sequencer/src/settlement/messages/MinaIncomingMessageAdapter.ts @@ -94,12 +94,14 @@ export class MinaIncomingMessageAdapter implements IncomingMessageAdapter { Poseidon.hash(fields), ]).toString(); + const signature = Signature.create(PrivateKey.random(), [Field(0)]); + return new PendingTransaction({ hash, methodId: methodId.toString(), sender: EMPTY_PUBLICKEY.toBase58(), nonce: UInt64.zero.toString(), - signature: Signature.create(PrivateKey.random(), [Field(0)]).toJSON(), + signature: { r: signature.r.toString(), s: signature.s.toJSON() }, argsFields: fields.map((f) => f.toString()), auxiliaryData: auxiliary, isMessage: true,