@proto-kit/protocol 0.1.1-develop.153

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +45 -0
  3. package/dist/Constants.d.ts +4 -0
  4. package/dist/Constants.d.ts.map +1 -0
  5. package/dist/Constants.js +3 -0
  6. package/dist/config/ConfigurableModule.d.ts +18 -0
  7. package/dist/config/ConfigurableModule.d.ts.map +1 -0
  8. package/dist/config/ConfigurableModule.js +20 -0
  9. package/dist/config/ConfigurationAggregator.d.ts +10 -0
  10. package/dist/config/ConfigurationAggregator.d.ts.map +1 -0
  11. package/dist/config/ConfigurationAggregator.js +35 -0
  12. package/dist/config/ConfigurationReceiver.d.ts +25 -0
  13. package/dist/config/ConfigurationReceiver.d.ts.map +1 -0
  14. package/dist/config/ConfigurationReceiver.js +36 -0
  15. package/dist/config/ModuleContainer.d.ts +44 -0
  16. package/dist/config/ModuleContainer.d.ts.map +1 -0
  17. package/dist/config/ModuleContainer.js +89 -0
  18. package/dist/config/types.d.ts +2 -0
  19. package/dist/config/types.d.ts.map +1 -0
  20. package/dist/config/types.js +1 -0
  21. package/dist/index.d.ts +24 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +23 -0
  24. package/dist/model/MethodPublicInput.d.ts +51 -0
  25. package/dist/model/MethodPublicInput.d.ts.map +1 -0
  26. package/dist/model/MethodPublicInput.js +11 -0
  27. package/dist/model/MethodPublicOutput.d.ts +59 -0
  28. package/dist/model/MethodPublicOutput.d.ts.map +1 -0
  29. package/dist/model/MethodPublicOutput.js +12 -0
  30. package/dist/model/Option.d.ts +94 -0
  31. package/dist/model/Option.d.ts.map +1 -0
  32. package/dist/model/Option.js +96 -0
  33. package/dist/model/Path.d.ts +31 -0
  34. package/dist/model/Path.d.ts.map +1 -0
  35. package/dist/model/Path.js +44 -0
  36. package/dist/model/StateTransition.d.ts +85 -0
  37. package/dist/model/StateTransition.d.ts.map +1 -0
  38. package/dist/model/StateTransition.js +58 -0
  39. package/dist/model/StateTransitionProvableBatch.d.ts +57 -0
  40. package/dist/model/StateTransitionProvableBatch.d.ts.map +1 -0
  41. package/dist/model/StateTransitionProvableBatch.js +21 -0
  42. package/dist/model/network/NetworkState.d.ts +64 -0
  43. package/dist/model/network/NetworkState.d.ts.map +1 -0
  44. package/dist/model/network/NetworkState.js +14 -0
  45. package/dist/model/transaction/ProtocolTransaction.d.ts +70 -0
  46. package/dist/model/transaction/ProtocolTransaction.d.ts.map +1 -0
  47. package/dist/model/transaction/ProtocolTransaction.js +18 -0
  48. package/dist/model/transaction/RuntimeTransaction.d.ts +55 -0
  49. package/dist/model/transaction/RuntimeTransaction.d.ts.map +1 -0
  50. package/dist/model/transaction/RuntimeTransaction.js +26 -0
  51. package/dist/protocol/Protocol.d.ts +37 -0
  52. package/dist/protocol/Protocol.d.ts.map +1 -0
  53. package/dist/protocol/Protocol.js +50 -0
  54. package/dist/protocol/ProtocolModule.d.ts +9 -0
  55. package/dist/protocol/ProtocolModule.d.ts.map +1 -0
  56. package/dist/protocol/ProtocolModule.js +10 -0
  57. package/dist/prover/block/BlockProvable.d.ts +149 -0
  58. package/dist/prover/block/BlockProvable.d.ts.map +1 -0
  59. package/dist/prover/block/BlockProvable.js +20 -0
  60. package/dist/prover/block/BlockProver.d.ts +48 -0
  61. package/dist/prover/block/BlockProver.d.ts.map +1 -0
  62. package/dist/prover/block/BlockProver.js +171 -0
  63. package/dist/prover/block/BlockScopedModule.d.ts +3 -0
  64. package/dist/prover/block/BlockScopedModule.d.ts.map +1 -0
  65. package/dist/prover/block/BlockScopedModule.js +6 -0
  66. package/dist/prover/statetransition/StateTransitionProvable.d.ts +84 -0
  67. package/dist/prover/statetransition/StateTransitionProvable.d.ts.map +1 -0
  68. package/dist/prover/statetransition/StateTransitionProvable.js +11 -0
  69. package/dist/prover/statetransition/StateTransitionProver.d.ts +39 -0
  70. package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -0
  71. package/dist/prover/statetransition/StateTransitionProver.js +157 -0
  72. package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts +16 -0
  73. package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts.map +1 -0
  74. package/dist/prover/statetransition/StateTransitionWitnessProvider.js +17 -0
  75. package/dist/prover/statetransition/StateTransitionWitnessProviderReference.d.ts +7 -0
  76. package/dist/prover/statetransition/StateTransitionWitnessProviderReference.d.ts.map +1 -0
  77. package/dist/prover/statetransition/StateTransitionWitnessProviderReference.js +20 -0
  78. package/dist/src/model/Option.d.ts +158 -0
  79. package/dist/src/model/Option.d.ts.map +1 -0
  80. package/dist/src/model/Option.js +53 -0
  81. package/dist/src/model/Path.d.ts +35 -0
  82. package/dist/src/model/Path.d.ts.map +1 -0
  83. package/dist/src/model/Path.js +51 -0
  84. package/dist/src/model/StateTransition.d.ts +201 -0
  85. package/dist/src/model/StateTransition.d.ts.map +1 -0
  86. package/dist/src/model/StateTransition.js +43 -0
  87. package/dist/src/utils/PrefixedHashList.d.ts +15 -0
  88. package/dist/src/utils/PrefixedHashList.d.ts.map +1 -0
  89. package/dist/src/utils/PrefixedHashList.js +28 -0
  90. package/dist/src/utils/ProvableHashList.d.ts +30 -0
  91. package/dist/src/utils/ProvableHashList.d.ts.map +1 -0
  92. package/dist/src/utils/ProvableHashList.js +43 -0
  93. package/dist/utils/PrefixedHashList.d.ts +14 -0
  94. package/dist/utils/PrefixedHashList.d.ts.map +1 -0
  95. package/dist/utils/PrefixedHashList.js +12 -0
  96. package/dist/utils/PrefixedProvableHashList.d.ts +8 -0
  97. package/dist/utils/PrefixedProvableHashList.d.ts.map +1 -0
  98. package/dist/utils/PrefixedProvableHashList.js +12 -0
  99. package/dist/utils/ProvableHashList.d.ts +27 -0
  100. package/dist/utils/ProvableHashList.d.ts.map +1 -0
  101. package/dist/utils/ProvableHashList.js +43 -0
  102. package/dist/utils/Utils.d.ts +17 -0
  103. package/dist/utils/Utils.d.ts.map +1 -0
  104. package/dist/utils/Utils.js +63 -0
  105. package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts +25 -0
  106. package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts.map +1 -0
  107. package/dist/utils/merkletree/InMemoryMerkleTreeStorage.js +72 -0
  108. package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts +26 -0
  109. package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts.map +1 -0
  110. package/dist/utils/merkletree/MemoryMerkleTreeStorage.js +79 -0
  111. package/dist/utils/merkletree/MerkleTreeStore.d.ts +11 -0
  112. package/dist/utils/merkletree/MerkleTreeStore.d.ts.map +1 -0
  113. package/dist/utils/merkletree/MerkleTreeStore.js +1 -0
  114. package/dist/utils/merkletree/RollupMerkleTree.d.ts +130 -0
  115. package/dist/utils/merkletree/RollupMerkleTree.d.ts.map +1 -0
  116. package/dist/utils/merkletree/RollupMerkleTree.js +244 -0
  117. package/jest.config.cjs +1 -0
  118. package/package.json +35 -0
  119. package/src/Constants.ts +3 -0
  120. package/src/index.ts +23 -0
  121. package/src/model/MethodPublicOutput.ts +12 -0
  122. package/src/model/Option.test.ts +21 -0
  123. package/src/model/Option.ts +133 -0
  124. package/src/model/Path.ts +52 -0
  125. package/src/model/StateTransition.ts +72 -0
  126. package/src/model/StateTransitionProvableBatch.ts +31 -0
  127. package/src/model/Transaction.ts +29 -0
  128. package/src/model/network/NetworkState.ts +15 -0
  129. package/src/model/transaction/ProtocolTransaction.ts +25 -0
  130. package/src/model/transaction/RuntimeTransaction.ts +34 -0
  131. package/src/protocol/Protocol.ts +129 -0
  132. package/src/protocol/ProtocolModule.ts +27 -0
  133. package/src/prover/block/BlockProvable.ts +45 -0
  134. package/src/prover/block/BlockProver.ts +302 -0
  135. package/src/prover/statetransition/StateTransitionProvable.ts +40 -0
  136. package/src/prover/statetransition/StateTransitionProver.ts +270 -0
  137. package/src/prover/statetransition/StateTransitionWitnessProvider.ts +24 -0
  138. package/src/prover/statetransition/StateTransitionWitnessProviderReference.ts +17 -0
  139. package/src/utils/PrefixedProvableHashList.ts +21 -0
  140. package/src/utils/ProvableHashList.ts +50 -0
  141. package/src/utils/merkletree/InMemoryMerkleTreeStorage.ts +99 -0
  142. package/src/utils/merkletree/MerkleTreeStore.ts +15 -0
  143. package/src/utils/merkletree/RollupMerkleTree.ts +250 -0
  144. package/src/utils/merkletree/VirtualMerkleTreeStore.ts +21 -0
  145. package/src/utils/utils.ts +103 -0
  146. package/test/BlockProver.test.ts +127 -0
  147. package/test/Protocol.test.ts +27 -0
  148. package/test/StateTransition.test.ts +182 -0
  149. package/tsconfig.json +8 -0
  150. package/tsconfig.test.json +9 -0
