@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.
- package/LICENSE.md +201 -0
- package/README.md +45 -0
- package/dist/Constants.d.ts +4 -0
- package/dist/Constants.d.ts.map +1 -0
- package/dist/Constants.js +3 -0
- package/dist/config/ConfigurableModule.d.ts +18 -0
- package/dist/config/ConfigurableModule.d.ts.map +1 -0
- package/dist/config/ConfigurableModule.js +20 -0
- package/dist/config/ConfigurationAggregator.d.ts +10 -0
- package/dist/config/ConfigurationAggregator.d.ts.map +1 -0
- package/dist/config/ConfigurationAggregator.js +35 -0
- package/dist/config/ConfigurationReceiver.d.ts +25 -0
- package/dist/config/ConfigurationReceiver.d.ts.map +1 -0
- package/dist/config/ConfigurationReceiver.js +36 -0
- package/dist/config/ModuleContainer.d.ts +44 -0
- package/dist/config/ModuleContainer.d.ts.map +1 -0
- package/dist/config/ModuleContainer.js +89 -0
- package/dist/config/types.d.ts +2 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/model/MethodPublicInput.d.ts +51 -0
- package/dist/model/MethodPublicInput.d.ts.map +1 -0
- package/dist/model/MethodPublicInput.js +11 -0
- package/dist/model/MethodPublicOutput.d.ts +59 -0
- package/dist/model/MethodPublicOutput.d.ts.map +1 -0
- package/dist/model/MethodPublicOutput.js +12 -0
- package/dist/model/Option.d.ts +94 -0
- package/dist/model/Option.d.ts.map +1 -0
- package/dist/model/Option.js +96 -0
- package/dist/model/Path.d.ts +31 -0
- package/dist/model/Path.d.ts.map +1 -0
- package/dist/model/Path.js +44 -0
- package/dist/model/StateTransition.d.ts +85 -0
- package/dist/model/StateTransition.d.ts.map +1 -0
- package/dist/model/StateTransition.js +58 -0
- package/dist/model/StateTransitionProvableBatch.d.ts +57 -0
- package/dist/model/StateTransitionProvableBatch.d.ts.map +1 -0
- package/dist/model/StateTransitionProvableBatch.js +21 -0
- package/dist/model/network/NetworkState.d.ts +64 -0
- package/dist/model/network/NetworkState.d.ts.map +1 -0
- package/dist/model/network/NetworkState.js +14 -0
- package/dist/model/transaction/ProtocolTransaction.d.ts +70 -0
- package/dist/model/transaction/ProtocolTransaction.d.ts.map +1 -0
- package/dist/model/transaction/ProtocolTransaction.js +18 -0
- package/dist/model/transaction/RuntimeTransaction.d.ts +55 -0
- package/dist/model/transaction/RuntimeTransaction.d.ts.map +1 -0
- package/dist/model/transaction/RuntimeTransaction.js +26 -0
- package/dist/protocol/Protocol.d.ts +37 -0
- package/dist/protocol/Protocol.d.ts.map +1 -0
- package/dist/protocol/Protocol.js +50 -0
- package/dist/protocol/ProtocolModule.d.ts +9 -0
- package/dist/protocol/ProtocolModule.d.ts.map +1 -0
- package/dist/protocol/ProtocolModule.js +10 -0
- package/dist/prover/block/BlockProvable.d.ts +149 -0
- package/dist/prover/block/BlockProvable.d.ts.map +1 -0
- package/dist/prover/block/BlockProvable.js +20 -0
- package/dist/prover/block/BlockProver.d.ts +48 -0
- package/dist/prover/block/BlockProver.d.ts.map +1 -0
- package/dist/prover/block/BlockProver.js +171 -0
- package/dist/prover/block/BlockScopedModule.d.ts +3 -0
- package/dist/prover/block/BlockScopedModule.d.ts.map +1 -0
- package/dist/prover/block/BlockScopedModule.js +6 -0
- package/dist/prover/statetransition/StateTransitionProvable.d.ts +84 -0
- package/dist/prover/statetransition/StateTransitionProvable.d.ts.map +1 -0
- package/dist/prover/statetransition/StateTransitionProvable.js +11 -0
- package/dist/prover/statetransition/StateTransitionProver.d.ts +39 -0
- package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -0
- package/dist/prover/statetransition/StateTransitionProver.js +157 -0
- package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts +16 -0
- package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts.map +1 -0
- package/dist/prover/statetransition/StateTransitionWitnessProvider.js +17 -0
- package/dist/prover/statetransition/StateTransitionWitnessProviderReference.d.ts +7 -0
- package/dist/prover/statetransition/StateTransitionWitnessProviderReference.d.ts.map +1 -0
- package/dist/prover/statetransition/StateTransitionWitnessProviderReference.js +20 -0
- package/dist/src/model/Option.d.ts +158 -0
- package/dist/src/model/Option.d.ts.map +1 -0
- package/dist/src/model/Option.js +53 -0
- package/dist/src/model/Path.d.ts +35 -0
- package/dist/src/model/Path.d.ts.map +1 -0
- package/dist/src/model/Path.js +51 -0
- package/dist/src/model/StateTransition.d.ts +201 -0
- package/dist/src/model/StateTransition.d.ts.map +1 -0
- package/dist/src/model/StateTransition.js +43 -0
- package/dist/src/utils/PrefixedHashList.d.ts +15 -0
- package/dist/src/utils/PrefixedHashList.d.ts.map +1 -0
- package/dist/src/utils/PrefixedHashList.js +28 -0
- package/dist/src/utils/ProvableHashList.d.ts +30 -0
- package/dist/src/utils/ProvableHashList.d.ts.map +1 -0
- package/dist/src/utils/ProvableHashList.js +43 -0
- package/dist/utils/PrefixedHashList.d.ts +14 -0
- package/dist/utils/PrefixedHashList.d.ts.map +1 -0
- package/dist/utils/PrefixedHashList.js +12 -0
- package/dist/utils/PrefixedProvableHashList.d.ts +8 -0
- package/dist/utils/PrefixedProvableHashList.d.ts.map +1 -0
- package/dist/utils/PrefixedProvableHashList.js +12 -0
- package/dist/utils/ProvableHashList.d.ts +27 -0
- package/dist/utils/ProvableHashList.d.ts.map +1 -0
- package/dist/utils/ProvableHashList.js +43 -0
- package/dist/utils/Utils.d.ts +17 -0
- package/dist/utils/Utils.d.ts.map +1 -0
- package/dist/utils/Utils.js +63 -0
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts +25 -0
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts.map +1 -0
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.js +72 -0
- package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts +26 -0
- package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts.map +1 -0
- package/dist/utils/merkletree/MemoryMerkleTreeStorage.js +79 -0
- package/dist/utils/merkletree/MerkleTreeStore.d.ts +11 -0
- package/dist/utils/merkletree/MerkleTreeStore.d.ts.map +1 -0
- package/dist/utils/merkletree/MerkleTreeStore.js +1 -0
- package/dist/utils/merkletree/RollupMerkleTree.d.ts +130 -0
- package/dist/utils/merkletree/RollupMerkleTree.d.ts.map +1 -0
- package/dist/utils/merkletree/RollupMerkleTree.js +244 -0
- package/jest.config.cjs +1 -0
- package/package.json +35 -0
- package/src/Constants.ts +3 -0
- package/src/index.ts +23 -0
- package/src/model/MethodPublicOutput.ts +12 -0
- package/src/model/Option.test.ts +21 -0
- package/src/model/Option.ts +133 -0
- package/src/model/Path.ts +52 -0
- package/src/model/StateTransition.ts +72 -0
- package/src/model/StateTransitionProvableBatch.ts +31 -0
- package/src/model/Transaction.ts +29 -0
- package/src/model/network/NetworkState.ts +15 -0
- package/src/model/transaction/ProtocolTransaction.ts +25 -0
- package/src/model/transaction/RuntimeTransaction.ts +34 -0
- package/src/protocol/Protocol.ts +129 -0
- package/src/protocol/ProtocolModule.ts +27 -0
- package/src/prover/block/BlockProvable.ts +45 -0
- package/src/prover/block/BlockProver.ts +302 -0
- package/src/prover/statetransition/StateTransitionProvable.ts +40 -0
- package/src/prover/statetransition/StateTransitionProver.ts +270 -0
- package/src/prover/statetransition/StateTransitionWitnessProvider.ts +24 -0
- package/src/prover/statetransition/StateTransitionWitnessProviderReference.ts +17 -0
- package/src/utils/PrefixedProvableHashList.ts +21 -0
- package/src/utils/ProvableHashList.ts +50 -0
- package/src/utils/merkletree/InMemoryMerkleTreeStorage.ts +99 -0
- package/src/utils/merkletree/MerkleTreeStore.ts +15 -0
- package/src/utils/merkletree/RollupMerkleTree.ts +250 -0
- package/src/utils/merkletree/VirtualMerkleTreeStore.ts +21 -0
- package/src/utils/utils.ts +103 -0
- package/test/BlockProver.test.ts +127 -0
- package/test/Protocol.test.ts +27 -0
- package/test/StateTransition.test.ts +182 -0
- package/tsconfig.json +8 -0
- 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
|
+
}
|