@@ -0,0 +1,25 @@
1
+ import { Bool, Field, PublicKey, Signature, Struct, UInt64 } from "snarkyjs";
2
+
3
+ export class ProtocolTransaction extends Struct({
4
+ methodId: Field,
5
+ nonce: UInt64,
6
+ sender: PublicKey,
7
+ argsHash: Field,
8
+ signature: Signature,
9
+ }) {
10
+ public static getSignatureData(args: {
11
+ methodId: Field;
12
+ nonce: UInt64;
13
+ argsHash: Field;
14
+ }): Field[] {
15
+ return [args.methodId, ...args.nonce.toFields(), args.argsHash];
16
+ }
17
+
18
+ public getSignatureData(): Field[] {
19
+ return ProtocolTransaction.getSignatureData(this);
20
+ }
21
+
22
+ public validateSignature(): Bool {
23
+ return this.signature.verify(this.sender, this.getSignatureData());
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ import { Field, Poseidon, PublicKey, Struct, UInt64 } from "snarkyjs";
2
+
3
+ import { ProtocolTransaction } from "./ProtocolTransaction";
4
+
5
+ /**
6
+ * This struct is used to expose transaction information to the runtime method
7
+ * execution. This class has not all data included in transactions on purpose.
8
+ * For example, we don't want to expose the signature or args as fields.
9
+ */
10
+ export class RuntimeTransaction extends Struct({
11
+ nonce: UInt64,
12
+ sender: PublicKey,
13
+ argsHash: Field,
14
+ }) {
15
+ public static fromProtocolTransaction({
16
+ nonce,
17
+ sender,
18
+ argsHash,
19
+ }: ProtocolTransaction): RuntimeTransaction {
20
+ return new RuntimeTransaction({
21
+ nonce,
22
+ sender,
23
+ argsHash,
24
+ });
25
+ }
26
+
27
+ public hash(): Field {
28
+ return Poseidon.hash([
29
+ ...this.nonce.toFields(),
30
+ ...this.sender.toFields(),
31
+ this.argsHash,
32
+ ]);
33
+ }
34
+ }
@@ -0,0 +1,129 @@
1
+ import {
2
+ log,
3
+ ModuleContainer,
4
+ ModulesConfig,
5
+ ModulesRecord,
6
+ StringKeyOf,
7
+ TypedClass,
8
+ } from "@proto-kit/common";
9
+ import { DependencyContainer } from "tsyringe";
10
+
11
+ import {
12
+ BlockProvable,
13
+ BlockProverPublicInput,
14
+ BlockProverPublicOutput,
15
+ } from "../prover/block/BlockProvable";
16
+ import { StateTransitionProver } from "../prover/statetransition/StateTransitionProver";
17
+ import {
18
+ StateTransitionProvable,
19
+ StateTransitionProverPublicInput,
20
+ StateTransitionProverPublicOutput,
21
+ } from "../prover/statetransition/StateTransitionProvable";
22
+ import { BlockProver } from "../prover/block/BlockProver";
23
+
24
+ import { ProtocolModule } from "./ProtocolModule";
25
+
26
+ export type GenericProtocolModuleRecord = ModulesRecord<
27
+ TypedClass<ProtocolModule<any, any>>
28
+ >;
29
+
30
+ interface BlockProverType
31
+ extends ProtocolModule<BlockProverPublicInput, BlockProverPublicOutput>,
32
+ BlockProvable {}
33
+
34
+ interface StateTransitionProverType
35
+ extends ProtocolModule<
36
+ StateTransitionProverPublicInput,
37
+ StateTransitionProverPublicOutput
38
+ >,
39
+ StateTransitionProvable {}
40
+
41
+ export interface ProtocolCustomModulesRecord {
42
+ BlockProver: TypedClass<BlockProverType>;
43
+ StateTransitionProver: TypedClass<StateTransitionProverType>;
44
+ }
45
+
46
+ export interface ProtocolModulesRecord
47
+ extends GenericProtocolModuleRecord,
48
+ ProtocolCustomModulesRecord {}
49
+
50
+ export interface ProtocolDefinition<Modules extends ProtocolModulesRecord> {
51
+ modules: Modules;
52
+ // config: ModulesConfig<Modules>
53
+ }
54
+
55
+ export class Protocol<
56
+ Modules extends ProtocolModulesRecord
57
+ > extends ModuleContainer<Modules> {
58
+ // .from() to create Protocol
59
+ public static from<Modules extends ProtocolModulesRecord>(
60
+ modules: ProtocolDefinition<Modules>
61
+ ) {
62
+ const protocol = new Protocol(modules);
63
+
64
+ // Set empty config for all modules, since we don't have that feature yet
65
+ // eslint-disable-next-line max-len
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
67
+ const emptyConfig = Object.keys(modules.modules).reduce<any>(
68
+ (agg, item: string) => {
69
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70
+ agg[item] = {};
71
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
72
+ return agg;
73
+ },
74
+ {}
75
+ );
76
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
77
+ protocol.configure(emptyConfig as ModulesConfig<Modules>);
78
+
79
+ return protocol;
80
+ }
81
+
82
+ protected decorateModule(
83
+ moduleName: StringKeyOf<Modules>,
84
+ containedModule: InstanceType<Modules[StringKeyOf<Modules>]>
85
+ ) {
86
+ log.debug(`Decorated ${moduleName}`);
87
+ containedModule.protocol = this;
88
+
89
+ super.decorateModule(moduleName, containedModule);
90
+ }
91
+
92
+ public get dependencyContainer(): DependencyContainer {
93
+ return this.container;
94
+ }
95
+
96
+ private isModule(
97
+ moduleName: keyof Modules
98
+ ): moduleName is StringKeyOf<Modules> {
99
+ return this.definition.modules[moduleName] !== undefined;
100
+ }
101
+
102
+ public get blockProver(): BlockProvable {
103
+ // Why do I resolve directly here?
104
+ // I don't know exactly but generics don't let me use .resolve()
105
+ return this.container.resolve<InstanceType<Modules["BlockProver"]>>(
106
+ "BlockProver"
107
+ );
108
+ }
109
+
110
+ public get stateTransitionProver(): StateTransitionProvable {
111
+ return this.container.resolve<
112
+ InstanceType<Modules["StateTransitionProver"]>
113
+ >("StateTransitionProver");
114
+ }
115
+ }
116
+
117
+ export const VanillaProtocol = {
118
+ create(): Protocol<{
119
+ StateTransitionProver: typeof StateTransitionProver;
120
+ BlockProver: typeof BlockProver;
121
+ }> {
122
+ return Protocol.from({
123
+ modules: {
124
+ StateTransitionProver,
125
+ BlockProver,
126
+ },
127
+ });
128
+ },
129
+ };
@@ -0,0 +1,27 @@
1
+ import {
2
+ AreProofsEnabled,
3
+ Configurable,
4
+ ZkProgrammable,
5
+ } from "@proto-kit/common";
6
+
7
+ import type { Protocol, ProtocolModulesRecord } from "./Protocol";
8
+ import { noop } from "lodash";
9
+
10
+ export abstract class ProtocolModule<PublicInput, PublicOutput>
11
+ extends ZkProgrammable<PublicInput, PublicOutput>
12
+ implements Configurable<unknown>
13
+ {
14
+ public config = {};
15
+
16
+ public protocol?: Protocol<ProtocolModulesRecord>;
17
+
18
+ public get appChain(): AreProofsEnabled | undefined {
19
+ return this.protocol?.dependencyContainer.resolve<AreProofsEnabled>(
20
+ "AppChain"
21
+ );
22
+ }
23
+
24
+ public constructor() {
25
+ super();
26
+ }
27
+ }
@@ -0,0 +1,45 @@
1
+ import { Field, Proof, Struct, UInt64 } from "snarkyjs";
2
+
3
+ import { StateTransitionProof } from "../statetransition/StateTransitionProvable";
4
+ import { MethodPublicOutput } from "../../model/MethodPublicOutput";
5
+ import { ZkProgrammable } from "@proto-kit/common";
6
+ import { ProtocolTransaction } from "../../model/transaction/ProtocolTransaction";
7
+ import { NetworkState } from "../../model/network/NetworkState";
8
+
9
+ export class BlockProverPublicInput extends Struct({
10
+ transactionsHash: Field,
11
+ stateRoot: Field,
12
+ networkStateHash: Field,
13
+ }) {}
14
+
15
+ export class BlockProverPublicOutput extends Struct({
16
+ transactionsHash: Field,
17
+ stateRoot: Field,
18
+ }) {}
19
+
20
+ export type BlockProverProof = Proof<
21
+ BlockProverPublicInput,
22
+ BlockProverPublicOutput
23
+ >;
24
+
25
+ export class BlockProverExecutionData extends Struct({
26
+ transaction: ProtocolTransaction,
27
+ networkState: NetworkState,
28
+ // accountstate
29
+ }) {}
30
+
31
+ export interface BlockProvable
32
+ extends ZkProgrammable<BlockProverPublicInput, BlockProverPublicOutput> {
33
+ proveTransaction: (
34
+ publicInput: BlockProverPublicInput,
35
+ stateProof: StateTransitionProof,
36
+ appProof: Proof<void, MethodPublicOutput>,
37
+ executionData: BlockProverExecutionData
38
+ ) => BlockProverPublicOutput;
39
+
40
+ merge: (
41
+ publicInput: BlockProverPublicInput,
42
+ proof1: BlockProverProof,
43
+ proof2: BlockProverProof
44
+ ) => BlockProverPublicOutput;
45
+ }
@@ -0,0 +1,302 @@
1
+ /* eslint-disable max-lines */
2
+ import { Experimental, Field, type Proof, Provable, SelfProof } from "snarkyjs";
3
+ import { inject, injectable } from "tsyringe";
4
+ import {
5
+ PlainZkProgram,
6
+ provableMethod,
7
+ WithZkProgrammable,
8
+ ZkProgrammable,
9
+ } from "@proto-kit/common";
10
+
11
+ import { DefaultProvableHashList } from "../../utils/ProvableHashList";
12
+ import { MethodPublicOutput } from "../../model/MethodPublicOutput";
13
+ import { ProtocolModule } from "../../protocol/ProtocolModule";
14
+ import {
15
+ StateTransitionProof,
16
+ StateTransitionProverPublicInput,
17
+ StateTransitionProverPublicOutput,
18
+ } from "../statetransition/StateTransitionProvable";
19
+ import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction";
20
+
21
+ import {
22
+ BlockProvable,
23
+ BlockProverExecutionData,
24
+ BlockProverProof,
25
+ BlockProverPublicInput,
26
+ BlockProverPublicOutput,
27
+ } from "./BlockProvable";
28
+
29
+ const errors = {
30
+ stateProofNotStartingAtZero: () =>
31
+ "StateProof not starting ST-commitment at zero",
32
+
33
+ stateTransitionsHashNotEqual: () =>
34
+ "StateTransition list commitments are not equal",
35
+
36
+ propertyNotMatching: (propertyName: string) => `${propertyName} not matching`,
37
+
38
+ stateRootNotMatching: (step: string) => `StateRoots not matching ${step}`,
39
+
40
+ transactionsHashNotMatching: (step: string) =>
41
+ `transactions hash not matching ${step}`,
42
+ };
43
+
44
+ export interface BlockProverState {
45
+ // The current state root of the block prover
46
+ stateRoot: Field;
47
+
48
+ /**
49
+ * The current commitment of the transaction-list which
50
+ * will at the end equal the bundle hash
51
+ */
52
+ transactionsHash: Field;
53
+
54
+ /**
55
+ * The network state which gives access to values such as blockHeight
56
+ * This value is the same for the whole batch (L2 block)
57
+ */
58
+ networkStateHash: Field;
59
+ }
60
+
61
+ /**
62
+ * BlockProver class, which aggregates a AppChainProof and
63
+ * a StateTransitionProof into a single BlockProof, that can
64
+ * then be merged to be committed to the base-layer contract
65
+ */
66
+ @injectable()
67
+ export class BlockProver
68
+ extends ProtocolModule<BlockProverPublicInput, BlockProverPublicOutput>
69
+ implements BlockProvable
70
+ {
71
+ public constructor(
72
+ @inject("StateTransitionProver")
73
+ private readonly stateTransitionProver: ZkProgrammable<
74
+ StateTransitionProverPublicInput,
75
+ StateTransitionProverPublicOutput
76
+ >,
77
+ @inject("Runtime")
78
+ private readonly runtime: WithZkProgrammable<void, MethodPublicOutput>
79
+ ) {
80
+ super();
81
+ }
82
+
83
+ /**
84
+ * Applies and checks the two proofs and applies the corresponding state
85
+ * changes to the given state
86
+ *
87
+ * @param state The from-state of the BlockProver
88
+ * @param stateTransitionProof
89
+ * @param appProof
90
+ * @returns The new BlockProver-state to be used as public output
91
+ */
92
+ public applyTransaction(
93
+ state: BlockProverState,
94
+ stateTransitionProof: Proof<
95
+ StateTransitionProverPublicInput,
96
+ StateTransitionProverPublicOutput
97
+ >,
98
+ appProof: Proof<void, MethodPublicOutput>,
99
+ { transaction, networkState }: BlockProverExecutionData
100
+ ): BlockProverState {
101
+ appProof.verify();
102
+ stateTransitionProof.verify();
103
+
104
+ const stateTo = { ...state };
105
+
106
+ // eslint-disable-next-line no-warning-comments
107
+ // TODO Check methodId?
108
+
109
+ // Checks for the stateTransitionProof and appProof matching
110
+ stateTransitionProof.publicInput.stateTransitionsHash.assertEquals(
111
+ Field(0),
112
+ errors.stateProofNotStartingAtZero()
113
+ );
114
+
115
+ appProof.publicOutput.stateTransitionsHash.assertEquals(
116
+ stateTransitionProof.publicOutput.stateTransitionsHash,
117
+ errors.stateTransitionsHashNotEqual()
118
+ );
119
+
120
+ // Apply state if status success
121
+ state.stateRoot.assertEquals(
122
+ stateTransitionProof.publicInput.stateRoot,
123
+ errors.propertyNotMatching("from state root")
124
+ );
125
+ stateTo.stateRoot = Provable.if(
126
+ appProof.publicOutput.status,
127
+ stateTransitionProof.publicOutput.stateRoot,
128
+ stateTransitionProof.publicInput.stateRoot
129
+ );
130
+
131
+ // Check transaction signature
132
+ transaction
133
+ .validateSignature()
134
+ .assertTrue("Transaction signature not valid");
135
+
136
+ // Check if the methodId is correct
137
+ // to do
138
+
139
+ // Check transaction integrity against appProof
140
+ const blockTransactionHash =
141
+ RuntimeTransaction.fromProtocolTransaction(transaction).hash();
142
+
143
+ blockTransactionHash.assertEquals(
144
+ appProof.publicOutput.transactionHash,
145
+ "Transactions provided in AppProof and BlockProof do not match"
146
+ );
147
+
148
+ // Check network state integrity against appProof
149
+ state.networkStateHash.assertEquals(
150
+ appProof.publicOutput.networkStateHash,
151
+ "Network state does not match state used in AppProof"
152
+ );
153
+ state.networkStateHash.assertEquals(
154
+ networkState.hash(),
155
+ "Network state provided to BlockProver does not match the publicInput"
156
+ );
157
+
158
+ // Append tx to transaction list
159
+ const transactionList = new DefaultProvableHashList(
160
+ Field,
161
+ state.transactionsHash
162
+ );
163
+
164
+ const { transactionHash } = appProof.publicOutput;
165
+ transactionList.push(transactionHash);
166
+
167
+ stateTo.transactionsHash = transactionList.commitment;
168
+
169
+ return stateTo;
170
+ }
171
+
172
+ @provableMethod()
173
+ public proveTransaction(
174
+ publicInput: BlockProverPublicInput,
175
+ stateProof: StateTransitionProof,
176
+ appProof: Proof<void, MethodPublicOutput>,
177
+ executionData: BlockProverExecutionData
178
+ ): BlockProverPublicOutput {
179
+ const state: BlockProverState = {
180
+ transactionsHash: publicInput.transactionsHash,
181
+ stateRoot: publicInput.stateRoot,
182
+ networkStateHash: publicInput.networkStateHash,
183
+ };
184
+
185
+ this.applyTransaction(state, stateProof, appProof, executionData);
186
+
187
+ return new BlockProverPublicOutput({
188
+ stateRoot: state.stateRoot,
189
+ transactionsHash: state.transactionsHash,
190
+ });
191
+ }
192
+
193
+ @provableMethod()
194
+ public merge(
195
+ publicInput: BlockProverPublicInput,
196
+ proof1: BlockProverProof,
197
+ proof2: BlockProverProof
198
+ ): BlockProverPublicOutput {
199
+ proof1.verify();
200
+ proof2.verify();
201
+
202
+ // Check state
203
+ publicInput.stateRoot.assertEquals(
204
+ proof1.publicInput.stateRoot,
205
+ errors.stateRootNotMatching("publicInput.from -> proof1.from")
206
+ );
207
+ proof1.publicOutput.stateRoot.assertEquals(
208
+ proof2.publicInput.stateRoot,
209
+ errors.stateRootNotMatching("proof1.to -> proof2.from")
210
+ );
211
+
212
+ // Check transaction list
213
+ publicInput.transactionsHash.assertEquals(
214
+ proof1.publicInput.transactionsHash,
215
+ errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
216
+ );
217
+ proof1.publicOutput.transactionsHash.assertEquals(
218
+ proof2.publicInput.transactionsHash,
219
+ errors.transactionsHashNotMatching("proof1.to -> proof2.from")
220
+ );
221
+
222
+ return new BlockProverPublicOutput({
223
+ stateRoot: proof2.publicOutput.stateRoot,
224
+ transactionsHash: proof2.publicOutput.transactionsHash,
225
+ });
226
+ }
227
+
228
+ /**
229
+ * Creates the BlockProver ZkProgram.
230
+ * Recursive linking of proofs is done via the previously
231
+ * injected StateTransitionProver and the required AppChainProof class
232
+ */
233
+ public zkProgramFactory(): PlainZkProgram<
234
+ BlockProverPublicInput,
235
+ BlockProverPublicOutput
236
+ > {
237
+ const StateTransitionProofClass =
238
+ this.stateTransitionProver.zkProgram.Proof;
239
+ const RuntimeProofClass = this.runtime.zkProgrammable.zkProgram.Proof;
240
+
241
+ const proveTransaction = this.proveTransaction.bind(this);
242
+ const merge = this.merge.bind(this);
243
+
244
+ const program = Experimental.ZkProgram({
245
+ publicInput: BlockProverPublicInput,
246
+ publicOutput: BlockProverPublicOutput,
247
+
248
+ methods: {
249
+ proveTransaction: {
250
+ privateInputs: [
251
+ StateTransitionProofClass,
252
+ RuntimeProofClass,
253
+ BlockProverExecutionData,
254
+ ],
255
+
256
+ method(
257
+ publicInput: BlockProverPublicInput,
258
+ stateProof: StateTransitionProof,
259
+ appProof: Proof<void, MethodPublicOutput>,
260
+ executionData: BlockProverExecutionData
261
+ ) {
262
+ return proveTransaction(
263
+ publicInput,
264
+ stateProof,
265
+ appProof,
266
+ executionData
267
+ );
268
+ },
269
+ },
270
+
271
+ merge: {
272
+ privateInputs: [
273
+ SelfProof<BlockProverPublicInput, BlockProverPublicOutput>,
274
+ SelfProof<BlockProverPublicInput, BlockProverPublicOutput>,
275
+ ],
276
+
277
+ method(
278
+ publicInput: BlockProverPublicInput,
279
+ proof1: BlockProverProof,
280
+ proof2: BlockProverProof
281
+ ) {
282
+ return merge(publicInput, proof1, proof2);
283
+ },
284
+ },
285
+ },
286
+ });
287
+
288
+ const methods = {
289
+ proveTransaction: program.proveTransaction,
290
+ merge: program.merge,
291
+ };
292
+
293
+ const SelfProofClass = Experimental.ZkProgram.Proof(program);
294
+
295
+ return {
296
+ compile: program.compile.bind(program),
297
+ verify: program.verify.bind(program),
298
+ Proof: SelfProofClass,
299
+ methods,
300
+ };
301
+ }
302
+ }
@@ -0,0 +1,40 @@
1
+ import { Field, Proof, Struct } from "snarkyjs";
2
+ import { ZkProgrammable } from "@proto-kit/common";
3
+
4
+ import { StateTransitionProvableBatch } from "../../model/StateTransitionProvableBatch";
5
+
6
+ import { StateTransitionWitnessProviderReference } from "./StateTransitionWitnessProviderReference";
7
+
8
+ export class StateTransitionProverPublicInput extends Struct({
9
+ stateTransitionsHash: Field,
10
+ stateRoot: Field,
11
+ }) {}
12
+
13
+ export class StateTransitionProverPublicOutput extends Struct({
14
+ stateTransitionsHash: Field,
15
+ stateRoot: Field,
16
+ }) {}
17
+
18
+ export type StateTransitionProof = Proof<
19
+ StateTransitionProverPublicInput,
20
+ StateTransitionProverPublicOutput
21
+ >;
22
+
23
+ export interface StateTransitionProvable
24
+ extends ZkProgrammable<
25
+ StateTransitionProverPublicInput,
26
+ StateTransitionProverPublicOutput
27
+ > {
28
+ witnessProviderReference: StateTransitionWitnessProviderReference;
29
+
30
+ runBatch: (
31
+ publicInput: StateTransitionProverPublicInput,
32
+ batch: StateTransitionProvableBatch
33
+ ) => StateTransitionProverPublicOutput;
34
+
35
+ merge: (
36
+ publicInput: StateTransitionProverPublicInput,
37
+ proof1: StateTransitionProof,
38
+ proof2: StateTransitionProof
39
+ ) => StateTransitionProverPublicOutput;
40
+ }